第四章 區塊鏈共識機制
1、概述
區塊鏈是基於去中心網絡實現的。
去中心網絡的意思就是:網絡中的任何一個節點都有着同等地位,大家都有着同樣的話語權。每個節點上都存儲着完整的賬本。
那問題來了,這些數據是如何添加到鏈上的,這麼多的節點,以哪個節點的記錄爲準呢?
共識機制就是解決這個問題的。共識機制是區塊鏈節點就區塊信息達成全網一致共識的機制,可以保證最新區塊準確添加到區塊鏈、節點存儲的區塊鏈信息一致不分叉、可以抵禦惡意攻擊。
下面將介紹區塊鏈採用的共識機制的詳細過程,並簡單介紹一下其他的共識機制。
2、工作量證明共識機制
區塊鏈採用的是工作量證明機制POW。簡單來說,就是所有節點去爭奪一個任務,哪個節點率先完成任務,則該節點獲得記賬權及系統獎勵。
下面看一下記賬的完整流程,假設A轉賬給B:
- A創建一條交易記錄:A->B,並把該筆記錄向區塊鏈網絡中的各個節點進行廣播。
- 區塊鏈中的各個節點收集網絡中尚未確定的交易記錄,進行驗證並記錄下來。
- 節點開始計算一個數學難題,不斷嘗試直到找到合理的隨機數。
- 節點創建候選區塊,先創建區塊頭信息,再把驗證通過的交易記錄納入到區塊體中。
- 率先完成數學難題的節點,把區塊廣播到網絡中。
- 其它節點接收到該區塊,並進行驗證。通過後在該區塊後面繼續添加區塊。通常在增加6個區塊後,該交易被永久留存。
- B收到A的轉賬。
各個節點被稱爲礦工,這個競爭記賬的過程被稱爲挖礦。
2.2 交易優先級
因爲每個區塊的大小是1M,包含的交易數大概是2500到3000筆左右,那如何確定哪些交易納入到候選區塊中呢,這就涉及到交易優先級的問題。
A節點需要爲內存池中的每筆交易分配一個優先級,並選擇較高優先級的交易記錄來構建候選區塊,Priority<0.576就要付費。
Priority = Sum (Value of input * Input Age) / Transaction Size
- value of input:是由比特幣單位“聰”(1億分之1個比特幣)來表示的。
- input age:是自該UTXO被記錄到區塊鏈爲止所經歷過的區塊數,即這個UTXO在區塊鏈中的深度。
- transaction size:交易記錄的大小由字節來表示。
區塊中用來存儲交易的前50K字節是保留給較高優先級交易的。節點在填充這50K字節的時候,會優先考慮這些最高優先級的交易,不管它們是否包含了礦工費。這種機制使得高優先級交易即便是零礦工費,也可以優先被處理。
然後,A挖礦節點會選出那些包含最小礦工費的交易,並按照“每千字節礦工費”進行排序,優先選擇礦工費高的交易來填充剩下的區塊。
如區塊中仍有剩餘空間,A挖礦節點可以選擇那些不含礦工費的交易。
在區塊被填滿後,內存池中的剩餘交易會成爲下一個區塊的候選交易。因爲這些交易還留在內存池中,所以隨着新的區塊被加到鏈上,這些交易輸入時所引用UTXO的深度(即交易“塊齡”)也會隨着變大。由於交易的優先值取決於它交易輸入的“塊齡”,所以這個交易的優先值也就隨之增長了。最後,一個零礦工費交易的優先值就有可能會滿足高優先級的門檻,被免費地打包進區塊。
由於未打包的交易存儲在內存中,如果礦工的內存釋放了,則未打包的交易就丟失了,爲了防止這種情況,發送交易的錢包,需要定期檢查交易是否被打包進區塊,如果沒有的話,則需要重新發送交易記錄,從而提醒節點不要把該筆交易忽略。
2.3 數學難題
生成一個區塊的時間大概是10分鐘,那問題來了,什麼問題能讓計算機計算10分鐘,並且隨着區塊鏈網絡中計算機的算力的變化生成的時間依然能保持在10分鐘左右?
2.3.1 數學難題
這個數學題,是要對整個區塊的數據求hash值:
而這個hash值需要滿足一定的限制條件:以n個0開頭。由於區塊數據是固定的,無論計算多少次hash值,結果都是一樣的,爲了滿足限制條件,引入了一個32位的隨機數,計算的過程就是不斷的調整隨機數,使最終的hash值滿足限制條件。如果嘗試了所有的32位隨機數都不能得到正確的hash值,那麼就要改變幣基(coinbase)的一個隨機數,接着進行反覆計算。
這個計算量非常大,比如在 2015 年年底,在大約 2 的 68 次方個隨機數中,只有一個可以成功,這個數字比全球總人口的平方還要大。(搞不懂爲什麼是2的68次方,只要知道非常難就行了)
2.3.2 動態調整難度
這段有點繞,捋了很長時間才捋明白。
隨着技術的發展及加入網絡的節點的變化,如何保證產生一個區塊的時間在10分鐘左右呢,區塊鏈採用了動態調整難度的方式。
假設第一批區塊創建時:最大目標值爲Target1,消耗的時間爲2016*10分鐘=20160分鐘,難度difficulty=1。
每挖出2016個區塊(大約爲2周,2016*10分鐘),會根據當前的難度值調整下一個階段的難度值。
-
假設最新2016個區塊耗時時間大於2016*10分鐘,則意味着之前的難度有點大了,需要降低難度。
-
假設最新2016個區塊耗時時間小於2016*10分鐘,則意味着之前的難度有點小了,需要增大難度。
也就是下一個階段的難度與當前消耗時間成反比,所以下階段難度爲:
下階段的目標值爲:
代入上面的公式變爲:
難度值、目標值在區塊中對應的字段爲:Difficulty、Bits。
但是bits不是顯式存儲的,而是經過了壓縮及規則處理後的結果,這裏不去細說了。
2.4 最長鏈原則
礦工進行挖礦的過程中,有可能兩個(比如A、B兩個礦工)及以上礦工同時完成挖礦,同時把結果公佈到區塊鏈網絡中。
網絡中的節點有的接收到了A礦工的區塊,有的接收到了B礦工的區塊,確認無誤後就開始在各自收到的區塊後面繼續挖礦,這就會產生分叉。
後續節點繼續進行挖礦,又會把新區塊發佈到全網中,比如是在A礦工區塊的後面新增的區塊。新區塊得到全網認可後,這個區塊所在的鏈就成了最長鏈,其它節點需要在這個鏈上繼續進行挖礦,這就是最長鏈原則。
最長鏈原則可以有效的避免分叉
2.5 作用
該共識機制在區塊鏈提現中有以下幾個作用:
- 交易:在共識機制下,競爭成功的節點完成了交易的記賬,其它節點進行了交易的驗證並保存了完整的賬本信息。
- 發行貨幣:競爭成功的節點,會獲得系統發放的獎勵。正是由於這個獎勵體系,在利益的驅使下,各個節點纔有動力去競爭記賬權,另外,這也是去中心網絡上發行貨幣的唯一方式。挖礦獎勵每4年遞減一次,依次爲50、25、12.5…,基於這個公式,比特幣挖礦獎勵以指數方式遞減,直到2140年。屆時所有的比特幣(20,999,999,980)全部發行完畢。到時候挖礦系統將不再有獎勵,完全靠交易手續費維持。
- 維持交易安全、不可逆:在該共識機制下,想對之前的數據進行篡改,必須重寫之後的所有數據,而重寫所有數據,就意味着破壞者的算力需要遠超誠實節點;另外,在該機制下,無法佔用別人的資金,因爲就算算力超越了所有誠實節點,誠實節點還有一個驗證的過程。
2.6 缺點
缺點有以下幾個:
- 容量問題:每個區塊大小爲1M,最多能放2000-3000條交易,不能應對大流量的場景。當交易數量過多時,會優先選擇金額較大、手續費較高的交易,小額的、手續費低的交易有可能永遠無法完成交易。這點完全背離了去中心化的初中。
- 性能:每10分鐘一個區塊,最多能放2000-3000條交易,則qps爲5,這在大型系統中肯定是無法接受的。
- 資源消耗問題:所有節點耗費大量的資源來計算一個數學難題,最終只錄取一個節點的結果,造成了大量的資源浪費。
- 算力集中問題凸顯:隨着挖礦難度增大,個體礦工已經無法挖到了,出現了大量的礦池(集合大量的礦工共同挖礦),這些礦池的算力集中,有的已經無限接近51%了,比如Ghash礦池。
3、其它共識機制
工作量證明機制只是衆多共識機制裏面的一種,下面介紹一下其它的共識機制。
3.1 權益證明
權益證明Pos,與工作量證明不同,工作量證明以算力競爭記賬權利,權益證明以持有資產競爭記賬權利。
這裏涉及到一個重要概念:幣天,1幣天就是持有1個幣1天,比如有30個幣,持有100天,則等於3000幣天。如果交易出去了,則幣天清0。
每個節點依據自己的幣天數量,會有不同的目標值(這與pow不同,pow中每個節點的目標值是相同的),幣天越大則目標值越大,則競爭成功的概率越大。
3.1.1 優點
相對於pow51%算力攻擊,pos的51%資產攻擊更加困難。而且資產比較大的節點本身就是系統的受益者,如果攻擊網絡,它自己的損失會很大。
3.1.2 缺點
缺點也很明顯,誰的資產多,誰就佔有優勢,會造成持有資產較多的節點有意識的持續持有資產,降低了資產的流動性,不利於網絡的發展。
第二個問題是,貨幣發行的問題。在網絡之初,是沒有任何貨幣的,此時如何進行貨幣的發行成爲了問題。
3.2 工作量證明+權益證明
採用工作量證明機制Pow發行貨幣,通過pos維護網絡安全。
該機制解決了純pos初期貨幣無法發行的問題。
3.3 股份授權證明
簡稱Dpos。
每個持幣節點將投票權授權給一名代表。由票數最多的100個節點作爲代表,按照既定的事件表輪流產生區塊。所有的代表會收到一個區塊交易費的1%作爲酬勞。這種方式可以大大提升網絡達成共識的效率。
3.4 瑞波證明
這個算法沒有搞明白,先介紹下原理,後面再學習吧。
首先,在瑞波網絡中,節點分成2大類:驗證節點、非驗證節點。只有驗證節點有記賬權限。
驗證節點又細分爲可信任節點及普通節點。普通驗證節點負責對交易進行驗證並接受可信任節點的提議。當可信任節點對交易認可比例達到要求後,交易纔可以入賬。每個普通驗證節點會保存一個可信任節點的列表。
下面看一下瑞波證明的過程:
- 驗證節點接收網絡中未確認的交易,存儲在本地,與本地賬本進行驗證,如果不通過,則直接丟棄。如果驗證通過,則打包進候選交易集,作爲提案發送給其它驗證節點。
- 驗證節點接收到其它驗證節點的提案,判斷是否在可信節點列表中,如果不在則直接丟棄。如果在可信任列表中,則對比提案與本地的候選交易集,發現匹配的交易則驗證次數加1。在一定時間內,當交易獲得的票數超過50%,則進入下一輪。
- 重複步驟2,每次提高交易獲得的票數的閾值,直到該閾值達到80%。
- 把達到80%票數的交易寫入到本地賬本中,交易關閉。
問題:沒有說明白多個驗證節點同時記賬,以哪個驗證節點的爲主呢??