區塊鏈

簡介

區塊鏈的資料結構是有序的,向前鏈接的區塊和交易的列表。區塊鏈可以儲存為一個扁平的檔案,或者簡單的資料庫。Bitcoin Core客戶端使用Google的LevelDB資料庫儲存區塊鏈的元數據。區塊向前鏈接,每個區塊都指向它的前一個區塊。區塊鏈經常被可視化為垂直的堆疊,第一個區塊作為堆疊底,其他的依次向上堆疊。彼此堆疊的區塊堆疊形式引出了 "height" 的術語,來代表區塊與第一個區塊的距離,"top" 和 "tip" 指代最新添加的區塊。

區塊鏈中的每個區塊都由一個雜湊值標識,在該區塊頭上使用SHA256加密雜湊演算法生成。每個區塊還通過區塊頭中的 "previous block hash"(上一個區塊的雜湊值)欄位引用先前的區塊,稱為 parent 區塊。換句話說,每個區塊在其自己的頭部中包含其父區塊的雜湊值。雜湊值序列創建了一個鏈,將每個區塊連接到其父項,一直鏈接到有第一個區塊,稱為 創世區塊 genesis block

儘管一個區塊只有一個父區塊,但它可以暫時擁有多個子區塊。每個子區塊都指向相同的區塊作為它們的父區塊,並在 "previous block hash" 欄位中包含相同的(父區塊的)雜湊。在區塊鏈"分叉"期間會出現多個子區塊,這是一種臨時情況,當不同的礦區幾乎同時由不同的礦工發現時(參見 [forks])。最終,只有一個子區塊成為區塊鏈的一部分,"fork"就解決了。一個區塊可能有多個子區塊,但每個區塊只有一個父區塊。這是因為一個區塊只有一個引用其單親的 "previous block hash" 欄位。

"previous block hash" 欄位在區塊的頭部,並且影響當前區塊的雜湊值。如果父區塊的標識改變,子區塊的標識也會改變。當父區塊以某種方式改變,父區塊的雜湊值就會改變。父區塊變化了的雜湊值要求子區塊的 "previous block hash" 也必須改變,這又會引起孫子區塊的改變,以此類推。這種級聯效應可以確保一旦一個區塊在其之後有許多後代,它就不能在不強制重新計算所有後續區塊的情況下進行更改。由於重新計算需要大量的計算(耗費大量的能源),長鏈區塊的存在使得區塊鏈的歷史不可更改,這是比特幣安全性的一個關鍵特徵。

看待區塊鏈的一種方式就像地質構造中的層或冰川巖芯樣本。表層可能隨著季節變化,甚至在沉澱之前被吹走。但是一旦深入幾英寸,地質層就變得越來越穩定。當你向下看幾百英尺時,你會看到幾百萬年來一直沒有受到干擾的過去的快照。在區塊鏈中,如果由於分叉導致鏈重新計算,可能會修改最近的幾個區塊。前六個區塊就像是幾英寸的表土。一旦你深入區塊鏈超過六個區塊,區塊變化的可能性就越來越小。在100個區塊之前,穩定性非常高,以至於可以花費coinbase交易 - 包含新開採的比特幣的交易。幾千個區塊(一個月),對於所有實際目的來說,區塊鏈都已成確定的歷史。雖然協議總是允許一條鏈被一條較長的鏈消除,任何區塊被反轉的可能性總是存在的,但是這種事件的可能性會隨著時間流逝而減少,直到它變得無限小。

區塊的結構

區塊是一個容器資料結構,用於彙總包含在公共賬本(區塊鏈)中的交易。區塊有一個包含元數據的頭部,後面跟著一個長長的交易列表。區塊頭為80位元組,平均交易至少為400位元組,平均每區塊包含超過1900個交易。一個包含所有交易的完整區塊因此比區塊頭大10,000倍。 The structure of a block 描述了一個區塊的結構。

Table 1. The structure of a block
Size Field Description

4 bytes

Block Size

The size of the block, in bytes, following this field

80 bytes

Block Header

Several fields form the block header

1——9 bytes (VarInt)

Transaction Counter

How many transactions follow

Variable

Transactions

The transactions recorded in this block

區塊頭

區塊頭由三組區塊元數據組成。首先,有一個對前區塊雜湊值的引用,它將這個區塊連接到區塊鏈中的前一個區塊。第二組元數據,分別為 難度 difficulty時間戳 timestamp隨機數 nonce,與挖礦競賽有關,參見 [mining]。第三個元數據是merkle樹根,這是一種資料結構,用於有效地彙總區塊中的所有交易。The structure of the block header 描述了區塊頭的結構。

Table 2. The structure of the block header
Size Field Description

4 bytes

Version

A version number to track software/protocol upgrades

32 bytes

Previous Block Hash

A reference to the hash of the previous (parent) block in the chain

32 bytes

Merkle Root

A hash of the root of the merkle tree of this block’s transactions

4 bytes

Timestamp

The approximate creation time of this block (seconds from Unix Epoch)

4 bytes

Difficulty Target

The Proof-of-Work algorithm difficulty target for this block

4 bytes

Nonce

A counter used for the Proof-of-Work algorithm

隨機數,難度目標,和時間戳用於挖礦過程,在 [mining] 中有詳細介紹。

區塊標識符:區塊頭的雜湊值和區塊高度

區塊的主要標識符是它的加密雜湊值,這是一種數位指紋,通過SHA256演算法將區塊頭兩次雜湊獲得。得到的32位元組雜湊被稱為 block hash ,更準確地說是 block header hash,因為只有區塊頭用於計算。例如 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f 是第一個區塊的雜湊值, 區塊的雜湊值唯一而明確地標識一個區塊,任何節點都可以通過簡單地對區塊頭進行雜湊來獨立地派生它。

注意,區塊的雜湊值實際上並不包含在區塊的資料結構中,無論是在網路上傳輸區塊時,還是作為區塊鏈的一部分儲存在節點的持久性儲存時。相反,當從網路接收區塊時,每個節點計算區塊的雜湊值。區塊雜湊值可以作為區塊元數據的一部分儲存在單獨的資料庫表中,以方便索引並從硬碟快速檢索。

另一種識別區塊的方法是它在區塊鏈中的位置,稱為 區塊高度 block height。第一個區塊位於區塊高度0處,與被雜湊值 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f 引用的區塊相同。區塊可以通過兩種方式標識:通過引用區塊的雜湊值或通過引用區塊高度。在第一個區塊的"頂部"添加的每個後續區塊在區塊鏈中都在一個"更高"的位置,就像一個盒子疊在另一個上面一樣。2017年1月1日的區塊鏈高度約為44.6萬,這意味著在2009年1月創建的第一個區塊的頂部有446000個區塊。

與區塊雜湊值不同,區塊高度不是唯一標識符。儘管單個區塊總是具有特定且不變的區塊高度,但反過來並不正確 —— 區塊高度並不總是標識一個區塊。兩個或更多區塊可能具有相同的區塊高度,爭奪區塊鏈中的相同位置。這種情況將在 [forks] 一節中詳細討論。區塊高度也不是區塊的資料結構的一部分;它不儲存在區塊中。當從比特幣網路收到區塊時,每個節點都會動態識別區塊在區塊鏈中的位置(高度)。區塊高度也可以作為元數據儲存在索引資料庫表中以加快檢索速度。

Tip

區塊的block hash總是唯一標識一個區塊。區塊也總是有一個特定的block height。但是,特定的區塊高度並不總是能夠標識單個區塊。相反,兩區塊或更多區塊可能會在區塊鏈中爭奪一個位置。

創世區塊

區塊鏈中的第一個區塊被稱為創世區塊,於2009年創建。它是區塊鏈中所有區塊的共同祖先,這意味著如果你從任何區塊開始,並隨時間上向前追溯,最終將到達創世區塊。

節點總是以至少一個區塊的區塊鏈開始,因為這個區塊是在比特幣客戶端軟體中靜態編碼的,因此它不能被改變。每個節點總是"知道"起始區塊的雜湊和結構,它創建的固定時間,以及其中的單一交易。因此,每個節點都有區塊鏈的起點,這是一個安全的"根",從中可以構建受信任的區塊鏈。

請參閱 chainparams.cpp 中 Bitcoin Core 客戶端內的靜態編碼的genesis區塊。

以下雜湊值標識符屬於創世區塊:

000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

你可以在任何區塊瀏覽器網站(例如 blockchain.info )中搜索該區塊雜湊值,你將找到一個描述此區塊內容的頁面,包含該雜湊的URL:

在命令行中使用 Bitcoin Core 客戶端:

$ bitcoin-cli getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
{
    "hash" : "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
    "confirmations" : 308321,
    "size" : 285,
    "height" : 0,
    "version" : 1,
    "merkleroot" : "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
    "tx" : [
        "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
    ],
    "time" : 1231006505,
    "nonce" : 2083236893,
    "bits" : "1d00ffff",
    "difficulty" : 1.00000000,
    "nextblockhash" : "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
}

創世區塊包含一個隱藏的訊息。幣基交易的輸入包含的文字是 "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks."。此訊息旨在通過參考英國報紙 The_Times 的標題提供此區塊創建的最早日期的證據。它還半開玩笑地提醒人們關注獨立貨幣體系的重要性,比特幣發行時正值前所未有的全球貨幣危機。比特幣的創造者Satoshi Nakamoto將這個訊息嵌入了第一區塊。

在區塊鏈中鏈接區塊

比特幣完整節點保留了區塊鏈從創世區塊開始的本地副本。區塊鏈的本地副本會隨著新區塊被發現並用於擴展鏈而不斷更新。當一個節點通過網路接收到區塊時,它驗證這些區塊,然後將它們鏈接到現有的區塊鏈。為了建立鏈接,節點將檢查傳入的區塊頭並查找"previous block hash"。

例如,假設一個節點在區塊鏈的本地副本中有277,314個區塊。節點知道的最後一個區塊是區塊277,314,區塊頭的雜湊值為:

00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249

然後,該節點從網路接收一個新的區塊,解析如下:

{
    "size" : 43560,
    "version" : 2,
    "previousblockhash" :
        "00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249",
    "merkleroot" :
        "5e049f4030e0ab2debb92378f53c0a6e09548aea083f3ab25e1d94ea1155e29d",
    "time" : 1388185038,
    "difficulty" : 1180923195.25802612,
    "nonce" : 4215469401,
    "tx" : [
        "257e7497fb8bc68421eb2c7b699dbab234831600e7352f0d9e6522c7cf3f6c77",

 #[... many more transactions omitted ...]

        "05cfd38f6ae6aa83674cc99e4d75a1458c165b7ab84725eda41d018a09176634"
    ]
}

查看這個新區塊,找到 previousblockhash 欄位,其中包含其父區塊的雜湊值。它是節點所知道的雜湊值,是位於鏈的277,314高度的最後一個區塊。因此,這個新區塊是鏈上最後一個區塊的孩子,並擴展了現有的區塊鏈。該節點將此新區塊添加到鏈的末端,使區塊鏈更長,新的高度為277,315。Blocks linked in a chain by reference to the previous block header hash 顯示三個區塊的鏈,通過 previousblockhash 欄位中的引用鏈接。

默克爾樹 Merkle Trees

比特幣區塊鏈中的每個區塊都包含一個 merkle tree ,作為所有交易的彙總。

默克爾樹 merkle tree, 也叫做 二元雜湊樹 binary hash tree, 是一種用於有效彙總和驗證大型數據集的完整性的資料結構。 Merkle樹是包含加密雜湊的二元樹。術語"樹"在電腦科學中被用來描述分支的資料結構,但是這些樹通常是顛倒顯示的,"根"在頂部,"葉子"在底部,你將在下面的例子中看到。

mbc2 0901.png
Figure 1. Blocks linked in a chain by reference to the previous block header hash

比特幣中使用Merkle樹來彙總區塊中的所有交易,為整個交易集提供全面的數位指紋,提供了一個非常有效的流程來驗證交易是否包含在區塊中。 Merkle樹是通過對節點對兒(pairs of nodes)進行遞歸雜湊構造的,直到只有一個雜湊,稱為 rootmerkle root。比特幣的merkle樹中使用的加密雜湊演算法是將SHA256應用兩次,也稱為double-SHA256。

當N個數據元素被雜湊並彙總到一個Merkle樹中時,你可以檢查樹中是否包含任何一個數據元素,並且最多隻需 2*log2~(N) 次計算,因此這是一個非常有效的資料結構。

Merkle樹是自下而上構建的。在下面的例子中,我們從四個交易開始,A,B,C和D,它們構成了merkle樹的 葉子 leaves,如 Calculating the nodes in a merkle tree 所示。交易不儲存在merkle樹中;相反,它們的數據被雜湊並且所得到的雜湊值被儲存在每個葉節點中,如 HA,HB,HC 和 HD

HA = SHA256(SHA256(Transaction A))

然後將連續的葉節點對彙總到父節點中,方法是連接兩個雜湊值並對它們進行雜湊。例如,要構造父節點 HAB,將子節點的兩個32位元組雜湊值連接起來,以創建一個64位元組的字串。然後對該字串進行雙重雜湊來產生父節點的雜湊值:

HAB = SHA256(SHA256(HA + HB))

繼續該過程,直到頂部只有一個節點,該節點被稱為merkle根。該32位元組雜湊值儲存在區塊頭中,彙總了四個交易中的所有數據。Calculating the nodes in a merkle tree 展示瞭如何通過節點的成對雜湊來計算根。

merkle_tree
Figure 2. Calculating the nodes in a merkle tree

由於merkle樹是二元樹,它需要偶數個葉節點。如果要彙總的交易數量為奇數,則最後一個交易的雜湊值將被複制以創建偶數個葉節點,這稱為 平衡的樹 balanced tree。在 << merkle_tree_odd>> 中,交易C被複制。

merkle_tree_odd
Figure 3. Duplicating one data element achieves an even number of data elements

使用四個交易構造樹的方法可以推廣到構造任意大小的樹。在比特幣中,通常在一個區塊中有幾百到幾千個交易,這些交易的彙總方式完全相同,僅產生單個Merkle根的32個位元組的數據。在 A merkle tree summarizing many data elements 中,你將看到一棵由16個交易構成的樹。請注意,儘管根看起來比圖中的葉節點大,但它的大小完全相同,只有32個位元組。無論區塊中是否有一個交易或十萬個交易,merkle根總是將它們總結為32個位元組。

為了證明一個區塊中包含一個特定的交易,一個節點只需要產生 log2~(N) 個32個位元組的雜湊值,構成一個認證 pathmerkle_path,將特定的交易連接到樹的根。隨著交易數量的增加,這一點尤為重要,因為交易數量的基數為2的對數增長速度要慢得多。這使得比特幣節點能夠高效地生成10或12個雜湊值(320-384位元組)的路徑,這可以提供兆位元組大小的區塊中超過一千個交易中的單個交易的驗證。

merkle_tree_large
Figure 4. A merkle tree summarizing many data elements

A merkle path used to prove inclusion of a data element 中,節點可以通過產生只有四個32位元組雜湊長(總共128位元組)的merkle路徑來證明交易K包含在該區塊中。該路徑由四個雜湊值組成( 在 << merkle_tree_path>> 帶藍色背景的 ),HL,HIJ,HMNOP 和 HABCDEFGH。通過提供這四個雜湊值作為驗證路徑,任何節點都可以通過計算四個額外的雜湊值來證明 HK(底部黑色背景的)包含在Merkle根中:HKL,HIJKL,HIJKLMNOP 和merkle樹根(在圖中用虛線表示)。

merkle_tree_path
Figure 5. A merkle path used to prove inclusion of a data element

Building a merkle tree 中的程式碼演示瞭如何使用libbitcoin的一些輔助函數,創建從葉節點雜湊值一直到根的Merkle樹。

Example 1. Building a merkle tree
link:code/merkle.cpp[]

Compiling and running the merkle example code 展示了編譯和運行結果

Example 2. Compiling and running the merkle example code
$ # Compile the merkle.cpp code
$ g++ -o merkle merkle.cpp $(pkg-config --cflags --libs libbitcoin)
$ # Run the merkle executable
$ ./merkle
Current merkle hash list:
  32650049a0418e4380db0af81788635d8b65424d397170b8499cdc28c4d27006
  30861db96905c8dc8b99398ca1cd5bd5b84ac3264a4e1b3e65afa1bcee7540c4

Current merkle hash list:
  d47780c084bad3830bcdaf6eace035e4c6cbf646d103795d22104fb105014ba3

Result: d47780c084bad3830bcdaf6eace035e4c6cbf646d103795d22104fb105014ba3

隨著規模的增加,梅克爾樹的效率變得越來越明顯。 Merkle tree efficiency 展示了證明交易是區塊的一部分鎖需要的作為merkle路徑交換的數據量。

Table 3. Merkle tree efficiency
Number of transactions Approx. size of block Path size (hashes) Path size (bytes)

16 transactions

4 kilobytes

4 hashes

128 bytes

512 transactions

128 kilobytes

9 hashes

288 bytes

2048 transactions

512 kilobytes

11 hashes

352 bytes

65,535 transactions

16 megabytes

16 hashes

512 bytes

從表中可以看出,區塊大小從16個交易的4KB快速增加到65,535個交易的16MB,證明交易存在所需的Merkle路徑則增加得很慢,從128位元組到只有512位元組。使用merkle樹,節點可以只下載區塊頭(每區塊80個位元組),並且仍然能夠通過從完整節點檢索小型merkle路徑來證實交易包含在區塊中,而不儲存或傳輸絕大量的(可能幾個GB)區塊鏈數據。不維護完整區塊鏈的節點稱為簡單支付驗證(SPV)節點,它使用merkle路徑驗證交易而無需下載完整區塊。

Merkle 樹和簡單支付驗證節點

Merkle樹被SPV節點廣泛使用。 SPV節點沒有全部交易,並且不下載完整的區塊,只有區塊頭。為了驗證區塊中包含交易,而不必下載區塊中的所有交易,它們使用驗證路徑(merkle路徑)。

例如,考慮一個SPV節點,它對付款到它的錢包中地址的交易感興趣。SPV節點將在其與對等節點的連接上建立一個布林過濾器(參見 [bloom_filters] ),將接收到的交易限制為那些只包含其感興趣地址的交易。當對等節點看到與bloom過濾器匹配的交易時,它將使用 merkleblock 訊息發送該區塊。merkleblock 訊息包含區塊的頭,以及將感興趣的交易鏈接到區塊中的merkle根的merkle路徑。SPV節點可以使用此Merkle路徑將交易連接到區塊並驗證交易是否包含在區塊中。 SPV節點還使用區塊頭將區塊鏈接到區塊鏈的其餘部分。交易和區塊之間以及區塊和區塊鏈之間的這兩個鏈接的組合證明交易記錄在區塊鏈中。總而言之,SPV節點將接收到少於一千位元組的數據區塊頭和merkle路徑,其數據量比完整區塊(當前大約1兆位元組)少一千倍以上。

比特幣的測試區塊鏈

你可能會驚訝地發現有多個比特幣區塊鏈。 2009年1月3日由中本聰創建的"主"比特幣區塊鏈,帶有我們本章研究的創世區塊,被稱為 主網 mainnet。還有其他用於測試的比特幣區塊鏈,現在有:testnetsegnetregtest。讓我們依次看下。

測試網路 —— 比特幣的測試場

Testnet是用於測試目的的測試區塊鏈,網路和貨幣的名稱。測試網是一個全功能的活躍P2P網路,包括錢包,測試比特幣(testnet硬幣),挖礦以及 mainnet 的所有其他功能。實際上只有兩個區別:測試網點的硬幣價值很低,挖礦難度應該足夠低,以便任何人都可以相對容易地開採測試網硬幣。

任何擬用於比特幣主網生產的軟體開發應首先使用測試幣在測試網上進行測試。這可以保護開發人員免受由於錯誤導致的資金損失,並保護網路免受由於錯誤導致的意外行為。

然而,保持硬幣毫無價值並且容易挖,並不容易。儘管開發者提出了要求,但有些人使用高級挖礦設備(GPU和ASIC)在測試網上進行挖礦,增加了難度,使得不可能用CPU進行挖礦,最終使其難以獲得,人們開始評估它們的價值,因此它們也不是毫無價值的。因此,現在或者之後,測試網必須被廢棄並從新的創世區塊重新啟動,重新設置難度。

當前的測試網成為 testnet3,第三代 testnet,2011年2月重啟,重置了前一代測試網的難度。

請記住,testnet3是一個大型的區塊鏈,2017年初超過了20GB。耗盡電腦資源完全同步需要一天左右的時間。不如mainnet大,但也不是"輕量級"的。運行測試網路節點的一個好的方法是作為專用於此目的的虛擬機映像(例如,VirtualBox,Docker,雲伺服器等)。

使用測試網

像幾乎所有其他比特幣軟體一樣,Bitcoin Core完全支援在testnet而不是mainnet上運行。Bitcoin Core的所有功能都在測試網路上運行,包括錢包,開採測試網的幣,以及同步完整的測試網節點。

要在測試網上啟動 Bitcoin Core,使用 testnet 選項:

$ bitcoind -testnet

在日誌中,你應該看到bitcoind正在預設bitcoind目錄的 testnet3 子目錄中構建新的區塊鏈:

bitcoind: Using data directory /home/username/.bitcoin/testnet3

你可以使用 bitcoin-cli 命令行工具連接到bitcoind,但也必須將其切換到testnet模式:

$ bitcoin-cli -testnet getblockchaininfo
{
  "chain": "test",
  "blocks": 1088,
  "headers": 139999,
  "bestblockhash": "0000000063d29909d475a1c4ba26da64b368e56cce5d925097bf3a2084370128",
  "difficulty": 1,
  "mediantime": 1337966158,
  "verificationprogress": 0.001644065914099759,
  "chainwork": "0000000000000000000000000000000000000000000000000000044104410441",
  "pruned": false,
  "softforks": [

  [...]

你還可以使用其他完整節點實現(如 btcd(用Go編寫)和 bcoin(用JavaScript編寫))在testnet3上運行,以便在其他程式語言和框架中進行實驗和學習。

2017年初,testnet3支援了mainnet的所有功能,包括隔離見證(參見 [segwit])。因此,testnet3也可以用來測試隔離見證功能。

Segnet —— 隔離見證測試網

2016年啟動了一個特殊用途的測試網,幫助開發和測試隔離見證(又名segwit;見 [segwit])。該測試區塊鏈被稱為 segnet,可以通過運行Bitcoin Core的特殊版本(分支)加入。

由於segwit已添加到testnet3,因此不再需要使用segnet來測試segwit功能。

未來,我們可能會看到其他像segnet一樣,專門設計用於測試單個功能或主要架構更改的testnet區塊鏈。

Regtest —— 本地區塊鏈

Regtest代表"迴歸測試",它是一種Bitcoin Core功能,允許你為測試目的創建本地區塊鏈。與公共測試區塊鏈testnet3不同,regtest區塊鏈旨在作為封閉系統運行以進行本地測試。你從零開始啟動一個regtest區塊鏈,創建一個本地創世區塊。你可以將其他節點添加到網路,或者僅使用單個節點運行它來測試Bitcoin Core軟體。

要以 regtest 模式啟動 Bitcoin Core,使用 regtest 選項:

$ bitcoind -regtest

與testnet一樣,Bitcoin Core會在你的bitcoind預設目錄的 regtest 子目錄下初始化一個新的區塊鏈:

bitcoind: Using data directory /home/username/.bitcoin/regtest

要使用命令行工具,你需要指定 regtest 標誌:

$ bitcoin-cli -regtest getblockchaininfo
{
  "chain": "regtest",
  "blocks": 0,
  "headers": 0,
  "bestblockhash": "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206",
  "difficulty": 4.656542373906925e-10,
  "mediantime": 1296688602,
  "verificationprogress": 1,
  "chainwork": "0000000000000000000000000000000000000000000000000000000000000002",
  "pruned": false,
  [...]

如你所見,現在還沒有區塊。讓我們挖一些(500區塊)並獲得獎勵:

$ bitcoin-cli -regtest generate 500
[
  "7afed70259f22c2bf11e406cb12ed5c0657b6e16a6477a9f8b28e2046b5ba1ca",
  "1aca2f154a80a9863a9aac4c72047a6d3f385c4eec5441a4aafa6acaa1dada14",
  "4334ecf6fb022f30fbd764c3ee778fabbd53b4a4d1950eae8a91f1f5158ed2d1",
  "5f951d34065efeaf64e54e91d00b260294fcdfc7f05dbb5599aec84b957a7766",
  "43744b5e77c1dfece9d05ab5f0e6796ebe627303163547e69e27f55d0f2b9353",
   [...]
  "6c31585a48d4fc2b3fd25521f4515b18aefb59d0def82bd9c2185c4ecb754327"
]

只需要幾秒鐘的時間來挖出這些區塊,這使得測試很容易。如果你檢查你的錢包餘額,你會看到你獲得了前400個區塊的獎勵(coinbase獎勵必須達到在100個區塊後才可以消費):

$ bitcoin-cli -regtest getbalance
12462.50000000

使用測試區塊鏈進行開發

比特幣的各種區塊鏈( regtest、segnet、testnet3、mainnet)為比特幣開發提供了一系列測試環境。無論你是為Bitcoin Core開發還是另一個完整節點共識客戶端,都可以使用測試區塊鏈。應用程式,如錢包、交換、電子商務網站;甚至開發新穎的智慧合約和複雜的腳本。

你可以使用測試區塊鏈建立開發管道。開發時,在 regtest 上本地測試你的程式碼。一旦準備好在公共網路上嘗試它,切換到 testnet 以將程式碼暴露於有多種的程式碼和應用的,更具動態性的環境中。最後,一旦你確信自己的程式碼能夠按預期工作,請切換到 mainnet 以在生產環境中進行部署。當你進行更改,改進,錯誤修復等時,請再次啟動管道,首先是 regtest,然後是 testnet,最後部署到生產環境中。