Kopfzeile "offline" python hashen

Ich versuche zu beweisen, dass TransactionsRoot und ReceiptsRoot zu einem bestimmten Block gehören. Damit ich ohne web3 verifizieren kann, dass alle Transaktionen und Belege tatsächlich zu diesem Block gehören.

Nehmen wir an, ich habe diesen Block:

'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': []}

Wie kann ich sicherstellen, dass die Informationen über den Stamm korrekt sind? Gibt es eine einfache Möglichkeit, neu zu berechnen/zu beweisen, dass sich txRoot in diesem Block befindet und nicht geändert wurde?

Vielen Dank im Voraus

Antworten (1)

Sie stellen sicher, dass die Informationen korrekt sind, indem Sie alle Felder in ein Header-RLP-Objekt einfügen, den Hash generieren und ihn mit dem Block-Hash vergleichen. Zwei dieser Header-Felder sind der Transaktions-Root-Hash und der State-Root-Hash. Sie überprüfen alle Felder gleichzeitig.

Es gibt ein Header-Objekt in py-evm, das Sie verwenden könnten , oder Sie könnten eine minimale Version davon erstellen, wie zum Beispiel:

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))

Dann können Sie die BlockHeaderKlasse verwenden, um zu testen, ob die Felder im Header gültig sind. Erstellen Sie ein Header-Objekt und bestätigen Sie, dass der generierte Hash mit dem von Ihnen beobachteten identisch ist:

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")

In diesem Fall die Testdrucke:

Herzlichen Glückwunsch, Ihr Header-Hash stimmt mit Ihrem Transaktionsstamm, Statusstamm usw. überein.