Transactions

雜湊標頭“離線”python

  • October 16, 2018

我試圖證明 TransactionsRoot 和 ReceiptsRoot 確實屬於特定的塊。這樣我就可以在沒有 web3 的情況下驗證所有交易和收據實際上都屬於這個塊。

可以說我有這個塊:

'difficulty': 3963642329, 
'extraData': '0xd88301080f846765746888676f312e31302e31856c696e7578'), 
'gasLimit': 8000000, 
'gasUsed': 7987824, 
'hash': '0x47b8f62c1400dae65105d2f8e03824bfc58481c0b32f45788ad3378fbc05e9f6', 
'logsBloom': '0x0800012104000104c00400108000400000003000000040008400000002800100000a00000000000001010401040001000001002000000000020020080000240200000000012260010000084800420200040000100000030800802000112020001a200800020000000000500010100a00000000020401480000000010001048000011104800c002410000000010800000000014200040000400000000000000600020c00000004010080000000020100200000200000800001024c4000000080100004002004808000102920408810000002000008000000008000120400020008200d80000000010010000008028004000010000008220000200000100100800', 
'miner': '0x6A9ECfa04e99726eC105517AC7ae1aba550BeA6c', 
'mixHash': '0x0c0026c706351083c0a913e084dee16ca133b813baa6a174e4fb179d9f2ecc52', 
'nonce': '0xf245822d3412da7f', 
'number': 4156209, 
'parentHash': '0xad22d4d8f0e94032cb32e86027e0a5533d945ed95088264e91dd71e4fbaebeda', 
'receiptsRoot': '0xeb1e644436f93be8a9938dfe598cb7fd729f9d201b6f7c0695bee883b3ea6a5b', 
'sha3Uncles': '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', 
'size': 27324, 'stateRoot': '0x43e3325393fbc583a5a0b56e98073fb81e82d992b52406a79d662b690a4d2753', 
'timestamp': 1538483791, 
'totalDifficulty': 11844984547350924, 
'transactions': [.......], 
'transactionsRoot': '0x40c339f7715932ec591d8c0c588bacfaed9bddc7519a1e6e87cf45be639de810', 'uncles': []}

我怎樣才能確保有關根的資訊是正確的?有沒有一種簡單的方法來重新計算/證明 txRoot 在那個塊中並且沒有被改變?

先感謝您

您可以通過將所有欄位放入 Header RLP 對象、生成散列並將其與塊散列進行比較來確保資訊正確。其中兩個標頭欄位是交易根雜湊和狀態根雜湊。您同時驗證所有欄位。

您可以使用 py-evm 中的標頭對象,或者您可以建構它的最小版本,例如:

from eth_utils import keccak
import rlp
from rlp.sedes import (
   BigEndianInt,
   big_endian_int,
   Binary,
   binary,
)

address = Binary.fixed_length(20, allow_empty=True)
hash32 = Binary.fixed_length(32)
int256 = BigEndianInt(256)
trie_root = Binary.fixed_length(32, allow_empty=True)

class BlockHeader(rlp.Serializable):
   fields = [
       ('parent_hash', hash32),
       ('uncles_hash', hash32),
       ('coinbase', address),
       ('state_root', trie_root),
       ('transaction_root', trie_root),
       ('receipt_root', trie_root),
       ('bloom', int256),
       ('difficulty', big_endian_int),
       ('block_number', big_endian_int),
       ('gas_limit', big_endian_int),
       ('gas_used', big_endian_int),
       ('timestamp', big_endian_int),
       ('extra_data', binary),
       ('mix_hash', binary),
       ('nonce', Binary(8, allow_empty=True))
   ]

   def hash(self) -> bytes:
       return keccak(rlp.encode(self))

然後您可以使用BlockHeader該類來測試標頭中的欄位是否有效。建構一個標頭對象,並確認生成的雜湊與您觀察到的相同:

from eth_utils import to_bytes, to_hex

header = BlockHeader(
   parent_hash=to_bytes(0xad22d4d8f0e94032cb32e86027e0a5533d945ed95088264e91dd71e4fbaebeda),
   uncles_hash=to_bytes(0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347),
   coinbase=to_bytes(0x6A9ECfa04e99726eC105517AC7ae1aba550BeA6c),
   state_root=to_bytes(0x43e3325393fbc583a5a0b56e98073fb81e82d992b52406a79d662b690a4d2753),
   transaction_root=to_bytes(0x40c339f7715932ec591d8c0c588bacfaed9bddc7519a1e6e87cf45be639de810),
   receipt_root=to_bytes(0xeb1e644436f93be8a9938dfe598cb7fd729f9d201b6f7c0695bee883b3ea6a5b),
   bloom=0x0800012104000104c00400108000400000003000000040008400000002800100000a00000000000001010401040001000001002000000000020020080000240200000000012260010000084800420200040000100000030800802000112020001a200800020000000000500010100a00000000020401480000000010001048000011104800c002410000000010800000000014200040000400000000000000600020c00000004010080000000020100200000200000800001024c4000000080100004002004808000102920408810000002000008000000008000120400020008200d80000000010010000008028004000010000008220000200000100100800,
   difficulty=3963642329,
   block_number=4156209,
   gas_limit=8000000,
   gas_used=7987824,
   timestamp=1538483791,
   extra_data=to_bytes(0xd88301080f846765746888676f312e31302e31856c696e7578),
   mix_hash=to_bytes(0x0c0026c706351083c0a913e084dee16ca133b813baa6a174e4fb179d9f2ecc52),
   nonce=to_bytes(0xf245822d3412da7f),
)

if to_hex(header.hash()) == '0x47b8f62c1400dae65105d2f8e03824bfc58481c0b32f45788ad3378fbc05e9f6': 
   print("Congratulations, your header hash matches your transaction root, state root, etc.") 
else: 
   print("Sorry, your header hash does not match one of your header fields")

在這種情況下,測試列印:

恭喜,您的標頭雜湊與您的交易根、狀態根等相匹配。

引用自:https://ethereum.stackexchange.com/questions/60594