精通比特幣(第九章)【區塊鏈】

風靈使發表於2018-10-09

9.1簡介

區塊鏈的資料結構是由包含交易資訊的區塊按照從遠及近的順序有序連結起來的。它可以被儲存為平面檔案(flat file),或是儲存在一個簡單資料庫中。比特幣核心客戶端使用Google的LevelDB資料庫儲存區塊鏈後設資料。區塊被從遠及近有序地連結在這個鏈條裡,每個區塊都指向前一個區塊。區塊鏈經常被視為一個垂直的棧,第一個區塊作為棧底的首區塊,隨後每個區塊都被放置在之前的區塊之上。用棧來形象化表示區塊依次堆疊這一概念後,我們便可以使用 一些術語,例如:“高度”來表示區塊與首區塊之間的距離;以及“頂部”或“頂端”來表示最新新增的區塊。

對每個區塊頭進行SHA256加密雜湊,可生成一個雜湊值。通過這個雜湊值,可以識別出區塊鏈中的對應區塊。同時, 每一個區塊都可以通過其區塊頭的“父區塊雜湊值”欄位引用前一區塊(父區塊)。也就是說,每個區塊頭都包含它的父區塊雜湊值。這樣把每個區塊連結到各自父區塊的雜湊值序列就建立了一條一直可以追溯到第一個區塊(創世區塊)的 鏈條。

雖然每個區塊只有一個父區塊,但可以暫時擁有多個子區塊。每個子區塊都將同一區塊作為其父區塊,並且在“父區塊雜湊值”欄位中具有相同的(父區塊)雜湊值。一個區塊出現多個子區塊的情況被稱為“區塊鏈分叉”。區塊鏈分叉只是暫時狀態,只有當多個不同區塊幾乎同時被不同的礦工發現時才會發生(參見“區塊鏈分叉”)。最終,只有一個子區塊會成為區塊鏈的一部分,同時解決了“區塊鏈分叉”的問題。儘管一個區塊可能會有不止一個子區塊,但每一區塊只有 一個父區塊,這是因為一個區塊只有一個“父區塊雜湊值”欄位可以指向它的唯一父區塊。

由於區塊頭裡麵包含“父區塊雜湊值”欄位,所以當前區塊的雜湊值也受到該欄位的影響。如果父區塊的身份標識發生變化,子區塊的身份標識也會跟著變化。當父區塊有任何改動時,父區塊的雜湊值也發生變化。這將迫使子區塊的“父區塊雜湊值”欄位發生改變,從而又將導致子區塊的雜湊值發生改變。而子區塊的雜湊值發生改變又將迫使孫區塊的“父區塊雜湊值”欄位發生改變,又因此改變了孫區塊雜湊值,以此類推。一旦一個區塊有很多代以後,這種瀑布效應將保證該區塊不會被改變,除非強制重新計算該區塊所有後續的區塊。正是這樣的重新計算需要耗費巨大的計算量,所以一個長區塊鏈的存在可以讓區塊鏈的歷史不可改變,這也是比特幣安全性的一個關鍵特徵。

你可以把區塊鏈想象成地質構造中的地質層或者是冰川巖芯樣品。表層可能會隨著季節而變化,甚至在沉積之前就被風吹走了。但是越往深處,地質層就變得越穩定。到了幾百英尺深的地方,你看到的將是儲存了數百萬年但依然保持歷史原狀的岩層。在區塊鏈裡,最近的幾個區塊可能會由於區塊鏈分叉所引發的重新計算而被修改。最新的六個區塊就像幾英寸深的表土層。但是,超過這六塊後,區塊在區塊鏈中的位置越深,被改變的可能性就越小。在100個區塊以後,區塊鏈已經足夠穩定,這時Coinbase交易(包含新挖出的比特幣的交易)可以被支付。幾千個區塊(一個月)後的區塊鏈將變成確定的歷史,永遠不會改變。

9.2 區塊結構

區塊是一種被包含在公開賬簿(區塊鏈)裡的聚合了交易資訊的容器資料結構。它由一個包含後設資料的區塊頭和緊跟其後的構成區塊主體的一長串交易列表組成。區塊頭是80位元組,而平均每個交易至少是250位元組,而且平均每個區塊至少包含超過500個交易。因此,一個包含所有交易的完整區塊比區塊頭大1000倍。表7-1描述了一個區塊結構。

表7-1 區塊結構

9.3 區塊頭

區塊頭由三組區塊後設資料組成。首先是一組引用父區塊雜湊值的資料,這組後設資料用於將該區塊與區塊鏈中前一區塊相連線。第二組後設資料,即難度、時間戳和nonce,與挖礦競爭相關,詳見挖礦章節。第三組後設資料是merkle樹根(一種用來有效地總結區塊中所有交易的資料結構)。表7-2描述了區塊頭的資料結構。

表7-2 區塊頭結構

Nonce、難度目標和時間戳會用於挖礦過程,更多細節將在挖礦章節討論。

9.4 區塊識別符號:區塊頭雜湊值和區塊高度

區塊主識別符號是它的加密雜湊值,一個通過SHA256演算法對區塊頭進行二次雜湊計算而得到的數字指紋。產生的32位元組雜湊值被稱為區塊雜湊值,但是更準確的名稱是:區塊頭雜湊值,因為只有區塊頭被用於計算。例 如:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f是第一個比特幣區塊的區塊雜湊值。區塊雜湊值可以唯一、明確地標識一個區塊,並且任何節點通過簡單地對區塊頭進行雜湊計算都可以獨立地獲取該區塊雜湊值。

請注意,區塊雜湊值實際上並不包含在區塊的資料結構裡,不管是該區塊在網路上傳輸時,抑或是它作為區塊鏈的一部分被儲存在某節點的永久性儲存裝置上時。相反,區塊雜湊值是當該區塊從網路被接收時由每個節點計算出來的。區塊的雜湊值可能會作為區塊後設資料的一部分被儲存在一個獨立的資料庫表中,以便於索引和更快地從磁碟檢索區塊。

第二種識別區塊的方式是通過該區塊在區塊鏈中的位置,即“區塊高度(block height)”。第一個區塊,其區塊高度為 0,和之前雜湊值000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f所引用的區塊為同一 個區塊。因此,區塊可以通過兩種方式被識別:區塊雜湊值或者區塊高度。每一個隨後被儲存在第一個區塊之上的區塊在區塊鏈中都比前一區塊“高”出一個位置,就像箱子一樣,一個接一個堆疊在其他箱子之上。2017年1月1日的區塊高度大約是 446,000,說明已經有446,000個區塊被堆疊在2009年1月建立的第一個區塊之上。

和區塊雜湊值不同的是,區塊高度並不是唯一的識別符號。雖然一個單一的區塊總是會有一個明確的、固定的區塊高度, 但反過來卻並不成立,一個區塊高度並不總是識別一個單一的區塊。兩個或兩個以上的區塊可能有相同的區塊高度,在區塊鏈裡爭奪同一位置。這種情況在“區塊鏈分叉”一節中有詳細討論。區塊高度也不是區塊資料結構的一部分, 它並不被儲存在區塊裡。當節點接收來自比特幣網路的區塊時,會動態地識別該區塊在區塊鏈裡的位置(區塊高度)。 區塊高度也可作為後設資料儲存在一個索引資料庫表中以便快速檢索。

提示一個區塊的區塊雜湊值總是能唯一地識別出一個特定區塊。一個區塊也總是有特定的區塊高度。但是,一 個特定的區塊高度並不一定總是能唯一地識別出一個特定區塊。更確切地說,兩個或者更多數量的區塊也許會為了區塊鏈中的一個位置而競爭。

9.5 創世區塊

區塊鏈裡的第一個區塊建立於2009年,被稱為創世區塊。它是區塊鏈裡面所有區塊的共同祖先,這意味著你從任一區塊,循鏈向後回溯,最終都將到達創世區塊。
因為創世區塊被編入到比特幣客戶端軟體裡,所以每一個節點都始於至少包含一個區塊的區塊鏈,這能確保創世區塊不會被改變。每一個節點都“知道”創世區塊的雜湊值、結構、被建立的時間和裡面的一個交易。因此,每個節點都把該區塊作為區塊鏈的首區塊,從而構建了一個安全的、可信的區塊鏈。
chainparams.cpp裡可以看到創世區塊被編入到比特幣核心客戶端裡。

創世區塊的雜湊值為:

0000000000 19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

你可以在任何區塊瀏覽網站搜尋這個區塊雜湊值,如blockchain.info,你會發現一個描述這一區塊內容的頁面,該頁面的連結包含了這個區塊雜湊值:

https://blockchain.info/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
https://blockexplorer.com/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

在命令列使用比特幣核心客戶端:

$ 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"
}

創世區塊包含一個隱藏的資訊。在其Coinbase交易的輸入中包含這樣一句話“The Times 03/Jan/2009 Chancellor on brink of second bailout forbanks.”這句話是泰晤士報當天的頭版文章標題,引用這句話,既是對該區塊產生時間的說明,也可視為半開玩笑地提醒人們一個獨立的貨幣制度的重要性,同時告訴人們隨著比特幣的發展,一場前所未有的世界性貨幣革命將要發生。該訊息是由比特幣的創立者中本聰嵌入創世區塊中。

9.6 區塊連結成為區塊鏈

比特幣的全節點在本地儲存了區塊鏈從創世區塊起的完整副本。隨著新的區塊的產生,該區塊鏈的本地副本會不斷地更新用於擴充套件這個鏈條。當一個節點從網路接收傳入的區塊時,它會驗證這些區塊,然後連結到現有的區塊鏈上。為建立一個連線,一個節點將檢查傳入的區塊頭並尋找該區塊的“父區塊雜湊值”。

讓我們假設,例如,一個節點在區塊鏈的本地副本中有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"
]
}

對於這一新的區塊,節點會在“父區塊雜湊值”欄位裡找出包含它的父區塊的雜湊值。這是節點已知的雜湊值,也就是第 277314塊區塊的雜湊值。故這個新區塊是這個鏈條裡的最後一個區塊的子區塊,因此現有的區塊鏈得以擴充套件。節點將新的區塊新增至鏈條的尾端,使區塊鏈變長到一個新的高度277,315。圖9-1顯示了通過“父區塊雜湊值”欄位進行連線三個區塊的鏈。

圖9-1 區塊通過引用父區塊的區塊頭雜湊值的方式,以鏈條的形式進行相連

圖9-1通過引用前面的區塊頭雜湊連線成區塊鏈

9.7 Merkle 樹

區塊鏈中的每個區塊都包含了產生於該區塊的所有交易,且以Merkle樹表示。

Merkle樹是一種雜湊二叉樹,它是一種用作快速歸納和校驗大規模資料完整性的資料結構。這種二叉樹包含加密雜湊值。術語“樹”在計算機學科中常被用來描述一種具有分支的資料結構,但是樹常常被倒置顯示,“根”在圖的上部同時“葉子”在圖的下部,你會在後續章節中看到相應的例子。

在比特幣網路中,Merkle樹被用來歸納一個區塊中的所有交易,同時生成整個交易集合的數字指紋,且提供了一種校驗區塊是否存在某交易的高效途徑。生成一棵完整的Merkle樹需要遞迴地對一對節點進行雜湊,並將新生成的雜湊節點插入到Merkle樹中,直到只剩一個雜湊節點,該節點就是Merkle樹的根。在比特幣的Merkle樹中兩次使用到了SHA256 演算法,因此其加密雜湊演算法也被稱為double-SHA256

當N個資料元素經過加密後插入Merkle樹時,你至多計算2*log2(N) 次就能檢查出任意某資料元素是否在該樹中,這使得該資料結構非常高效。

Merkle樹是自底向上構建的。在如下的例子中,我們從A、B、C、D四個構成Merkle樹樹葉的交易開始,如圖9-2。

圖9-2 在Merkle樹中計算節點

圖9-2計算默克樹中的節點

所有的交易都並不儲存在Merkle樹中,而是將資料雜湊化,然後將雜湊值儲存至相應的葉子節點。這些葉子節點分別是HA、HB、HC和HD

HA = SHA256(SHA256(Transaction A))

將相鄰兩個葉子節點的雜湊值串聯在一起進行雜湊,這對葉子節點隨後被歸納為父節點。 例如,為了建立父節點HAB,子節點 A和子節點B的兩個32位元組的雜湊值將被串聯成64位元組的字串。隨後將字串進行兩次雜湊來產生父節點的雜湊值:

 HAB = SHA256(SHA256(H~A~ + H~B~))

繼續類似的操作直到只剩下頂部的一個節點,即Merkle根。產生的32位元組雜湊值儲存在區塊頭,同時歸納了四個交易的所有資料。圖9-2展示瞭如何通過成對節點的雜湊值計算Merkle樹的根。

因為Merkle樹是二叉樹,所以它需要偶數個葉子節點。如果僅有奇數個交易需要歸納,那最後的交易就會被複制一份以構成偶數個葉子節點,這種偶數個葉子節點的樹也被稱為平衡樹。如圖9-3所示,C節點被複制了一份。

圖9-3 複製一份資料節點,使整個樹中資料節點個數是偶數

圖9-3複製一個資料元素可以實現偶數個資料元素

由四個交易構造Merkle樹的方法同樣適用於從任意交易數量構造Merkle樹。在比特幣中,在單個區塊中有成百上千的交易是非常普遍的,這些交易都會採用同樣的方法歸納起來,產生一個僅僅32位元組的資料作為Merkle根。在圖9-4中,你會看見一個從16個交易形成的樹。需要注意的是,儘管圖中的根看起來比所有葉子節點都大,但實際上它們都是32位元組的相同大小。無論區塊中有一個交易或者有十萬個交易,Merkle根總會把所有交易歸納為32位元組。

圖9-4 歸納了許多資料元素的Merkle樹

圖9-4Merkle樹彙總了許多資料元素

為了證明區塊中存在某個特定的交易,一個節點只需要計算log2(N)個32位元組的雜湊值,形成一條從特定交易到樹根的認證路徑或者Merkle路徑即可。隨著交易數量的急劇增加,這樣的計算量就顯得異常重要,因為相對於交易數量的增長,以基底為2的交易數量的對數的增長會緩慢許多。這使得比特幣節點能夠高效地產生一條10或者12個雜湊值(320~384位元組)的路徑,來證明了在一個巨量位元組大小的區塊中上千交易中的某筆交易的存在。

在圖9-5中,一個節點能夠通過生成一條僅有4個32位元組雜湊值長度(總128位元組)的Merkle路徑,來證明區塊中存在一 筆交易K。該路徑有4個雜湊值(在圖9-5中由藍色標註)HL、HIJ、HMNOP和HABCDEFGH。由這4個雜湊值產生的認證路徑,再通過計算另外四對雜湊值HKL、HIJKL、HIJKLMNOP和Merkle樹根(在圖中由虛線標註),任何節點都能證明HK(在圖中由綠色標註)包含在Merkle根中。

圖9-5 一條為了證明樹中包含某個資料元素而使用的Merkle路徑

圖9-5用於證明包含資料元素的merkle路徑

例7-1中的程式碼借用libbitcoin庫中的一些輔助程式,演示了從葉子節點雜湊至根建立整個Merkle樹的過程。

例9-1 構造Merkle樹

code/merkle.cpp[]

例9-2展示了編譯以及執行上述程式碼後的結果

\ # 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樹的高效隨著交易規模的增加而變得異常明顯。表9-3展示了為了證明區塊中存在某交易而所需轉化為Merkle路徑的資料量。

表9-3 Merkle樹的效率

從表中可以看出,當區塊大小由16筆交易(4KB)急劇增加至65,535筆交易(16MB)時,為證明交易存在的Merkle路徑長度增長極其緩慢,僅僅從128位元組到512位元組。有了Merkle樹,一個節點能夠僅下載區塊頭(80位元組/區塊),然後通過從一個滿節點回溯一條小的Merkle路徑就能認證一筆交易的存在,而不需要儲存或者傳輸大量區塊鏈中大多數內容,這些內容可能有幾個G的大小。這種不需要維護一條完整的區塊鏈的節點,又被稱作簡單支付驗證(SPV)節點,它不需要下載整個區塊而通過Merkle路徑去驗證交易的存在。

9.8 Merkle樹和簡單支付驗證(SPV)

Merkle樹被SPV節點廣泛使用。SPV節點不儲存所有交易也不會下載整個區塊,僅僅儲存區塊頭。它們使用認證路徑或者Merkle路徑來驗證交易存在於區塊中,而不必下載區塊中所有交易。

例如,一個SPV節點想知道它錢包中某個比特幣地址即將到達的支付。該節點會在節點間的通訊連結上建立起bloom過濾器,限制只接受含有目標比特幣地址的交易。當對等體探測到某交易符合bloom過濾器,它將以Merkleblock訊息的形式傳送該區塊。Merkleblock訊息包含區塊頭和一條連線目標交易與Merkle根的Merkle路徑。SPV節點能夠使用該路徑找到與該交易相關的區塊,進而驗證對應區塊中該交易的有無。SPV節點同時也使用區塊頭去關聯區塊和區塊鏈中的其餘區塊。這兩種關聯,交易與區塊、區塊和區塊鏈,就可以證明交易存在於區塊鏈。簡而言之,SPV節點會收到少於1KB的有關區塊頭和Merkle路徑的資料,其資料量比一個完整的區塊(目前大約有1MB)少了一千多倍。

9.9比特幣的測試區塊鏈

你可能會驚訝地發現,有多個比特幣區塊鏈。 2009年1月3日由Satoshi Nakamoto建立的“主要”比特幣塊鏈,本章研究的創世區塊所在的網路,被稱為主網。另外還有其他用於測試的比特幣區塊鏈:現存的有testnet,segnet和regtest。我們依次看看每一個。

9.9.1Testnet——比特幣的試驗場

Testnet是用於測試的區塊鏈,網路和貨幣的總稱。 testnet是一個功能齊全的線上P2P網路,包括錢包,測試比特幣(testnet幣),挖礦以及類似主網的所有其他功能。實際上它和主網只有兩個區別:testnet幣是毫無價值的,挖掘難度足夠低,任何人都可以相對容易地使用testnet幣)。

任何打算在比特幣主幹網上用於生產的軟體開發都應該首先在testnet上用測試幣進行測試。這樣可以保護開發人員免受由於軟體錯誤而導致的金錢損失,也可以保護網路免受由於軟體錯誤導致的意外攻擊。

然而,保持測試幣的無價值和易挖掘並不容易。儘管有來自開發商的呼籲,但還是有人使用先進的裝置(GPU和ASIC)在testnet上挖礦。這就增加了難度,使用CPU挖礦不可能,導致獲取測試幣非常困難,以致於人們開始賦予其一定價值,所以測試幣並不是毫無價值。結果,時不時地testnet必須被報廢並重新從創始區塊啟動,重新進行難度設定。

目前的testnet被稱為testnet3,是testnet的第三次迭代,於2011年2月重啟,重置了之前的testnet網路的難度。

請記住,testnet3是一個大區塊鏈,在2017年初超過20 GB。完全同步需要一天左右的時間,並佔用您的計算機資源。它不像主網,也不是“輕量級”。執行testnet節點的一個好方法就是將其執行為一個專用的虛擬機器映象(例如,VirtualBox,Docker,Cloud Server等)。

9.9.1.1使用testnet

像幾乎所有其他比特幣軟體一樣,Bitcoin Core完全支援在testnet網路執行而不是隻能網上執行,還允許您進行測試幣挖礦並執行一個testnet全節點。

如果要在testnet上啟動Bitcoin Core,而不是在主網啟動,您可以使用testnet開關:


$ bitcoind -testnet

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

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

要連線bitcoind,可以使用bitcoin-cli命令列工具,但是要記得切換到testnet模式:

$ bitcoin-cli -testnet getinfo

{

  "version": 130200,
  
  "protocolversion": 70015,
  
  "walletversion": 130000,
  
  "balance": 0.00000000,
  
  "blocks": 416,
  
  "timeoffset": 0,
  
  "connections": 3,
  
  "proxy": "",
  
  "difficulty": 1,
  
  "testnet": true,
  
  "keypoololdest": 1484801486,
  
  "keypoolsize": 100,
  
  "paytxfee": 0.00000000,
  
  "relayfee": 0.00001000,
  
  "errors": ""
  
}

您還可以使用getblockchaininfo命令確認testnet3區塊鏈的詳細資訊和同步進度:

$ bitcoin-cli -testnet getblockchaininfo

{

  "chain": "test",
  
  "blocks": 1088,
  
  "headers": 139999,
  
  "bestblockhash": "0000000063d29909d475a1c4ba26da64b368e56cce5d925097bf3a2084370128",
  
  "difficulty": 1,
  
  "mediantime": 1337966158,
  
  "verificationprogress": 0.001644065914099759,
  
  "chainwork": "0000000000000000000000000000000000000000000000000000044104410441",
  
  "pruned": false,
  
  "softforks": [

  [...]

在testnet3上,你也可以執行使用其他語言和框架實現的全節點來實驗和學習,例如btcd(用Go編寫)和bcoin(用JavaScript編寫)。

在2017年初,testnet3支援主網的所有功能,也包括在主網路上尚未啟用的隔離見證(Segregated Witness(見[segwit]隔離見證章節))。 因此,testnet3也可用於測試隔離見證功能。

9.9.2 Segnet—隔離見證測試網路

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

由於已經將segwit新增到testnet3中,因此後來不再使用segnet來測試segwit功能。

在將來,我們可能會看到其他專門用於測試單個功能或主要架構更改(如segnet)的測試網路區塊鏈。

9.9.3 Regtest–本地區塊鏈

Regtest代表“迴歸測試”,是一種比特幣核心功能,允許您建立本地區塊鏈以進行測試。 與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標誌。 我們來試試getblockchaininfo命令來檢查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

9.10使用測試塊鏈進行開發

Bitcoin的各種區塊鏈(regtest,segnet,testnet3,以及主網)為比特幣開發提供了一系列測試環境。 無論您是開發比特幣核心還是另一個全節點共識客戶端,諸如錢包,交易所,電子商務網站等應用程式,甚至開發新穎的智慧合同和複雜的指令碼等等,請使用測試區塊鏈網進行開發。

您可以使用測試區塊鏈來建立開發管道。 在開發它時,建議在本地測試程式碼。 一旦您準備好在公共網路上嘗試,請切換到testnet,將您的程式碼暴露在更加動態的環境中,並提供更多樣化的程式碼和應用程式。 最後,一旦您確信您的程式碼正常工作,請切換到主網以實現生產部署。 當您進行變更,改進,錯誤修復等操作時,再次啟動這個開發管道,首先在regtest上部署每個變更,然後在testnet上進行測試,最後實現生產。

相關文章