Development

如何驗證我的 merkle 根函式是否正確?

  • August 3, 2016

我最近開始在技術層面上玩比特幣(我是一位經驗豐富的軟體開發人員,但到目前為止只是比特幣的使用者)。我正在嘗試實現一個函式來計算 merkle 根,如這裡的協議文件所述。我想我已經實現了所描述的功能,但我不太確定如何去驗證我所做的事情。理想情況下,我想編寫一些單元測試,但我需要一些輸入值和期望輸出。

有誰知道我在哪裡可以找到一組交易雜湊,以及應該從那裡產生的正確的默克爾根?我真的在尋找可用於驗證函式正確性的範例輸入和輸出。

我嘗試從比特幣塊 96001複製和粘貼交易雜湊,但我正在計算的 merkle 根與 blockchain.info 上顯示的不匹配。奇怪的是,當我將相同的交易雜湊輸入BitcoinJS-lib 中的默克爾根函式時,它會產生與我的函式相同的默克爾根。我的函式和 BitcoinJS-lib 都錯了嗎?blockchain.info 錯了嗎?還是這裡發生了其他事情?

var sha256 = (buffer) => {
 return crypto.createHash('sha256')
   .update(buffer)
   .digest()
}

var doubleSha256 = (buffer) => sha256(sha256(buffer))

var merkleRoot = (hashes) => {
 if (hashes.length == 1)
   return hashes[0]

 return merkleRoot(
   _.chain(hashes)
     .chunk(2)
     .each(tuple => tuple[1] = tuple[1] || tuple[0])
     .map(tuple => Buffer.concat(tuple))
     .map(doubleSha256)
     .value()
 )
}

// Transaction hashes from block 96001:
var tx1 = Buffer.from('dcc95c8740525e27d87333558e5d0a288d0eac9062598c86c77e75dcde7178d2', 'hex')
var tx2 = Buffer.from('043cd1d9166cf16a4cc02d4385667657056cbe23f7058877c7fde09ef7de904a', 'hex')
var tx3 = Buffer.from('88b058d7e3e7b6d174d0f5a76a209a3107de65c01b010cda72ee64b22c980998', 'hex')

console.log(merkleRoot([tx1, tx2, tx3].sort()).toString('hex'));

// expected 'e7ae478c684e965d730e72b9cac644fd1ebeb1517fe69cc458d9d4070b9de8d8'
// output   'b2f52e4efbbab7653489b83d5ad331f1ada1b7e5959ac63b8aa45a786ae90279'

很可能,您有一些字節序問題。請記住,發布的 merkle 根是小端的,交易雜湊也是如此。您必須將它們反轉,然後計算 merkle 計算。

您可以在此處查看帶有 tx 雜湊的塊的詳細資訊:

<https://webbtc.com/block/00000000000000000375c25e5af8f3b2310585ad6a7c264d66398018ce4c6a41.json>

該 json 有效負載中有一個非常有用的鍵,稱為“mrkl_tree”,它告訴您 merkle 樹的所有節點(因此兩個相鄰葉節點的父節點在該集合中)。圍繞它建構測試可能是最簡單的。

引用自:https://bitcoin.stackexchange.com/questions/46843