Ethereumjs

使用 ethereumjs 從 BlockBodies 消息中計算交易嘗試根雜湊

  • March 19, 2020

給定一個解碼的BlockBodies消息,我想計算交易樹的根雜湊,以便我可以將它與我的節點下載的塊頭進行匹配。

在查看了乙太坊交易樹是如何形成的並掃描了go-ethereumOpenEthereum (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!

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