Hash

檢查塊 #100000 的 Merkle 根

  • September 5, 2019

以下文本複制自 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 執行相同操作,則最終雜湊為:49aef42d78e3e9999c9e6ec9e1ddd​​d6cb880bf3b076a03be1318ca789089308e

我們的最後一步是將 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

到這裡一切都很簡單

比特幣的值被轉換為大端約定,但在計算雜湊時,單一類型被轉換為小端。

真實形式的交易我可以執行這段話嗎

  1. 將值形式 big-endian 轉換為 little-endian
  2. 將值轉換為十六進制
  3. 以正確的順序加入所有屬性十六進制形式
  4. 將大字元串轉換為二進制形式
  5. 應用 sha256
  6. 將結果轉換為大端

我使用了 C++,並且由於比特幣庫,他們設法完成了這個操作,但是如果你使用 python,你可以使用這個例子來計算雜湊。

建構樹的步驟很簡單,只要確保你正確計算雜湊,所以我建議你先測試雜湊函式,然後再建構樹,以避免在瑣碎的錯誤中浪費不必要的時間

ps:如果您有原始格式的事務腳本(如果您從 blk 文件中讀取資訊),它們已經轉換為 little-endian,因此不應進一步轉換。(取決於您的反序列化過程)

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