下一代加密货币网络
项目描述
这是Ethereum项目的Python核心库。
有关基于Python的命令行客户端,请参阅:https://github.com/ethereum/pyethapp
安装
sudo apt-get install libssl-dev build-essential automake pkg-config libtool libffi-dev libgmp-dev
git clone https://github.com/ethereum/pyethereum/
cd pyethereum
python setup.py install
组件
ethereum.pow.chain
包含Chain类,可用于管理区块链。主要方法有
__init__(genesis=None, env=None, new_head_cb=None, reset_genesis=False, localtime=None) - 使用给定的创世纪初始化。env指定环境(包括链配置和数据库),new_head_cb是当添加新头时调用的回调,localtime是链假设的当前时间戳。创世纪可以是
无 - 在这种情况下,它假设已给出 env,并创建一个包含 env.db 中保存的数据的 Chain 对象。如果设置了 reset_genesis,则重新初始化链。
一个 State 对象
创世声明
状态快照 (State.snapshot())
分配(即. 字典 {address: {balance: 1, nonce: 2, code: b'\x03\x04\x05', storage: {"0x06": "0x07"}}})
add_block(block) - 将一个区块添加到链中
process_time_queue(timestamp) - 告诉链当前时间已增加到新的时间戳。然后链将处理任何因为出现得太“早”而未处理的区块
get_blockhash_by_number(num) - 获取指定区块号的区块哈希
get_block(hash) - 获取给定区块哈希的区块
get_block_by_number(num) - 等价于 get_block(get_blockhash_by_number(num))
get_parent(block) - 获取一个区块的父区块
get_children(block) - 获取一个区块的子区块
head (属性) - 获取链头的区块
state (属性) - 获取链头的状态
mk_poststate_of_blockhash(hash) - 在给定区块之后创建一个状态对象
has_block(block) - 该区块是否在链中?返回 True/False
get_chain(from, to) - 大约等于 [get_block_by_number(i) for i in range(from, to)],但会自动停止,如果达到链头。 from 可以省略以从创世开始,to 可以省略以到达链头。
get_tx_position(tx) - 如果事务在链中,则返回 (blknum, index),其中 blknum 是包含事务的区块的区块号,index 是其在区块中的位置
ethereum.state
包含用于管理状态的 State 类。主要方法包括
__init__(root_hash, env, **kwargs) - 使用给定的根哈希、给定的 env(包括配置和数据库)以及给定的辅助参数初始化状态。这些包括
txindex - 事务索引
gas_used - 消耗的燃气量
gas_limit - 区块燃气限制
block_number - 区块号
block_coinbase - 区块 coinbase 地址
block_difficulty - 区块难度
timestamp - 时间戳
logs - 到目前为止创建的日志
receipts - 到目前为止创建的收据(来自当前区块中的先前事务)
bloom - 布隆过滤器
suicides - 自杀(或自毁,较新且更政治正确的同义词)
recent_uncles - 链中的最近叔区块
prev_headers - 前一个区块头部
refunds - 自杀/自毁退款计数器
Pyethereum采用了一种以状态为中心的最大化模型;处理交易或区块所需要的信息全部位于状态本身,这使得实际的状态转换逻辑非常简洁,例如apply_transaction(state, tx)和apply_block(state, block)。
get_balance - 获取账户余额
get_code - 获取账户代码
get_storage_data(addr, k) - 获取给定地址的给定键的存储。期望键以数值形式(例如,b”cow”或“0x636f77”表示为6516599)。
to_snapshot(root_only=False, no_prevblocks=False) - 为当前状态创建快照。如果设置root_only,则仅添加状态根,而不是整个状态。如果设置no_prevblocks,则不添加先前头信息和叔父信息。设置这些标志中的任何一个意味着需要相同的数据库才能从快照中恢复。
from_snapshot(snapshot, env)(类方法)- 使用给定的env从给定的快照创建状态。
ephemeral_clone() - 创建一个状态的副本,您可以对其进行操作而不会影响原始状态。
还有许多修改状态的方法,例如set_code,set_storage_data,但通常建议避免使用这些方法,而应仅通过apply_transaction和apply_block修改状态。
ethereum.meta
此文件包含两个函数
apply_block(state, block) - 将一个区块处理到给定的状态上
make_head_candidate(chain, txqueue=None, parent=None, timestamp, coinbase, extra_data, min_gasprice=0) - 在给定的父区块上创建链的候选区块(默认:链的头部)。从给定的txqueue对象获取交易,并带有给定的mingasprice(否则不添加交易)。timestamp,coinbase和extra_data可以用于指定区块中的参数;否则使用默认值。
ethereum.messages
应从此处调用主函数apply_transaction(state, tx)。
ethereum.utils
包含许多实用函数,包括
数值和十六进制转换
encode_int(i) - 将整数转换为大端二进制表示
zpad(data, length) - 通过在左侧添加零字节将数据填充到所需长度
encode_int32(i) - 等同于zpad(encode_int(i), 32),但更快
big_endian_to_int(d) - 将二进制数据转换为整数
encode_hex(b) - 将字节转换为十六进制
decode_hex(h) - 将十六进制转换为字节
int_to_addr(i) - 将整数转换为地址
is_numeric(i) - 如果值是int或long,则返回True,否则返回False
密码学
sha3(data) - 计算SHA3(或更确切地说,keccak256)哈希
ecrecover_to_pub(hash, v, r, s) - 从签名恢复创建签名的公钥,作为64字节的二进制blob encode_int32(x) + encode_int32(y)。对它进行哈希处理并取最后20个字节给出签名的地址。
ecsign(hash, key) - 返回签名的v,r,s值
normalize_key(key) - 将键从多种格式转换为32字节二进制
privtoaddr(key) - 将键转换为地址
地址
normalize_address(addr) - 将地址转换为20字节二进制形式
check_checksum(addr) - 如果地址校验和通过则返回True,否则返回False
checksum_encode(addr) - 将地址转换为带有校验和的十六进制形式
mk_contract_address(addr, nonce) - 根据给定的地址和nonce创建合约的地址
杂项
denoms - 包含以太币的计量单位,例如denoms.finney = 10**15,denoms.shannon = 10**9,denoms.gwei = 10**9
ethereum.block
包含Block和BlockHeader类。通常建议避免直接创建块和块头,而是使用mk_head_candidate。成员变量很简单
block.transactions - 块中的交易
block.uncles - 块中的叔父节点
block.header - 块的头部
在头部中
header.hash - 哈希(也是块哈希)
header.mining_hash - 用于工作量证明挖掘的哈希
header.to_dict() - 序列化为可读的字典
header.prevhash - 前一个块哈希
header.uncles_hash - 叔父节点列表的哈希
header.coinbase - coinbase(矿工)地址
header.state_root - 后状态根哈希
header.tx_list_root - 块中交易的哈希
header.receipts_root - 收据梅尔树的哈希
header.bloom - bloom过滤器
header.difficulty - 块难度
header.number - 块号
header.gas_limit - 气限
header.gas_used - 已使用的气
header.timestamp - 时间戳
header.extra_data - 块额外数据
header.mixhash和header.nonce - Ethash工作量证明值
ethereum.transactions
包含Transaction类,具有以下方法和值
__init__(nonce, gasprice, startgas, to, value, data, (v, r, s optional)) - 构造函数
sign(key, network_id=None) - 使用给定的密钥并带有给定的EIP155链ID对交易进行签名,如果留为None则创建一个EIP155之前的交易,请注意此操作可能存在重放攻击!
sender - 交易的发送者地址
network_id - 交易的EIP155链ID
hash - 交易的哈希
to_dict() - 序列化为可读的字典
intrinsic_gas_used - 交易消耗的气量,包括交易数据的成本
creates - 如果交易创建了一个合约,则返回合约地址
nonce(随机数), gasprice(燃料价格), startgas(起始燃料), to(接收者地址), value(价值), data(数据), v, r, s(签名参数) - 交易参数
ethereum.tools.keys
创建加密的私钥存储
decode_keystore_json(jsondata, password) - 从加密的keystore对象中返回私钥。注意:如果您从文件中加载,最方便的方式是 import json; key = decode_keystore_json(json.load(open('filename.json')), 'password')
make_keystore_json(key, pw, kdf='pbkdf2', cipher='aes-128-ctr') - 为密钥创建一个加密的keystore对象。建议保留kdf和cipher的默认值。
ethereum.abi
在Ethereum之上,大多数HLL(solidity、serpent、viper等)的编译器都有输出程序ABI声明的选项。这是一个类似于以下内容的json对象
[{"name": "ecrecover(uint256,uint256,uint256,uint256)", "type": "function", "constant": false, "inputs": [{"name": "h", "type": "uint256"}, {"name": "v", "type": "uint256"}, {"name": "r", "type": "uint256"}, {"name": "s", "type": "uint256"}], "outputs": [{"name": "out", "type": "int256[]"}]}, {"name": "PubkeyTripleLogEvent(uint256,uint256,uint256)", "type": "event", "inputs": [{"name": "x", "type": "uint256", "indexed": false}, {"name": "y", "type": "uint256", "indexed": false}, {"name": "z", "type": "uint256", "indexed": false}]}]
您可以通过以下方式初始化一个abi.ContractTranslator对象来对合约进行编码和解码
true, false = True, False ct = abi.ContractTranslator(<json here>) txdata = ct.encode('function_name', [arg1, arg2, arg3])
您还可以调用ct.decode_event([topic1, topic2...], logdata)来解码一个日志。
RLP编码和解码
对于任何交易或块,您可以简单地做
import rlp bindata = rlp.encode(<tx or block>)
解码
import rlp from ethereum.transactions import Transaction rlp.decode(blob, Transaction)
或
import rlp from ethereum.blocks import Block rlp.decode(blob, Block)
共识抽象
pyethereum代码库旨在最大限度地适应多种不同的共识算法。如果您想添加新的共识算法,您需要执行以下步骤
在pow旁边添加一个目录,并在其中创建一个实现Chain模块的chain.py类。这可能具有完全不同的工作量证明分叉选择规则(GHOST、签名计数、Casper等)。
将条目添加到consensus_strategy.py。您需要实现
check_seal - 检查块是否被正确“密封”(挖矿、签名等)
validate_uncles(state, block) - 检查叔父是否有效
initialize(state, block) - 在处理交易之前在apply_block中调用
finalize(state, block) - 在处理交易后在apply_block中调用
get_uncle_candidates(chain, state) - 在mk_head_candidate中调用,以将叔父包含在块中
创建一个具有CONSENSUS_STRATEGY设置为您的全新共识策略名称的链配置
测试模块
请参阅https://github.com/ethereum/pyethereum/wiki/Using-pyethereum.tester
测试
运行python3.6 -m pytest ethereum/tests/<filename>以运行该目录中的任何.py文件。目前,除了几个Metropolis特定的状态测试和块测试外,所有测试都通过。
要创建自己的状态测试,请使用测试模块如下
from ethereum.tools import tester as t import json c = t.Chain() x = c.contract(<code>, language=<language>) pre = t.mk_state_test_prefill(c) x.foo(<args>) post = t.mk_state_test_postfill(c, pre) open('output.json', 'w').write(json.dumps(post, indent=4))
要创建一个测试填充文件,请执行post = t.mk_state_test_postfill(c, pre, True)。
许可证
请参阅LICENSE
项目详细信息
下载文件
下载适用于您平台上的文件。如果您不确定选择哪个,请了解有关 安装软件包 的更多信息。