区块链系列教程之:比特币中的共识
文章目錄
- 簡介
- 比特幣中的共識
- 交易的校驗
- 區(qū)塊的構建
- 區(qū)塊的校驗
- 區(qū)塊鏈的分叉
- 區(qū)塊鏈分叉的種類
- 總結
簡介
在比特幣的P2P網(wǎng)絡中是怎么達成共識的呢?達成共識需要做哪些交易的校驗呢?交易和區(qū)塊是怎么傳播到整個區(qū)塊鏈網(wǎng)絡的呢?看完這篇文章你就明白了。
比特幣中的共識
之前我在講分布式系統(tǒng)的時候有講過分布式系統(tǒng)的幾個共識算法,包括raft,Paxos和拜占庭容錯算法。
比特幣的共識和之前講的都不同,它使用的是工作量證明(POW)的算法。
比特幣的去中心化共識由所有網(wǎng)絡節(jié)點的4種獨立過程相互作用而產生:
? 每個全節(jié)點依據(jù)綜合標準對每個交易進行獨立驗證
? 通過完成工作量證明算法的驗算,挖礦節(jié)點將交易記錄獨立打包進新區(qū)塊
? 每個節(jié)點獨立的對新區(qū)塊進行校驗并組裝進區(qū)塊鏈
? 每個節(jié)點對區(qū)塊鏈進行獨立選擇,在工作量證明機制下選擇累計工作量最大的區(qū)塊鏈
交易的校驗
比特幣網(wǎng)絡中,交易是由網(wǎng)絡中的節(jié)點獨立校驗的。
在交易傳遞到臨近的節(jié)點前,每一個收到交易的比特幣節(jié)點將會首先驗證該交易,這將確保只有有效的交易才會在網(wǎng)絡中傳播,而無效的交易將會在第一個節(jié)點處被廢棄。
每一個節(jié)點在校驗每一筆交易時,都需要對照一個長長的標準列表:
?交易的語法和數(shù)據(jù)結構必須正確。
?輸入與輸出列表都不能為空。
?交易的字節(jié)大小是小于MAX_BLOCK_SIZE的。
?每一個輸出值,以及總量,必須在規(guī)定值的范圍內 (小于2,100萬個幣,大于0)。
?沒有哈希等于0,N等于-1的輸入(coinbase交易不應當被中繼)。
?nLockTime是小于或等于INT_MAX的。
?交易的字節(jié)大小是大于或等于100的。
?交易中的簽名數(shù)量應小于簽名操作數(shù)量上限。
?解鎖腳本(scriptSig)只能夠將數(shù)字壓入棧中,并且鎖定腳本(scriptPubkey)必須要符合isStandard的格式 (該格式將會拒絕非標準交易)。
?池中或位于主分支區(qū)塊中的一個匹配交易必須是存在的。
?對于每一個輸入,如果引用的輸出存在于池中任何的交易,該交易將被拒絕。
?對于每一個輸入,在主分支和交易池中尋找引用的輸出交易。如果輸出交易缺少任何一個輸入,該交易將成為一個孤立的交易。如果與其匹配的交易還沒有出現(xiàn)在池中,那么將被加入到孤立交易池中。
?對于每一個輸入,如果引用的輸出交易是一個coinbase輸出,該輸入必須至少獲得COINBASE_MATURITY (100)個確認。
?對于每一個輸入,引用的輸出是必須存在的,并且沒有被花費。
?使用引用的輸出交易獲得輸入值,并檢查每一個輸入值和總值是否在規(guī)定值的范圍內 (小于2100萬個幣,大于0)。
?如果輸入值的總和小于輸出值的總和,交易將被中止。
?如果交易費用太低以至于無法進入一個空的區(qū)塊,交易將被拒絕。
?每一個輸入的解鎖腳本必須依據(jù)相應輸出的鎖定腳本來驗證。
經過這么多長長的校驗之后,交易就準備被寫入?yún)^(qū)塊了。
區(qū)塊的構建
驗證交易后,比特幣節(jié)點會將這些交易添加到自己的內存池中。內存池也稱作交易池,用來暫存尚未被加入到區(qū)塊的交易記錄。與其他節(jié)點一樣,挖礦節(jié)點會收集、驗證并中繼新的交易。而與其他節(jié)點不同的是,挖礦節(jié)點會把這些交易整合到一個候選區(qū)塊中。
比特幣節(jié)點需要為內存池中的每筆交易分配一個優(yōu)先級,并選擇較高優(yōu)先級的交易記錄來構建候選區(qū)塊。交易的優(yōu)先級是由交易輸入所花費的 UTXO的“塊齡”決定,交易輸入值高、“塊齡”大的交易比那些新的、輸入值小的交易擁有更高的優(yōu)先級。如果區(qū)塊中有足夠的空間,高優(yōu)先級的交易行為將不需要礦工費。
然后,挖礦節(jié)點會選出那些包含最小礦工費的交易,并按照“每千字節(jié)礦工費”進行排序,優(yōu)先選擇礦工費高的交易來填充剩下的區(qū)塊,區(qū)塊大小上限為MAX_BLOCK_SIZE。
如區(qū)塊中仍有剩余空間,挖礦節(jié)點可以選擇那些不含礦工費的交易。有些礦工會竭盡全力將那些不含礦工費的交易整合到區(qū)塊中,而其他礦工也許會選擇忽略這些交易。
在區(qū)塊被填滿后,內存池中的剩余交易會成為下一個區(qū)塊的候選交易。因為這些交易還留在內存池中,所以隨著新的區(qū)塊被加到鏈上,這些交易輸入時所引用 UTXO的深度(即交易“塊齡”)也會隨著變大。由于交易的優(yōu)先值取決于它交易輸入的“塊齡”,所以這個交易的優(yōu)先值也就隨之增長了。最后,一個零礦工費 交易的優(yōu)先值就有可能會滿足高優(yōu)先級的門檻,被免費地打包進區(qū)塊。
區(qū)塊的校驗
在區(qū)塊中打包好了交易之后,會將該區(qū)塊廣播出去,而接收到區(qū)塊的節(jié)點就會進行區(qū)塊的校驗。
當一個節(jié)點接收到一個新的區(qū)塊,它將對照一個長長的標準清單對該區(qū)塊進行驗證,若沒有通過驗證,這個區(qū)塊將被拒絕。
這些標準可以在比特幣核心客戶端的CheckBlock函數(shù)和CheckBlockHead函數(shù)中獲得,它包括:
? 區(qū)塊的數(shù)據(jù)結構語法上有效
? 區(qū)塊頭的哈希值小于目標難度(確認包含足夠的工作量證明)
? 區(qū)塊時間戳早于驗證時刻未來兩個小時(允許時間錯誤)
? 區(qū)塊大小在長度限制之內
? 第一個交易(且只有第一個)是coinbase交易
? 使用檢查清單驗證區(qū)塊內的交易并確保它們的有效性
區(qū)塊鏈的分叉
因為區(qū)塊鏈是去中心化的數(shù)據(jù)結構,所以不同副本之間不能總是保持一致。區(qū)塊有可能在不同時間到達不同節(jié)點,導致節(jié)點有不同的區(qū)塊鏈視角。解決的辦法是,每一個節(jié)點總是選擇并嘗試延長代表累計了最大工作量證明的區(qū)塊鏈,也就是最長的或最大累計難度的鏈。
在第一張圖中,網(wǎng)絡有一個統(tǒng)一的區(qū)塊鏈視角,以藍色區(qū)塊為主鏈的“頂點”
當有兩個候選區(qū)塊同時想要延長最長區(qū)塊鏈時,分叉事件就會發(fā)生。正常情況下,分叉發(fā)生在兩名礦工在較短的時間內,各自都算得了工作量證明解的時候。
兩個礦工在各自的候選區(qū)塊一發(fā)現(xiàn)解,便立即傳播自己的“獲勝”區(qū)塊到網(wǎng)絡中,先是傳播給鄰近的節(jié)點而后傳播到整個網(wǎng)絡。
每個收到有效區(qū)塊的節(jié)點都會將其并入并延長區(qū)塊鏈。如果該節(jié)點在隨后又收到了另一個候選區(qū)塊,而這個區(qū)塊又擁有同樣父區(qū)塊,那么節(jié)點會將這個區(qū)塊連接到候選鏈上。
其結果是,一些節(jié)點收到了一個候選區(qū)塊,而另一些節(jié)點收到了另一個候選區(qū)塊,這時兩個不同版本的區(qū)塊鏈就出現(xiàn)了。
假如工作在“綠色”區(qū)塊上的礦工找到了一個“粉色”區(qū)塊延長了區(qū)塊鏈(藍色-綠色-粉色),他們會立刻傳播這個新區(qū)塊,整個網(wǎng)絡會都會認為這個區(qū)塊是有效的。
所有在上一輪選擇“綠色”區(qū)塊為勝出者的節(jié)點會直接將這條鏈延長一個區(qū)塊。
然而,那些選擇“紅色”區(qū)塊為勝出者的節(jié)點現(xiàn)在會看到兩個鏈:“藍色-綠色-粉色”和“藍色-紅色”。
如圖所示,這些節(jié)點會根據(jù)結果將“藍色-綠色-粉色”這條鏈設置為主鏈,將“藍色-紅色”這條鏈設置為備用鏈。這些節(jié)點接納了新的更長的鏈,被迫改變了原有對區(qū)塊鏈的觀點,這就叫做鏈的重新共識。
因為“紅”區(qū)塊做為父區(qū)塊已經不在最長鏈上,導致了他們的候選區(qū)塊已經成為了“孤塊”,所以現(xiàn)在任何原本想要在“藍色-紅色”鏈上延長區(qū)塊鏈的礦工都會停下來。
全網(wǎng)將“藍色-綠色-粉色”這條鏈識別為主鏈,“粉色”區(qū)塊為這條鏈的最后一個區(qū)塊。全部礦工立刻將他們產生的候選區(qū)塊的父區(qū)塊切換為“粉色”,來延長“藍色-綠色-粉色”這條鏈。
區(qū)塊鏈分叉的種類
通常來說區(qū)塊鏈的分叉可以分為兩種:
硬分叉,是當比特幣協(xié)議規(guī)則發(fā)生改變,舊節(jié)點拒絕接受由新節(jié)點創(chuàng)造的區(qū)塊的情況。違反規(guī)則的區(qū)塊將被忽視,礦工會按照他們的規(guī)則集,在他們最后見證的區(qū)塊之后創(chuàng)建區(qū)塊。
軟分叉,是當比特幣協(xié)議規(guī)則發(fā)生改變,舊的節(jié)點并不會意識到規(guī)則是不同的,它們將遵循改變后的規(guī)則集,繼續(xù)接受由新節(jié)點創(chuàng)造的區(qū)塊。礦工們可能會在他們完全沒有理解,或者驗證過的區(qū)塊上進行工作。
通過硬分叉,區(qū)塊鏈早已經不是原來的那個區(qū)塊鏈了。
從上圖可以看到,比特幣從最初的的版本已經發(fā)展了很多個分叉,他們的本質都是一樣的,問題就在于你到底認可哪條鏈。
總結
本文介紹了區(qū)塊鏈的共識機制,和交易的校驗步驟,最后講解了區(qū)塊鏈的分叉。希望大家能夠喜歡。
本文作者:flydean程序那些事
本文鏈接:http://www.flydean.com/bitcoin-consensus/
本文來源:flydean的博客
歡迎關注我的公眾號:程序那些事,更多精彩等著您!
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的区块链系列教程之:比特币中的共识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小师妹学JVM之:逃逸分析和TLAB
- 下一篇: 小师妹学JVM之:JIT中的PrintA