ethereum.pow.chain
包含类“Chain”,管理区块链,包括以下方法:
- __init__(genesis=None, env=None, new_head_cb=None, reset_genesis=False, localtime=None, max_history=1000, **kwargs),以给定的genesis初始化,env 指明了环境(包括区块链配置和数据库),new_head_cb 是添加新块时的回调函数,localtime 链的时间戳, max_history初始化做多链上1000个区块,kwargs 关键字参数;genesis参数可以是:
- None - 当env参数指明环境,None参数表示以env.db保存的数据创建一个Chain 实例(对象),如果reset_genesis=True,None表示重新初始化链
- 一个State对象
- genesis 声明
- 状态快照(State.snapshot())
- 一个分配(dict参数为{address:{balance: 1,nonce: 2,code: b'\x03\x04\x05',storage:{"0x06":"0x07"}}})
- add_block(block) -增加一个block
- process_time_queue - 告诉链时间戳已经更新,链将会处理“早于”最新时间戳的未被处理的区块
- get_blockhash_by_number (num)-根据区块号得到区块的hash值
- get_block(hash) -根据hash值得到区块
- get_block_by_number(num) 等价于get_block(get_blockhash_by_number(num))
- get_parent(block) -得到区块的父区块
- get_children(block) -得到区块的子区块
- head(property) -得到链头部的区块
- state(property) -得到链头部的状态
- mk_poststate_of_blockhash(hash) -为给定区块创建状态对象
- has_block(block) -判断区块是不是在链上
- get_chain(from, to) -粗略的等价于[get_block_by_number(i) for i in range(from, to)], from 缺省表示从genesis开始,to 缺省表示链的头部
- get_tx_position(tx) - 如果tx表示的交易已经在链中,返回(blknum, index),blknum表示包含交易在内的区块号,index表示交易在区块中的位置
ethereum.state
包含状态类"State",用来管理状态,包括以下方法:
- __init__(root_hash, env, **kwargs) -由根hash值,env(包括一个配置文件和数据库)和可选关键字参数初始化一个状态,包括:
- txindex - 交易序号
- gas_used - 使用的gas
- gas_limit - 区块gas限制
- block_number -区块号
- block_coinbase -区块账户地址
- block_difficulty - 区块难度
- timestamp -时间戳
- logs -目前创建的log
- receipts -在当前区块中创建的接收者
- bloom -布隆过滤器
- suicides -区块自毁
- recent-uncles - 区块链中的最近的“叔”块
- pre_headers -之前区块的头部
- refunds -区块自毁退款计数器
pyethereum遵循一个最大中心状态模型;处理交易或区块所需的唯一信息位于状态本身内,允许实际的状态转换逻辑apply_transaction(state, tx)和apply_block(state, block)
- get_balance -账户余额
- get_code -账户的代码
- get_storage_data(addr, k) -给定地址,给定键(key)的存储
- to_snapshot(root_only=False, no_prevblock=False) - 创建当前状态的快照。
- 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)在给定父区块的顶部为链创建候选区块
ethereum.messages
在这里应该调用主函数apply_transaction(state, tx)
ethereum.utils
包含一组使用函数,包括:
Numerical and hex conversions
- encode_int(i) - 整数编码成二进制数
- zpad(data, length) -左侧填充位数到想到的长度
- encode_int32(i) -等价于zpad(encode_int(i), 32)
- big_endian_to_int(d) -把二进制数据转换成整数
- encode_hex(b) -把字节转换成hex
- decode-hex(h) -hex转换成字节
- int_to_addr(i) -整数转换成地址
- is_numeric(i) -是int或long型返回True
Cyptography
- sha3(data) - 计算sha3的hash值
- ercevover_to_pub(hash, v, r, s)- 恢复出使签名成为encode_int32(x) + encode_int32(y)混合的64字节二进制公钥。对公钥签名并且取最后20个字节给出了签名消息的地址。
- ecsign(hash, key) -返回签名的 v,r,s 值
- normalize_key(key) -把其他格式的key转换成32字节的key
- privtoaddr(key) -把私钥转化成地址
Addresses
- normalize_address(addr) -把地址转换成20字节的二进制形式
- check_checksum(addr) -返回bool值,检查地址的checksum
- checksum_encode(addr) -把带checksum的地址转换成hex 形式
- mk_contract_address(addr, nonce) -根据地址和nonce创建合约的地址
Miscellaneous
- denoms -包含的以太的面值 denoms.finney = 10 **15,denoms.shanon = 10 ** 9, denoms.gwei = 10 ** 9
ethereum.block
包含Block和BlockHeader 类,不推荐创建Block和BlockHeader对象,一般使用mk_head_candidate替换,Block类的成员变量
- block.transactions - 区块包含的交易
- block.uncles -区块的叔块
- block.header -区块的头
header:
- header.hash -哈希值
- header.mining_hash -Pof 挖矿使用的hash值
- header.to_dict()- 把区块头格式化为可读的格式
- header.prevhash -前一个区块的hash值
- header.uncles_hash -叔列表的hash值
- header.coinbase- 账户地址
- header.state_root - 后状态的根hash值
- header.tx_list_root - 区块交易的hash列表
- header.recipients_root -接收树的hash值
- header.bloom -布隆过滤器
- header.difficulty -区块难度
- header.number -区块号
- header.gas_limit - gas限制
- header.gas_used -已使用的gas
- header.timestamp -时间戳
- header.extra_data -区块的额外数据
- header.mixhash 和 header.nonce PoW的Ethash值
ethereum.transactions
包含Transaction 类,包括接下里的方法和值:
- __init__(nonce, gasprice, startgas, to, value, data, (v, r, s optional)) -构造函数
- sign(key, network_id=None) -用给定的EIP155链ID和给定的key来给交易签名,(network_id为空将会创建pre-EIP155 tx,可能会受到再次支付的攻击)
- sender - 交易的发送id
- netword_id -EIP155链的交易ID
- hash - 交易的hash值
- to_dict ()- 换成人类可读的
- intrinsic_gas_used -交易耗费的gas,包括发送数据的消耗
- creates - 如果交易创建了合约,那么返回合约地址
- nonce, gasprice, startgas, to, value, data, v, r, s -交易的参数
ethereum.tools.keys
创建加密私钥存储
- decode_keystore_json(jsondata, password) -从加密密码库对象获取私钥;如果需要load一个文件,最方便的方法是:import json, key = decode_keystore_json(json.load(open('filename.json')),''password)
- make_keystore_json(key, pw, kdf='pbkdf2', cipher='aes-128-ctr') - 为key创建一个加密密码对象,推荐使用kdf和cipher默认值
ethereum.abi
以太坊平台上的大多数HLLS(slidity, serpent, viper)的编译器都有一个输出ABI声明的选项,是json格式的
可以初始化abi.ContractTranslator对象来编码或解码合约数据
true,false = True, False
ct = abi.ConstractTranslator(<json here>)
txdata = ct.decode('function_name'),[arg1, arg2, arg3]
也可以调用ct.decode_event([topic1, topic2 ...] ,logdata) 解码log
RLP encoding and decoding
对于任何交易或区块,你可以简单地:
import rlp
bindata = rlp.encode(<tx or block>)
解码:
import rlp
from ethereum.transactions import Transaction
rlp.decode(blob, Transation)
或:
import rlp
from ethereum.blocks import Block
rlp.decode(blob, Block)
Consensus abstraction
pyethereum 代码库旨在最大限度地有好的用于许多不同的共识算法。如果你想添加新的共识算法,则需要执行以下步骤:
- 在pow同级目录下添加chain.py, 实现Chain 模块,这可能有一个完全不同的叉选择规则,用于工作证明(GHOST,签名计数,Casper等)
- 增加一个consensus_strategy.py的入口,需要实现以下:
- check_seal -检查一个区块是否正确的“sealed”(挖矿,签名等等)
- validate_uncles(state, block) - 检查叔块是否有效
- initialize(state, block)-在交易处理之前在apply_block中调用
- finalize(state, block) -交易完成之后在apply_block中调用
- get_uncle_candidates(chain, state) -在mk_head_candidate中调用来包含一个区块的叔块
- 创建一个链配置,并将CONSENSUS_STRATEGY设置为你为新的共识算法命名的任何内容
Tester module
- Tests
运行 python3.6 -m pytest ethereum/tests/<filename> 命令,对这个目录中的任何文件。目前所有的测试都已经通过除了几个特大的状态测试和块测试
完成自己的状态测试,按照以下方法使用tester
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)