《精通比特幣》第八章“挖礦與共識”解讀——區塊鏈基礎知識篇

本章介紹比特幣系統的挖礦和去中心化的共識機制,對於以後區塊鏈項目的共識機制設計有很好的借鑑參考意義,我儘量讓沒有技術基礎的朋友也能看明白。

建議閱讀時長:20分鐘

第1節 概述

挖礦主要有2大作用:挖礦是一種將交易結算去中心化的過程,同時挖礦添加的新區塊伴隨著貨幣發行,也是增加貨幣供應的一個過程。

挖礦採用工作量證明算法,平均每10分鐘解答出一個隨機的數學難題,獲勝者完成對這段時間交易的確認同時獲得比特幣獎勵和手續費。礦工造假的成本遠遠大於其遵守規則的成本,從而從其自身利益上保障了缺乏造假的動機(除非某個機構超過全網算力的51%,跑贏其他挖礦節點產生新區塊的速度,才能做到更改交易信息)。

所以說,挖礦是比特幣去中心化自發共識的根基:為了鼓勵礦工完成交易的結算打包,每次新區塊打包完成並被認可為主鏈後,會有比特幣獎勵;礦工若不按照規則構建新區塊,因為工作量算法需要大量的計算,耗費時間和電量,其造假的成本遠大於其遵守規則後的成本,所以形成了自發共識

什麼是算力?

算力是指每秒鐘計算的次數,在比特幣系統中,指挖礦時每秒鐘可以嘗試多少個隨機數去計算區塊頭哈希值。

第2節 比特幣貨幣創造

比特幣總量為2100萬個,每次生成新區塊時,會發行新的比特幣。比特幣系統前210000個區塊,每個區塊獎勵給礦工50個比特幣,每210000個區塊之後,區塊獎勵減半。即高度為210000——419999的區塊,每個區塊獎勵25個比特幣;高度為420000——629999的區塊,每個區塊獎勵12.5個比特幣,依次類推。由於每個區塊產生的平均時間大約10分鐘,所以產生210000個區塊的時間等於210000*10/(60*24*365)大約需要4年時間,即比特幣的發幣速率,平均每4年降低50%。

在經過693萬個區塊之後,所有的20999999.9769個比特幣將會全部發行完畢,到了2140年左右,礦工挖礦的收入將全部來自於交易中的手續費。

關於比特幣的總量為什麼是2100萬,網上有很多說法,其中“中本聰的天才:比特幣以意想不到的方式躲開了一些密碼學炸彈”這篇文章中的介紹,我比較認可,感興趣的朋友可以搜索瞭解下。

第3節 挖礦以及新區塊產生過程

通過完成工作量證明的校驗,挖礦節點將交易打包進新區塊,這一過程的詳細步驟如下:

《精通比特幣》第八章“挖礦與共識”解讀——區塊鏈基礎知識篇

挖礦以及新區塊產生過程

(提示:如果只需要瞭解大致流程,不關心實現原理的朋友,可直接翻到文末的總結了。)

第4節 交易的校驗

從“ ”中,我們知道,錢包客戶端通過收集UTXO、提供正確的解鎖腳本、構造支付給接收者的輸出這一系列的方式來創建交易。新創建的交易隨即會廣播到相鄰的節點,臨近的節點會對這筆交易進行校驗,當校驗通過後,才會繼續廣播到其他節點,否則該筆交易不會被繼續廣播。

每一個節點在校驗每一筆交易時,都會按照如下清單檢查:

交易的語法和數據結構必須正確;

輸入和輸出列表都不能為空;

交易的字節大小是小於區塊大小限制的;

每一個輸出值以及總量,都必須在(0——2100萬)之間;

沒有哈希等於0,N等於-1的輸入;

nlocktime—交易鎖定時間:即交易有效的最早時間,需小於等於int_Max最大值;

交易的字節大小是大於或等於100個字節的;

交易中的簽名數量應小於等於簽名操作數量上限;

解鎖腳本只能夠將數字壓入棧中,並且鎖定腳本必須要符合標準格式;

池中或位於主分支區塊中的一個匹配交易必須是存在的;

對於每一個輸入,如果引用的輸出存在於池中任何的交易,該交易將會被拒絕;

對於每一個輸入,在主分支和交易池中尋找引用的輸出交易,如果輸入交易缺少任何一個輸入,該交易將會成為一個孤立的交易;

對於每一個輸入,如果引用的輸出交易是一個coinbase交易,該輸入必須至少獲得100個確認;

對於每一個輸入,引用的輸出是必須存在的,並且沒有被花費;

使用引用的輸出交易獲得輸入值,並檢查每一個輸入值和總值是否在(0—2100萬之間);

輸入值的總和不能小於輸出值的總和

若交易費太低導致無法進入一個空的區塊,交易將會被中止;

每一個輸入的解鎖腳本都必須依據相應輸出的鎖定腳本來進行驗證。

以上校驗全部通過後,節點會將該交易加入到本地的交易池中,同時繼續向其他節點廣播該筆交易。

第5節 構造候選區塊的交易

每個挖礦節點都會監聽新區塊,一旦監聽到新區塊後,會停下手中的挖礦,優先校驗新區塊,當新區塊校驗通過後,節點會把本地交易池中包含於新區塊中的交易記錄刪除,同時立即構建一個空白區塊,作為候選區塊,開始競爭下一個區塊。

候選區塊中的交易包含從交易池中獲取的交易和coinbase(創幣)交易。

從交易池中獲取交易

節點會為交易池中的每一筆交易分配一個優先級,並選擇優先級高的交易記錄來構建候選區塊。交易的優先級是由交易輸入所花費的UTXO的“塊齡”所決定的,交易輸入值高、“塊齡”大的擁有較高優先級。

每筆交易的優先級計算公式為:

Priority=Sum(交易輸入值 * 塊齡)/交易總長度的字節數

其中交易輸入值是指交易中每個UTXO的輸出值,用單位“聰”表示;“塊齡”是指交易中每個UTXO所在的區塊與當前最新區塊之間的距離,即區塊的深度;交易長度的字節數,指該筆交易所佔的總空間大小。因為每筆交易可以有多個輸入,Sum求和是對每個輸入的交易輸入值與塊齡乘積之後再加和。

區塊中的前50個字節是保留給較高優先級交易的,不管它們是否包含了礦工費,較高優先級的交易會優先填充至這50個字節中;

然後,節點會按照“每千字礦工費”進行排序,優先選擇礦工費高的填充剩下的區塊空間(當前每個區塊空間的大小限制在1M內)。

如果區塊中仍有剩餘空間,節點可以選擇將沒有礦工費的交易填充,也可以選擇忽略餘下的交易,不添加到區塊中。

當區塊被填滿後,交易池中剩餘的交易會成為下一個區塊的候選交易,這些交易雖然當前沒有打包進塊,但隨著區塊的延長,這些交易所引用的UTXO所在塊的深度會增加,所以優先級也會隨之增加,最後一個零礦工費的交易也有可能滿足高優先級的條件被打包到後續的區塊中。

比特幣交易沒有過期、超時的概念。一筆交易存在於本地交易池中,一直未被確認的話,除非本地節點重新啟動,將本地交易池中的數據全部清空,否則交易會一直存在於交易池中,等待被新區塊打包確認。

創幣交易

創幣交易是每個區塊中的第1筆交易,用來將挖礦獎勵和區塊中所含交易的手續費之和支付給挖礦節點指定的比特幣地址。

節點先根據候選區塊所選交易中的所有輸入總和減去輸出總和的差,得到交易手續費;再計算挖礦獎勵,挖礦獎勵金額取決於所構建區塊的高度,詳見本章“第2節 比特幣貨幣創造”中的介紹。

由於創幣交易無需引用UTXO,所以其交易輸入與普通交易的交易輸入字段不一樣,創幣交易的交易輸入字段說明:

交易哈希:不引用任何一筆交易,值全部為0;

交易輸出索引:不引用任何一筆交易中的輸出,值全部為1

Coinbase數據長度:具體的字節數

Coinbase數據:在V2版本的區塊中,除了需要以區塊高度開始外,其他字節可以任意填充

通過上述的字段說明,可以發現,創幣交易的交易輸入沒有解鎖腳本,而是用Coinbase數據代替,用來標識創幣交易,同時coinbase數據中隨意填充的字節可以作為額外隨機數的來源,在工作量證明計算中可作為隨機數Nonce的來源。

第6節 構造區塊頭

為了構造區塊頭,挖礦節點需要填充如下6個字段:

版本:記錄版本號;

前區塊哈希值:當前候選區塊連接的前一個區塊的區塊哈希值;

Merkle根:當挖礦節點將創幣交易和從交易池中獲取的交易填充完成後,區塊頭根據本候選區塊包含的所有交易,計算交易哈希值後,逐層成對的組合,最後得到Merkle二叉樹的根節點——Merkle根,存儲在區塊頭中;

時間戳:記錄候選區塊的創建時間;

難度目標值:為使區塊有效,需滿足的工作量證明難度。難度目標值由程序預先定義的公式計算出來的,每2016個區塊後(即每兩週),難度目標值會自動調整一次,原因是隨著全網算力的變化,採用不同隨機數計算區塊頭哈希值的速度也會發生變化,這樣會導致每個區塊產生的時間發生變化。為了使大約每10分鐘產生一個新區塊,每兩週時,會根據期間的2016個區塊的平均產生時間來改變難度目標值,若其平均值大於10分鐘,則在隨後的2016個區塊中均降低難度,否則會增加難度。

隨機數Nonce

:初始值是0,挖礦的目標是找到一個使區塊頭哈希值小於難度目標值的隨機數。

第7節 挖礦

挖礦的目標是找到一個隨機數,使得對整個區塊頭進行哈希256函數計算後,得到的區塊頭哈希值小於難度目標值。這也是比特幣系統為達成共識所採用的工作量證明算法的核心。

工作量證明算法介紹

從“第6節 構造區塊頭”可知,區塊頭中包含了6個字段,對於同一個候選區塊,當交易填充完成後,Merkle根值不會變化,且版本、前區塊哈希值、時間戳、難度目標值也是固定的,不會發生變化,所以對整個區塊頭進行哈希函數映射時,為了使區塊頭哈希值不斷變化,只能通過不斷改變隨機數。

哈希256函數的輸入數據長度是任意的,將產生一個長度固定且絕不雷同的256字節的值。對於特定輸入,哈希的結果每次都一樣,任何實現相同哈希函數的人都可以計算和驗證。加密哈希函數的主要特徵是不同的輸入幾乎不可能出現相同的結果。因此相對於隨機的選擇輸入,若有意的選擇輸入去得到特定想要的哈希值幾乎不可能。所以,隨機數只能挨個去試。

例如,若難度目標是0000000000000002343534545,即至少前15位必須是0開頭,將區塊頭固定的前5個字段拼接隨機數後,通過哈希256函數計算得到的區塊頭哈希值為0000001111111111111111111,只有前6位是0,其大於難度目標,需要重新選擇新的隨機數(一般是當前隨機數加1),直至使得區塊頭哈希值小於難度目標值,挖礦節點可成功構建新區塊。

我們可以發現,難度目標值越小,找到隨機數的難度就越大。通過調整難度目標值的大小,可以調整新區塊的生成時間。

第8節 校驗新區塊

當一個節點挖礦成功後,會將新區塊廣播到相鄰的節點,每個相鄰的節點都會獨立的去校驗新區塊,只有校驗通過後,才會繼續廣播該區塊。需要對新區塊進行如下校驗:

區塊的數據結構語法上有效;

區塊頭的哈希值小於目標難度(確認包含足夠的工作量證明);

區塊時間戳早於驗證時刻未來兩個小時;

區塊大小在限制範圍之內;

第1個交易(且只能有1個)是coinbase交易;

使用檢查清單驗證區塊內的交易並驗證它們的有效性(詳見本章第4節“交易的校驗”);

每一個節點需獨立校驗新區塊,確保了礦工無法欺詐。為什麼礦工不為他們自己記錄一筆交易去獲得成千上萬的比特幣?這是因為每個節點都會根據相同的規則對區塊進行校驗,一個無效的交易將使整個區塊無效,這將導致區塊被其他節點拒絕,該筆偽造的交易自然不會成為總賬的一部分。所以,礦工必須構建完美的區塊,基於所有節點共享的規則,並且根據正確工作量證明的解決方案進行挖礦,這期間要花費大量的電力。如果他們作弊,所有的電力和努力都會白費,這就是為什麼獨立校驗是去中心化共識的重要組成部分。

第9節 區塊鏈的選擇與組裝

每個節點都會維護3種區塊:第1種是連接到主鏈上的;第2種是從主鏈上產生分支的備用鏈;第3種是沒有找到父區塊的孤立區塊。

主鏈

任何時候,主鏈都是累積了最多難度的區塊鏈,一般也是包含最多區塊的那個鏈,除非有兩個等長的鏈,其中一個有更多的工作量證明。

備用鏈

主鏈也會有一些分支,這些分支中的區塊並不是主鏈的一部分,保留這些區塊的目的是在未來的某個時刻某個備用鏈可能延長了並在難度上超過了主鏈,那麼這條備用鏈將會選為新的主鏈,同時後面的區塊也會在此基礎上繼續挖礦構建新區塊。

如果在同一個區塊的競爭中,同時有多個礦工都得到了正確的解並構建了新區塊時,其他節點可能會先後收到這些新區塊,於是會在主鏈的基礎上產生分支。

孤立區塊

當收到的一個新區塊沒有找到其父區塊時,節點會將它放在孤塊池中,直至接收到父區塊後,節點會將其從父區塊中取出來,並且將其連接起來,作為區塊鏈的一部分。

當兩個區塊在很短的時間內被挖出來,節點有可能會以完全相反的順序接收到它們,這個時候就會出現孤立塊。

綜上所述,挖礦節點在接收到新區塊並校驗通過後,會根據新區塊中記錄的前一個區塊,將新區塊組裝到前一個區塊所在的鏈中,若前一個區塊所在的鏈為主鏈,挖礦節點會繼續在此區塊的基礎上繼續開始挖下一個區塊;若前一個區塊所在的鏈為備用鏈,挖礦節點將新區塊組裝到備用鏈後,比較此時的主鏈和備用鏈哪個累積的難度最多,從而確定新的主鏈;若沒有找到前一個區塊所在的鏈,節點會將其放在孤立池中直至接收到其父區塊。

第10節 共識攻擊

比特幣共識機制依賴於這樣一個前提,那就是絕大多數的礦工,出於自己利益最大化的考慮,都會通過誠實的挖礦來維持整個比特幣系統。然而,當一個礦工擁有了全網大量算力之後,他們就有可能通過攻擊共識機制來破壞比特幣網絡的安全性和可靠性。

當一個挖礦節點的算力佔到全網的51%以上時,其發起的攻擊嘗試幾乎很有可能成功。共識攻擊主要包含2種:“雙重支付”和拒絕為某個特定比特幣地址的交易提供服務。

雙重支付

雙重支付,指同一筆款項支付了2次。比如,攻擊者A需要支付給B一定數額的比特幣,在這筆交易還未被6個區塊確認時,A再次手動在錢包客戶端利用這筆款項的UTXO發起支付,支付給了A自己,若攻擊者A擁有全網算力的51%,其有極大可能將第2筆交易加入到新區塊中,同時延長基於該區塊的鏈,使得B實際並未收到款項。

所以,雙重支付只能在攻擊者自己的錢包上進行,只有錢包的擁有者才能對同一UTXO進行簽名來完成支付。

在實際的大額交易場景中,最好是等到至少6個區塊確認後,再認可交易。

拒絕為特定比特幣地址提供服務

區塊中的交易是由挖礦節點在構建候選區塊中填充的,擁有全網算力超過51%的節點,構造交易時,故意不將某個比特幣地址的交易打包,同時快速的產生新區塊並延長基於此區塊的鏈,那麼這個比特幣地址的交易就會一直被忽略,無法完成交易。

隨著全網算力的不斷增大,以及挖礦節點的不斷增多,擁有51%算力的節點可能性很小。但如果算力掌握在幾個大的礦池手中,將會有共識攻擊的風險。

第11節 總結

本章主要介紹了比特幣系統去中心化達成共識的核心機制,即通過設立一個難題、各挖礦節點參與競爭解答、解答成功者獲得創建新區塊的資格、再由網絡中的其他節點獨立校驗並選擇新區塊,其中解答難題需要花費的成本使得礦工不會去惡意篡改交易、解答成功且被各節點接收後會對礦工發放獎勵,通過這一系列的工作量證明和比特幣獎勵,確保了比特幣系統至今運行9年也無需任何中心化機構參與。

本文首發於公號“Tina說”:從0到1建立區塊鏈認知,同時分享我的心路歷程。


分享到:


相關文章: