Ethereumjs
使用 ethereumjs 從 BlockBodies 消息中計算交易嘗試根雜湊
給定一個解碼的
BlockBodies
消息,我想計算交易樹的根雜湊,以便我可以將它與我的節點下載的塊頭進行匹配。在查看了乙太坊交易樹是如何形成的並掃描了go-ethereum、OpenEthereum (nee Parity)和ethereumjs-block的原始碼後,我覺得我已經接近了——但我仍然沒有得到正確的結果。
以下是我的程式碼中的重要部分:
const { Transaction } = require('ethereumjs-tx') const { rlp, toBuffer } = require('ethereumjs-util') const Trie = require('merkle-patricia-tree') // Construct a Patricia trie, using each transaction's index as the key, and the // raw transaction body as the value. const tree = new Trie() tree.batch(transactionsRaw.map((t, i) => ({ type: 'put', key: rlp.encode(toBuffer(i)), value: new Transaction(t).serialize() }))) // According to Infura, the transactions trie root for block 9069000 is... console.log('Expected tx root: 0xcee16501e007fe5240aa50faa96cce60c7de8ae56f34044d850e378b98e04537') // And this is what my code generates... console.log(`Actual tx root: 0x${tree.root.toString('hex')}`)
這是我執行程式碼時得到的結果:
Expected tx root: 0xcee16501e007fe5240aa50faa96cce60c7de8ae56f34044d850e378b98e04537 Actual tx root: 0x8147ebbcffc667ee12746a2154299728a46435f4078d2f6f8b113e34f2758c6b
transactionsRaw
我已經通過反序列化每個事務並將它們的雜湊值與 Infura 進行比較來驗證它包含正確的數據。我覺得我只是將錯誤的鍵/值放入 trie,但我找不到任何範例,並且比較雜湊並不能完全提供大量回饋😅
我在這裡做錯了什麼?
在回顧了它是如何
ethereumjs-block:Block.genTxTrie()
做到的之後,我設法弄清楚了:const trie = new Trie() await Promise.all(transactionsRaw.map((t, i) => new Promise(resolve => { trie.put( rlp.encode(i), new Transaction(t).serialize(), resolve ) }) ))
或者
const trie = new Trie() const put = util.promisify(trie.put.bind(trie)) await Promise.all(transactionsRaw.map((t, i) => put(rlp.encode(i), new Transaction(t).serialize()) ))
它有效🎉
Expected tx root: 0xcee16501e007fe5240aa50faa96cce60c7de8ae56f34044d850e378b98e04537 Actual tx root: 0xcee16501e007fe5240aa50faa96cce60c7de8ae56f34044d850e378b98e04537
得到錯誤結果的原因
merkle-patricia-tree:BaseTrie.batch()
是該方法僅在底層 LevelDB 實例上執行,而不是實際的 patricia trie!