區塊鏈研究實驗室|如何使用Merkle樹驗證​交易區塊

買賣虛擬貨幣

前言

本教程旨在簡化對比特幣如何使用Merkle樹驗證交易區塊的講解。Merkle根是透過將成對的txid雜湊一起建立的,它為區塊中的所有事務提供了一個簡短但唯一的認證。

然後將這個merkle根用作於區塊頭中的欄位,這意味著每個區塊頭將對區塊內的每個事務都有一個簡潔的表示。

本教程將演示如何計算merkle根欄位。

先決條件

本教程將需要訪問比特幣節點。我們建議以regtest模式配置節點進行,這樣我們就可以自由地玩各種場景,而不必浪費真正的BTC。但是您也可以針對testnet或mainnet配置執行這些操作。

在深入到Merkle樹之前,讓我們先了解一下它們的操作所需的專業術語,稱為hash函式或trapdoor函式。這些函式在一個方向上很容易計算,但在沒有特殊資訊的情況下(稱為“陷阱門”)很難在相反的方向上計算(求逆)。Trapdoor功能廣泛用於密碼學。雜湊函式是可用於將任意大小的數字資料對映到固定大小的任何函式,輸入資料的細微差異會導致輸出資料的很大差異。

其中一些雜湊函式包括md5、sha1和sha256。

使用sha256的示例

gr0kchain@bitcoindev $ echo -en "Hello World"| openssl dgst -sha256
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

這裡我們提供資料Hello World並將其傳遞到opnessl命令,並帶有sha256的摘要標誌。我們在這裡收到的輸出是輸入資料的認證a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e。任何在相同輸入資料上使用sha256的人都會產生相同的雜湊值。對資料的輕微更改會導致完全不同的雜湊值。

gr0kchain@bitcoindev $ echo -en "Hello World."| openssl dgst -sha256
f4bb1975bf1f81f76ce824f7536c1e101a8060a632a52289d530a6f600d52c92

關於merkle樹的一些背景

在前面的示例中,我們簡要介紹瞭如何從任意輸入資料生成唯一的認證。當我們需要為大量資料提供加密證明時,這非常有用。這些資料可以用所謂的merkle或hash樹表示。Merkle Trees是一種資料結構,您可以從中派生與前面所指出的相同的雜湊。

merkle樹的一個特性是,葉節點層中的任何更改都將導致完全不同的merkle根雜湊。因此,我們可以使用這個資料結構來驗證一組資料的完整性。

從命令列計算merkle根目錄

讓我們完成生成merkle root所需的步驟:

1、生成一個新地址。

gr0kchain@bitcoindev $ bitcoin-cli getnewaddress
mgKkU7NQsDrMZ6uY1J7on9TyKKeH3FNnhH

2、將比特幣傳送到新地址。

gr0kchain@bitcoindev $ bitcoin-cli sendtoaddress mgKkU7NQsDrMZ6uY1J7on9TyKKeH3FNnhH 1
a99011a19e9894753d6c65c8fa412838ea8042886537588e7205734d5de8956d

3、生成新區塊。

gr0kchain@bitcoindev $ bitcoin-cli generate 1
[
"1e871187ba510207d88f1bb0aa1895fb2420066277fdbba7c857b339810dfcec"
]

4、獲取區塊的資訊。

gr0kchain@bitcoindev $ bitcoin-cli getblock 

1e871187ba510207d88f1bb0aa1895fb2420066277fdbba7c857b339810dfcec
{
"hash""1e871187ba510207d88f1bb0aa1895fb2420066277fdbba7c857b

339810dfcec",
"confirmations"1,
"size"553,
"height"132,
"version"536870912,
"merkleroot""25c8487847de572c21bff029a95d9a9fecd9f4c2736984b9

79d37258cd47bd1f",
"tx": [
"3bd3a1309a518c381248fdc26c3a6bd62c35db7705069f59206684308cc237b3",
"a99011a19e9894753d6c65c8fa412838ea8042886537588e7205734d5de8956d"
  ],
"time"1553088284,
"mediantime"1553087229,
"nonce"3,
"bits""207fffff",
"difficulty"4.656542373906925e-10,
"chainwork""000000000000000000000000000000000000000000000000000000000000010a",
"previousblockhash""78c3c76fe213ca9f5a0f616b155341eb12b963ce10107b18c9ff612cfc90843d"
}

這裡我們可以看到該塊的兩個事務識別符號為3bd3a1309a518c381248fdc26c3a6bd62c35db7705069f59206684308cc237b3(我們的coinbase)和a99011a19e9894753d6c65c8fa412838ea8042886537588e7205734d5de8956d(我們上面執行的事務的識別符號)

5、接下來,我們需要將這些位元組順序從大到小顛倒過來(網路位元組順序)

gr0kchain@bitcoindev $ (export LC_ALL=C; xxd -revert -plain 

<<< 3bd3a1309a518c381248fdc26c3a6bd62c35db7705069f59206684308cc237b3

| rev | tr -d '\n'| xxd -plain | tr -d '\n')
b337c28c30846620599f060577db352cd66b3a6cc2fd4812388c519a30a1d33b
gr0kchain@bitcoindev $ (export LC_ALL=C; xxd -revert -plain 

<<< a99011a19e9894753d6c65c8fa412838ea8042886537588e7205734d5de8956d 

| rev | tr -d '\n'| xxd -plain | tr -d '\n')
6d95e85d4d7305728e583765884280ea382841fac8656c3d7594989ea11190a9

注意:此處使用LC_ALL = C刪除所有本地化設定。

6、連線這些值並從二進位制資料計算sha256摘要

gr0kchain@bitcoindev $ echo -en "b337c28c30846620599f060577db352cd66b3a6cc2fd4812388c519a30a1d33b6d95e85d4d7305728e583765884280ea382841fac8656c3d7594989ea11190a9"| xxd -r -p | sha256
c1f8c1f3b52135cf7f9d0f9422d6d826f4097631615fcc44e3ec70461c27b7b2

7、將此值轉換為二進位制,並在輸出上執行另一個sha256操作

gr0kchain@bitcoindev $ echo -en "c1f8c1f3b52135cf7f9d0f9422d6d826f4097631615fcc44e3ec70461c27b7b2"| xxd -r -p | sha256
1fbd47cd5872d379b9846973c2f4d9ec9f9a5da929f0bf212c57de477848c825

8、最後,顛倒順序從小到大。

gr0kchain@bitcoindev $ (export LC_ALL=C; xxd -revert -plain <<< 1fbd47cd5872d379b9846973c2f4d9ec9f9a5da929f0bf212c57de477848c825 | rev | tr -d '\n'| xxd -plain | tr -d '\n')
25c8487847de572c21bff029a95d9a9fecd9f4c2736984b979d37258cd47bd1f

我們現在有來自bitcoin-cli getblock命令的原始merkleroot值! 您可以根據需要重複此過程。

只包含coinbase事務的區塊的merkle根的異常

上述過程的一個例外是為包含單個事務的區塊生成merkle根。

gr0kchain@bitcoindev $ bitcoin-cli generate 1
[
"78c3c76fe213ca9f5a0f616b155341eb12b963ce10107b18c9ff612cfc90843d"
]
gr0kchain@bitcoindev $ bitcoin-cli getblock 78c3c76fe213ca9f5a0f616b155341eb12b963ce10107b18c9ff612cfc90843d
{
"hash""78c3c76fe213ca9f5a0f616b155341eb12b963ce10107b18c9ff612cfc90843d",
"confirmations"1,
"size"181,
"height"131,
"version"536870912,
"merkleroot""4415425121d3e80d3d733323ecdc981d43b6888241b99c0217a6b7184b021f5e",
"tx": [
"4415425121d3e80d3d733323ecdc981d43b6888241b99c0217a6b7184b021f5e"
  ],
"time"1553088104,
"mediantime"1553087066,
"nonce"0,
"bits""207fffff",
"difficulty"4.656542373906925e-10,
"chainwork""0000000000000000000000000000000000000000000000000000000000000108",
"previousblockhash""0d0c6c9b2c5b48451832c15cf6e8856772df2a0760f8614dbc0734e1e9d7171a"
}

在這裡我們可以看到merkle root與coinbase事務的事務id相同。還有另一種情況,如果葉節點的數量不均勻,則將現有的tx id附加到葉節點列表以計算第一級雜湊對。

結論

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;