檢查塊 #100000 的 Merkle 根
以下文本複制自 bitcoin.org 上的比特幣開發者參考:
如果一個區塊有三個或更多的交易,就會形成中間的默克爾樹行。TXID 按順序排列並配對,從 coinbase 交易的 TXID 開始。每對以 64 個原始字節的形式連接在一起,並經過 SHA256(SHA256()) 散列以形成第二行散列。如果有奇數(非偶數)個 TXID,則將最後一個 TXID 與其自身的副本連接起來並進行散列處理。如果第二行中有兩個以上的散列,則重複該過程以創建第三行(如有必要,進一步重複以創建其他行)。一旦獲得只有兩個散列的行,這些散列將連接並散列以產生默克爾根。
我正在嘗試使用此邏輯為塊 #100000 重新創建 merkle 根。此區塊中有 4 筆交易。我首先將 coinbase 交易的交易雜湊和緊隨其後的交易雜湊複製到 Sha256 計算器中以獲取雜湊。然後我再對該雜湊值進行一次雜湊:Sha256(sha256())。我對塊中的後兩個交易再重複一次該過程。最後,我使用生成的雜湊再次重複該過程以獲得默克爾根。不幸的是,這與 blockchain.info 的塊頭中顯示的 Merkle Root 無關。
有人可以解釋我哪裡出錯了嗎?
謝謝。
您必須在散列它們之前對交易 ID 進行字節交換,對每個子節點進行散列,然後對最終散列的十六進制值進行字節交換。
事務 1(Coibase 事務)8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87
要對其進行 Byteswap,您可以使用:
a = “8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87” “".join(reversed([a[i:i+2] for i in range(0, len(a), 2)])) @Greg Hewgill
字節交換 = 876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148c
事務 2 fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4 字節交換 = c40297f730dd7b5a99567eb8d27b78758f607507c52292d252d403189b5
您想要連接字節交換的事務值 1 和 2。事務 1 先執行。
876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148cc40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff
要散列這個十六進製字元串,您可以在命令終端中使用以下執行 Python 的程式碼:
> > > > > > 導入雜湊庫 > > > > > > transaction12_hex = “876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148cc40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff” > > > > > > transaction12_bin = transaction12_hex.decode(‘hex’) > > > > > > 雜湊 = hashlib.sha256(hashlib.sha256(transaction12_bin).digest()).digest() > > > > > > hash.encode(‘hex_codec’) > > > > > > 15b88c5107195bf09eb9da89b83d95b3d070079a3c5c5d3d17d0dcd873fbdacc > > > > > > > > >
事務 3 6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4 字節交換 = c46e239ab7d28e2c019b6d66ad8fae98a56ef1f21aeecb94d1b1718186f05963
事務 4 e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d 字節交換 = 1d0cb83721529a062d9675b98d6e5c587e4a770fc84ed00abc5a5de0e496
如果您對事務 3 和 4 執行相同操作,則最終雜湊為:49aef42d78e3e9999c9e6ec9e1dddd6cb880bf3b076a03be1318ca789089308e
我們的最後一步是將 1 & 2 和 3 & 4 的最終散列值組合起來,並對其進行雙重散列和字節交換。
我們的答案是 f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766 Merkle Root。
我認為錯誤是正確建構雜湊,我也是同樣的問題,現在我想分享我的經驗。
為了建構雜湊,我使用了這個很好的庫c++/java。
我將嘗試用簡單的程式碼來解釋自己。
這是創世塊的交易雜湊
string versionRawTransaction = "01000000"; string numbarTransactionInput = "01"; string output = "0000000000000000000000000000000000000000000000000000000000000000ffffffff"; string scriptLenght = "4d"; string scriptSing = "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73"; string sequences = "ffffffff"; string numbarTransactionOutput = "01"; string cAmmount = "00f2052a01000000"; string publicKeyScriptLenght = "43"; string publicKeyScript = "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac"; string lockTime = "00000000";
完整的雜湊是
01000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF4D04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73FFFFFFFF0100F2052A01000000434104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A67962E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C702B6BF11D5FAC00000000
什麼時候計算雜湊。我能得到這個雜湊嗎
4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
到這裡一切都很簡單
比特幣的值被轉換為大端約定,但在計算雜湊時,單一類型被轉換為小端。
真實形式的交易我可以執行這段話嗎
- 將值形式 big-endian 轉換為 little-endian
- 將值轉換為十六進制
- 以正確的順序加入所有屬性十六進制形式
- 將大字元串轉換為二進制形式
- 應用 sha256
- 將結果轉換為大端
我使用了 C++,並且由於比特幣庫,他們設法完成了這個操作,但是如果你使用 python,你可以使用這個例子來計算雜湊。
建構樹的步驟很簡單,只要確保你正確計算雜湊,所以我建議你先測試雜湊函式,然後再建構樹,以避免在瑣碎的錯誤中浪費不必要的時間
ps:如果您有原始格式的事務腳本(如果您從 blk 文件中讀取資訊),它們已經轉換為 little-endian,因此不應進一步轉換。(取決於您的反序列化過程)