首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python构建transactionsTrie。为什么我的交易根错了?

使用Python构建transactionsTrie。为什么我的交易根错了?
EN

Ethereum用户
提问于 2018-09-28 12:30:10
回答 2查看 171关注 0票数 0

我正在尝试用python构建一个TransactionsTrie。我正在使用这个trie-Library。我按照指示行事。

编辑:删除原来的问题,因为它是愚蠢的。

@carver非常感谢。你的回答很有帮助。因此,我尝试使用从py-evm引用的方法。

这是我的完整代码:

代码语言:javascript
复制
import requests
import json
import ethereum.utils as utils
from eth.db.trie import make_trie_root_and_nodes as make_trie
from eth.rlp.transactions import BaseTransactionFields
from eth.rlp.transactions import BaseTransaction

url = 'https://ropsten.infura.io/1234'

headers = {
    "Content-Type": "application/json"
}
data = {}
data['jsonrpc'] = '2.0'
data['id'] = 1
data['method'] = 'eth_getBlockByHash'
data['params'] = ["0xd993562b847a2b61f858ee2baa2351f05e22d755d3657444f06a8c51f88a11f8", True]
data = json.dumps(data)

response = requests.post(url, headers=headers, data=str(data) )
print(response.text)
block = json.loads(response.text)
result = block['result']
raw_transactions = result['transactions']

transactions = tuple()
for tx in raw_transactions:
    nonce = tx['nonce']
    nonce = utils.int_to_big_endian(int(nonce[2:], 16))
    gas_price = tx['gasPrice']
    gas_price = utils.int_to_big_endian(int(gas_price[2:], 16))
    gas = tx['gas']
    gas = utils.int_to_big_endian(int(gas[2:], 16))
    to = tx['to']
    to = bin(int(to[2:], 16))
    value = tx['value']
    value = utils.int_to_big_endian(int(value[2:], 16))
    data = tx['input']
    print(data)
    if data != '0x':
        data = bin(int(data[2:], 16))
    else:
        data = bin(0)
    print(data)
    v = tx['v']
    v = utils.int_to_big_endian(int(v[2:], 16))
    r = tx['r']
    r = utils.int_to_big_endian(int(r[2:], 16))
    s = tx['s']
    s = utils.int_to_big_endian(int(s[2:], 16))
    f = BaseTransactionFields(nonce = nonce, gas_price = gas_price, gas = gas, to = to, value = value, data = data, v = v, r = r, s = s)
    transactions += tuple(f)

tx_root, _ = make_trie(transactions)
print(tx_root.hex())

不过,我的txRoot和块中的那个不一样。我做错了什么?

EN

回答 2

Ethereum用户

回答已采纳

发布于 2018-09-28 17:48:36

当在Ethereum中构建事务trie时,键和值都是rlp编码的.键是基于零的包含顺序,值是完整事务(而不是哈希)。

您可以看到一个示例实用程序,即trie用于生成事务trie. (为清晰性而编辑):

代码语言:javascript
复制
items = tuple(rlp.encode(object) for object in rlp_objects)

kv_store = {}  # type: Dict[Hash32, bytes]
trie = HexaryTrie(kv_store, BLANK_ROOT_HASH)

for index, item in enumerate(items):
    index_key = rlp.encode(index, sedes=rlp.sedes.big_endian_int)
    trie[index_key] = item

transaction_root = trie.root_hash
票数 1
EN

Ethereum用户

发布于 2018-10-10 10:20:05

为了记录在案,我发布了我的完整代码,以便其他人可以使用它:)

代码语言:javascript
复制
def _create_transaction(*, nonce, gasprice, startgas, to, value, data=b'', v=None, r=None, s=None, network_id=None):
    if to:
        to = address_decoder(to)
    else:
        to = b''

    if network_id is not None:
        if r is not None or s is not None:
            raise Exception(
                "cannot set network id at the same time as r and s values")
        v = network_id

    tx = Transaction(nonce, gasprice, startgas, to,
                     value, data, v or 0, r or 0, s or 0)
    tx._sender = None

    return tx


def create_transaction(tx):

    nonce = tx['nonce']
    gas_price = tx['gasPrice']
    gas = tx['gas']
    to = tx['to']
    value = tx['value']
    data = tx['input'][2:]
    if data == "":
        data = b''
    else:
        data = data_decoder(data)
    v = tx['v']
    r = int.from_bytes(tx['r'], byteorder='big')
    s = int.from_bytes(tx['s'], byteorder='big')
    return _create_transaction(nonce=nonce, gasprice=gas_price, startgas=gas, to=to, data=data, value=value, v=v, r=r, s=s)


def make_trie_root_and_nodes(items: Transactions) -> TrieRootAndData:
    return _make_trie_root_and_nodes(tuple(rlp.encode(item) for item in items))


def _make_trie_root_and_nodes(items: Tuple[bytes, ...]) -> TrieRootAndData:
    kv_store = {}  # type: Dict[Hash32, bytes]
    trie = HexaryTrie(kv_store)
    with trie.squash_changes() as memory_trie:
        for index, item in enumerate(items):
            index_key = rlp.encode(index, sedes=rlp.sedes.big_endian_int)
            memory_trie[index_key] = item
    return trie.root_hash, kv_store

make_trie_root_and_nodes函数从这里(三位一体)中复制(并略有修改)

票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/59653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档