共識算法

 [區塊鏈] 共識算法之爭(PBFT,Raft,PoW,PoS,DPoS,Ripple)

目錄

 

正文

  近幾天對區塊鏈中幾種常見的共識機制(PBFT,Raft,PoW,PoS,DPoS,Ripple)進行了總結。儘量使用簡單易懂語言,篇幅較大,想了解的可以只讀每個算法介紹中前邊的原理。本篇文章主要參考《區塊鏈技術指南》,首先表示感謝! 

  ---Begin---

  區塊鏈架構是一種分佈式的架構。其部署模式有公共鏈、聯盟鏈、私有鏈三種,對應的是去中心化分佈式系統、部分去中心化分佈式系統和弱中心分佈式系統。

  在分佈式系統中,多個主機通過異步通信方式組成網絡集羣。在這樣的一個異步系統中,需要主機之間進行狀態複製,以保證每個主機達成一致的狀態共識。然而,異步系統中,可能出現無法通信的故障主機,而主機的性能可能下降,網絡可能擁塞,這些可能導致錯誤信息在系統內傳播。因此需要在默認不可靠的異步網絡中定義容錯協議,以確保各主機達成安全可靠的狀態共識。

  所謂共識,簡單理解就是指大家都達成一致的意思。其實在現實生活中,有很多需要達成共識的場景,比如開會討論,雙方或多方簽訂一份合作協議等。而在區塊鏈系統中,每個節點必須要做的事情就是讓自己的賬本跟其他節點的賬本保持一致。如果是在傳統的軟件結構中,這幾乎就不是問題,因爲有一箇中心服務器存在,也就是所謂的主庫,其他的從庫向主庫看齊就行了。在實際生活中,很多事情人們也都是按照這種思路來的,比如企業老闆發佈一個通知,員工照着做。但是區塊鏈是一個分佈式的對等網絡結構,在這個結構中沒有哪個節點是“老大”,一切都要商量着來。

  所以在區塊鏈系統中,如何讓每個節點通過一個規則將各自的數據保持一致是一個很核心的問題,這個問題的解決方案就是制定一套共識算法,實現不同賬本節點上的賬本數據的一致性和正確性。這就需要借鑑已有的在分佈式系統中實現狀態共識的算法,確定網絡中選擇記賬節點的機制,以及如何保障賬本數據在全網中形成正確、一致的共識。

  共識算法其實就是一個規則,每個節點都按照這個規則去確認各自的數據。我們暫且拋開算法的原理,先來想一想在生活中我們會如何解決這樣一個問題:假設一羣人開會,這羣人中沒有一個領導或者說老大,大家各抒己見,那麼最後如何統一出一個決定出來呢?實際處理的時候,我們一般會在某一個時間段中選出一個人,那個人負責彙總大家的內容,然後發佈完整的意見,其他人投票表決,每個人都有機會來做彙總發表,最後誰的支持者多就以誰的最終意見爲準。這種思路其實就算是一種共識算法了。然而在實際過程中,如果人數不多並且數量是確定的,還好處理;如果人數很多且數量也不固定,那就很難通過這種方式投票決定了,效率太低。我們需要通過一種機制篩選出最有代表性的人,在共識算法中就是篩選出具有代表性的節點。

  那如何篩選呢?其實就是設置一組條件,就像篩選尖子生一樣,給一組指標讓大家來完成,誰能更好地完成指標,誰就能有機會被選上。在區塊鏈系統中,存在着多種這樣的篩選方案,比如PBFT(Practical Byzantine Fault Tolerance,實用拜占庭容錯算法)、PoW(Proof of Work,工作量證明)、PoS(Proof of Stake,權益證明)、DPoS(Delegate Proof of Stake,委託權益證明)、Ripple(瑞波)等,各種不同的算法,其實就是不同的遊戲玩法。

 

 

一.拜占庭容錯技術(Byzantine Fault Tolerance,BFT)

  拜占庭容錯技術(Byzantine Fault Tolerance,BFT)是一類分佈式計算領域的容錯技術。拜占庭假設是對現實世界的模型化,由於硬件錯誤、網絡擁塞或中斷以及遭到惡意攻擊等原因,計算機和網絡可能出現不可預料的行爲。拜占庭容錯技術被設計用來處理這些異常行爲,並滿足所要解決的問題的規範要求。

  拜占庭容錯技術來源於拜占庭將軍問題(猛擊!查看該問題)。

  在分佈式系統中,特別是在區塊鏈網絡環境中,也和拜占庭將軍的環境類似,有運行正常的服務器(類似忠誠的拜占庭將軍),有故障的服務器,還有破壞者的服務器(類似叛變的拜占庭將軍)。共識算法的核心是在正常的節點間形成對網絡狀態的共識。

  通常,這些發生故障節點被稱爲拜占庭節點,而正常的節點即爲非拜占庭節點

  拜占庭容錯系統是一個擁有n臺節點的系統,整個系統對於每一個請求,滿足以下條件:

  1)所有非拜占庭節點使用相同的輸入信息,產生同樣的結果;

  2)如果輸入的信息正確,那麼所有非拜占庭節點必須接收這個信息,並計算相應的結果。

  拜占庭系統普遍採用的假設條件包括:

  1)拜占庭節點的行爲可以是任意的,拜占庭節點之間可以共謀;

  2)節點之間的錯誤是不相關的;

  3)節點之間通過異步網絡連接,網絡中的消息可能丟失、亂序並延時到達,但大部分協議假設消息在有限的時間裏能傳達到目的地;

  4)服務器之間傳遞的信息,第三方可以嗅探到,但是不能篡改、僞造信息的內容和驗證信息的完整性。

  原始的拜占庭容錯系統由於需要展示其理論上的可行性而缺乏實用性。另外,還需要額外的時鐘同步機制支持算法的複雜度也是隨節點增加而指數級增加

二.PBFT:Practical Byzantine Fault Tolerance,實用拜占庭容錯算法。

  實用拜占庭容錯系統(PBFT)降低了拜占庭協議的運行複雜度,從指數級別降低到多項式級別(Polynomial),使拜占庭協議在分佈式系統中應用成爲可能。

  PBFT是一種狀態機副本複製算法,即服務作爲狀態機進行建模,狀態機在分佈式系統的不同節點進行副本複製。每個狀態機的副本都保存了服務的狀態,同時也實現了服務的操作。將所有的副本組成的集合使用大寫字母R表示,使用0到|R|-1的整數表示每一個副本。爲了描述方便,通常假設故障節點數爲m個,整個服務節點數爲|R|=3m+1個,這裏m是有可能失效的副本的最大個數。儘管可以存在多於3m+1個副本,但是額外的副本除了降低性能之外不能提高可靠性。

  PBFT要求共同維護一個狀態,所有節點採取的行動一致。爲此,需要運行三類基本協議,包括一致性協議、檢查點協議和視圖更換協議。我們主要關注支持系統日常運行的一致性協議。一致性協議至少包含若干個階段:請求(request)、序號分配(pre-prepare)和響應(reply)。根據協議設計的不同,可能包含相互交互(prepare),序號確認(commit)等階段。

PBFT協議通信模式

  上圖爲PBFT協議通信模式,每一個客戶端的請求需要經過5個階段,通過採用兩次兩兩交互的方式在服務器達成一致之後再執行客戶端的請求。由於客戶端不能從服務器端獲得任何服務器運行狀態的信息,PBFT中主節點是否發生錯誤只能由服務器監測。如果服務器在一段時間內都不能完成客戶端的請求,則會觸發視圖更換協議。其中C爲客戶端,N0~N3表示服務節點,特別的,N0爲主節點,N3爲故障節點。整個協議的基本過程如下:

1)客戶端發送請求,激活主節點的服務操作。

2)當主節點接收請求後,啓動三階段的協議以向各從節點廣播請求。

[2.1]序號分配階段,主節點給請求賦值一個序列號n,廣播序號分配消息和客戶端的請求消息m,並將構造PRE-PREPARE消息給各從節點;

[2.2]交互階段,從節點接收PRE-PREPARE消息,向其他服務節點廣播PREPARE消息;

[2.3]序號確認階段,各節點對視圖內的請求和次序進行驗證後,廣播COMMIT消息,執行收到的客戶端的請求並給客戶端以響應。

3)客戶端等待來自不同節點的響應,若有m+1個響應相同,則該響應即爲運算的結果。

 

  PBFT在很多場景都有應用,在區塊鏈場景中,一般適合於對強一致性有要求的私有鏈和聯盟鏈場景。例如,在IBM主導的區塊鏈超級賬本項目中,PBFT是一個可選的共識協議。在Hyperledger的Fabric項目中,共識模塊被設計成可插拔的模塊,支持像PBFT、Raft等共識算法。

三.Raft協議。

  在這些分佈式系統的實用場景下,其假設條件不需要考慮拜占庭故障,而只是處理一般的死機故障。在這種情況下,採用Paxos等協議會更加高效。Paxos是Lamport設計的保持分佈式系統一致性的協議。但由於Paxos非常複雜,比較難以理解,因此後來出現了各種不同的實現和變種。Raft是由Stanford提出的一種更易理解的一致性算法,意在取代目前廣爲使用的Paxos算法。目前,在各種主流語言中都有了一些開源實現,比如本文中將使用的基於JGroups的Raft協議實現。關於Raft的原理,強烈推薦動畫版Raft講解 (猛擊!查看該視頻)。

  Raft最初是一個用於管理複製日誌的共識算法,它是一個爲真實世界應用建立的協議,主要注重協議的落地性和可理解性。Raft是在非拜占庭故障下達成共識的強一致協議。

  在區塊鏈系統中,使用Raft實現記賬共識的過程可以描述如下:首先選舉一個leader,接着賦予leader完全的權力管理記賬。leader從客戶端接收記賬請求,完成記賬操作,生成區塊,並複製到其他記賬節點。有了leader簡化了記賬操作的管理。例如,leader能夠決定是否接受新的交易記錄項而無需考慮其他的記賬節點,leader可能失效或與其他節點失去聯繫,這時,系統就會選出新的leader。

  在Raft中,每個結點會處於下面三種狀態中的一種:

  • follower:所有結點都以follower的狀態開始。如果沒收到leader消息則會變成candidate狀態
  • candidate:會向其他結點“拉選票”,如果得到大部分的票則成爲leader。這個過程就叫做Leader選舉(Leader Election)
  • leader:所有對系統的修改都會先經過leader。每個修改都會寫一條日誌(log entry)。leader收到修改請求後的過程如下,這個過程叫做日誌複製(Log Replication): 
    • 複製日誌到所有follower結點(replicate entry)
    • 大部分結點響應時才提交日誌
    • 通知所有follower結點日誌已提交
    • 所有follower也提交日誌
    • 現在整個系統處於一致的狀態

Raft階段主要分爲兩個,首先是leader選舉過程,然後在選舉出來的leader基礎上進行正常操作,比如日誌複製、記賬等。

1.Leader Election 

  當follower在選舉超時時間內未收到leader的心跳消息,則轉換爲candidate狀態。爲了避免選舉衝突,這個超時時間是一個150~300ms之間的隨機數。

  一般而言,在Raft系統中:

  1)任何一個服務器都可以成爲一個候選者candidate,它向其他服務器follower發出要求選舉自己的請求。

  2)其他服務器同意了,發出OK。注意,如果在這個過程中,有一個follower宕機,沒有收到請求選舉的要求,此時候選者可以自己選自己,只要達到N/2+1的大多數票,候選人還是可以成爲leader的。

  3)這樣這個候選者就成爲了leader領導人,它可以向選民也就是follower發出指令,比如進行記賬。

  4)以後通過心跳進行記賬的通知。

  5)一旦這個leader崩潰了,那麼follower中有一個成爲候選者,併發出邀票選舉。

  6)follower同意後,其成爲leader,繼續承擔記賬等指導工作。

2.Log Replication

  Raft的記賬過程按以下步驟完成:

  1)假設leader領導人已經選出,這時客戶端發出增加一個日誌的要求;

  2)leader要求follower遵從他的指令,都將這個新的日誌內容追加到他們各自日誌中;

  3)大多數follower服務器將交易記錄寫入賬本後,確認追加成功,發出確認成功信息;

  4)在下一個心跳中,leader會通知所有follower更新確認的項目。

  對於每個新的交易記錄,重複上述過程。

  在這一過程中,若發生網絡通信故障,使得leader不能訪問大多數follower了,那麼leader只能正常更新它能訪問的那些follower服務器。而大多數的服務器follower因爲沒有了leader,他們將重新選舉一個候選者作爲leader,然後這個leader作爲代表與外界打交道,如果外界要求其添加新的交易記錄,這個新的leader就按上述步驟通知大多數follower。當網絡通信恢復,原先的leader就變成follower,在失聯階段,這個老leader的任何更新都不能算確認,必須全部回滾,接收新的leader的新的更新。

 

四.POW:Proof of Work,工作證明。

  從去中心化賬本系統的角度看,每個加入這個系統的節點都要保存一份完整的賬本,但每個節點卻不能同時記賬,因爲節點處於不同的環境,接收到不同的信息,如果同時記賬的話,必然會導致賬本的不一致,造成混亂。因此,需要有共識來達成哪個節點有權記賬。比特幣區塊鏈通過競爭記賬的方式解決去中心化的記賬系統的一致性問題, 即以每個節點的計算能力即“算力”來競爭記賬權的機制。 

  在比特幣系統中,大約每10分鐘進行一輪算力競賽,競賽的勝利者,就獲得一次記賬的權力,並向其他節點同步新增賬本信息。然而,在一個去中心化的系統中,誰有權判定競爭的結果呢?比特幣系統是通過一個稱爲“工作量證明”(Proof of Work,PoW)的機制完成的。

  簡單地說,PoW就是一份確認工作端做過一定量工作的證明。PoW系統的主要特徵是計算的不對稱性。工作端需要做一定難度的工作得出一個結果,驗證方卻很容易通過結果來檢查工作端是不是做了相應的工作。

  舉個例子,給定字符串“blockchain”,我們給出的工作量要求是,可以在這個字符串後面連接一個稱爲nonce的整數值串,對連接後的字符串進行SHA256哈希運算,如果得到的哈希結果(以十六進制的形式表示)是以若干個0開頭的,則驗證通過。爲了達到這個工作量證明的目標,我們需要不停地遞增nonce值,對得到的新字符串進行SHA256哈希運算。按照這個規則,需要經過2688次計算才能找到前3位均爲0的哈希值,而要找到前6位均爲0的哈希值,則需進行620969次計算。

1 blockchain1 → 4bfb943cba9fb9926df93f33c17d64b378d56714e8a29c6ba8bdc9690cea8e27  
2 blockchain2 → 01181212a283e760929f6b1628d903127c65e6fb5a9ad7fe94b790e699269221 ……
3 blockchain515 → 0074448bea8027bebd6333d3aa12fd11641e051911c5bab661a9b849b83958a7……
4 blockchain2688 → 0009b257eb8cf9eba179ab2be74d446fa1c59f0adfa8814260f52ae0016dd50f……
5 blockchain48851: 00000b3d96b4db1a976d3a69829aabef8bafa35ab5871e084211a16d3a4f385c……
6 blockchain6200969: 000000db7fa334aef754b51792cff6c880cd286c5f490d5cf73f658d9576d424

  通過上面這個計算特定SHA256運算結果的示例,我們對PoW機制有了一個初步的理解。對於特定字符串後接隨機nonce值所構成的串,要找到這樣的nonce值,滿足前n位均爲0的SHA256值,需要多次進行哈希值的計算。一般來說,n值越大,需要完成的哈希計算量也越大。由於哈希值的僞隨機特性,要尋找4個前導0的哈希值,預期大概要進行216次嘗試,這個數學期望的計算次數,就是所要求的“工作量”。

  比特幣網絡中任何一個節點,如果想生成一個新的區塊並寫入區塊鏈,必須解出比特幣網絡出的PoW問題。這道題關鍵的3個要素是工作量證明函數、區塊及難度值。工作量證明函數是這道題的計算方法,區塊決定了這道題的輸入數據,難度值決定了這道題所需要的計算量。

  1.工作量證明函數 及 區塊數據計算過程

  比特幣系統中使用的工作量證明函數就是SHA256(猛擊!查看該問題)。

  比特幣區塊結構如下圖所示:

  比特幣的區塊由區塊頭及該區塊所包含的交易列表組成。區塊頭的大小爲80字節,由4字節的版本號、32字節的上一個區塊的哈希值、32字節的Merkle根哈希值、4字節的時間戳(當前時間)、4字節的當前難度值、4字節的隨機數組成。區塊包含的交易列表則附加在區塊頭後面,其中的第一筆交易是coinbase交易,這是一筆爲了讓礦工獲得獎勵及手續費的特殊交易。

  擁有80字節固定長度的區塊頭,就是用於比特幣工作量證明的輸入字符串。因此,爲了使區塊頭能體現區塊所包含的所有交易,在區塊的構造過程中,需要將該區塊要包含的交易列表,通過Merkle樹算法(猛擊)生成Merkle根哈希值,並以此作爲交易列表的哈希值存到區塊頭中。其中Merkle樹的算法圖解如下圖所示。

  

  

  上圖展示了一個具有4個交易記錄的Merkle樹的根哈希值的計算過程。首先以這4個交易作爲葉子結點構造一棵完全二叉樹,然後通過哈希值的計算,將這棵二叉樹轉化爲Merkle樹。

首先對4個交易記錄:Txa~Txc,分別計算各自的哈希值HA~HC,然後計算兩個中間節點的哈希值HAB=Hash(HA+HB)和HCD=Hash(HC+HD),最後計算出根節點的哈希值HABCD=Hash(HAB+HCD)。

 

  而構造出來的簡化的區塊鏈結構如上圖所示。We find that: 所有在給定時間範圍需要記錄的交易信息被構造成一個Merkle樹,區塊中包含了指向這個Merkle樹的哈希指針,關聯了與該區塊相關的交易數據,同時,區塊中也包含了指向前一區塊的哈希指針,使得記錄了不同交易的單個區塊被關聯起來,形成區塊鏈。

  2.挖礦難度

  難度值是比特幣系統中的節點在生成區塊時的重要參考指標,它決定了節點大約需要經過多少次哈希運算才能產生一個合法的區塊。比特幣的區塊大約每10分鐘生成一個,如果要在不同的全網算力條件下,新區塊的產生都基本保持這個速率,難度值必須根據全網算力的變化進行調整。簡單地說,難度值被設定在無論節點計算能力如何,新區塊產生速率都保持在每10分鐘一個。

  難度的調整是在每個完整節點中獨立自動發生的。每2016個區塊,所有節點都會按統一的公式自動調整難度,這個公式是由最新2016個區塊的花費時長與期望時長(期望時長爲20160分鐘,即兩週,是按每10分鐘一個區塊的產生速率計算出的總時長)比較得出的,根據實際時長與期望時長的比值,進行相應調整(或變難或變易)。也就是說,如果區塊產生的速率比10分鐘快則增加難度,比10分鐘慢則降低難度。 

  這個公式可以總結爲:新難度值=舊難度值×(過去2016個區塊花費時長/20160分鐘)

  工作量證明需要有一個目標值。比特幣工作量證明的目標值(Target)的計算公式:目標值=最大目標值/難度值

  其中最大目標值爲一個恆定值:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

  目標值的大小與難度值成反比。比特幣工作量證明的達成就是礦工計算出來的區塊哈希值必須小於目標值。

  3.PoW過程 

  比特幣PoW的過程,可以簡單理解成就是將不同的nonce值作爲輸入,嘗試進行SHA256哈希運算,找出滿足給定數量前導0的哈希值的過程。而要求的前導0的個數越多,代表難度越大。比特幣節點求解工作量證明問題的步驟大致歸納如下:

  1)生成鑄幣交易,並與其他所有準備打包進區塊的交易組成交易列表,通過Merkle樹算法生成Merkle根哈希;

  2)把Merkle根哈希及其他相關字段組裝成區塊頭,將區塊頭的80字節數據作爲工作量證明的輸入;

  3)不停地變更區塊頭中的隨機數,即nonce的數值,並對每次變更後的區塊頭做雙重SHA256運算(即SHA256(SHA256(Block_Header))),將結果值與當前網絡的目標值做對比,如果小於目標值,則解題成功,工作量證明完成。

  比特幣的工作量證明,就是俗稱“挖礦”所做的主要工作。

  4.PoW能否解決拜占庭將軍問題 

  關於比特幣PoW共識機制能否解決拜占庭將軍問題一直在業界有爭議。2015年,Juan Garay對比特幣的PoW共識算法進行了正式的分析,得出的結論是比特幣的PoW共識算法是一種概率性的拜占庭協議(Probabilistic BA)。Garay對比特幣共識協議的兩個重要屬性分析如下。

  1)一致性(Agreement)

  在不誠實節點總算力小於50%的情況下,同時每輪同步區塊生成的機率很少的情況下,誠實的節點具有相同的區塊的概率很高。用數學的嚴格語言說應該是:當任意兩個誠實節點的本地鏈條截取K個節點,兩條剩下的鏈條的頭區塊不相同的概率隨着K的增加呈指數型遞減。

  2)正確性(Validity)

  大多數的區塊必須由誠實節點提供。嚴格來說,當不誠實算力非常小的時候,才能使大多數區塊由誠實節點提供。

  因此可以看到,當不誠實的算力小於網絡總算力的50%時,同時挖礦難度比較高,在大約10分鐘出一個區塊情況下,比特幣網絡達到一致性的概念會隨確認區塊的數目增多而呈指數型增加。但當不誠實算力具一定規模,甚至不用接近50%的時候,比特幣的共識算法並不能保證正確性,也就是,不能保證大多數的區塊由誠實節點來提供。

  因此,我們可以看到,比特幣的共識算法不適合於私有鏈和聯盟鏈。其原因首先是它是一個最終一致性共識算法,不是一個強一致性共識算法。第二個原因是其共識效率低。提供共識效率又會犧牲共識協議的安全性。另外,比特幣通過巧妙的礦工獎勵機制來提升網絡的安全性。礦工挖礦獲得比特幣獎勵以及記賬所得的交易費用使得礦工更希望維護網絡的正常運行,而任何破壞網絡的非誠信行爲都會損害礦工自身的利益。因此,即使有些比特幣礦池具備強大的算力,它們都沒有作惡的動機,反而有動力維護比特幣的正常運行,因爲這和它們的切實利益相關。

  PoW機制存在明顯的弊端。一方面,PoW的前提是,節點和算力是均勻分佈的,因爲通過CPU的計算能力來進行投票,擁有錢包(節點)數和算力值應該是大致匹配的,然而隨着人們將CPU挖礦逐漸升級到GPU、FPGA,直至ASIC礦機挖礦,節點數和算力值也漸漸失配。另一方面,PoW太浪費了。比特幣網絡每秒可完成數百萬億次SHA256計算,但這些計算除了使惡意攻擊者不能輕易地僞裝成幾百萬個節點和打垮比特幣網絡,並沒有更多實際或科學價值。當然,相對於允許世界上任何一個人在瞬間就能通過去中心化和半匿名的全球貨幣網絡,給其他人幾乎沒有手續費地轉賬所帶來的巨大好處,它的浪費也許只算是很小的代價。

  有鑑於此,人們提出了權益證明(Proof of Stake,PoS)。

 

五.POS:Proof of Stake,股權證明。

  PoS類似於財產儲存在銀行,這種模式會根據你持有數字貨幣的量和時間,分配給你相應的利息。 
  簡單來說,就是一個根據你持有貨幣的量和時間,給你發利息的一個制度,在股權證明PoS模式下,有一個名詞叫幣齡,每個幣每天產生1幣齡,比如你持有100個幣,總共持有了30天,那麼,此時你的幣齡就爲3000,這個時候,如果你發現了一個PoS區塊,你的幣齡就會被清空爲0。你每被清空365幣齡,你將會從區塊中獲得0.05個幣的利息(假定利息可理解爲年利率5%),那麼在這個案例中,利息 = 3000 * 5% / 365 = 0.41個幣,這下就很有意思了,持幣有利息。

  點點幣(Peercoin)是首先採用權益證明的貨幣,點點幣在SHA256的哈希運算的難度方面引入了幣齡的概念,使得難度與交易輸入的幣齡成反比。在點點幣中,幣齡被定義爲幣的數量與幣所擁有的天數的乘積,這使得幣齡能夠反映交易時刻用戶所擁有的貨幣數量。實際上,點點幣的權益證明機制結合了隨機化與幣齡的概念,未使用至少30天的幣可以參與競爭下一區塊,越久和越大的幣集有更大的可能去簽名下一區塊。

  然而,一旦幣的權益被用於簽名一個區塊,則幣齡將清爲零,這樣必須等待至少30日才能簽署另一區塊。同時,爲防止非常老或非常大的權益控制區塊鏈,尋找下一區塊的最大概率在90天后達到最大值,這一過程保護了網絡,並隨着時間逐漸生成新的幣而無需消耗大量的計算能力。點點幣的開發者聲稱這將使得惡意攻擊變得困難,因爲沒有中心化的挖礦池需求,而且購買半數以上的幣的開銷似乎超過獲得51%的工作量證明的哈希計算能力。

  權益證明必須採用某種方法定義任意區塊鏈中的下一合法區塊,依據賬戶結餘來選擇將導致中心化,例如單個首富成員可能會擁有長久的優勢。爲此,人們還設計了其他不同的方法來選擇下一合法區塊。

  PoS機制雖然考慮到了PoW的不足,但依據權益結餘來選擇,會導致首富賬戶的權力更大,有可能支配記賬權。股份授權證明機制(Delegated Proof of Stake,DPoS)的出現正是基於解決PoW機制和PoS機制的這類不足。

 

六.DPOS:Delegated Proof of Stake,委任權益證明

  比特股(Bitshare)是一類採用DPoS機制的密碼貨幣,它期望通過引入一個技術民主層來減少中心化的負面影響。

  比特股的DPoS機制,中文名叫做股份授權證明機制(又稱受託人機制),它的原理是讓每一個持有比特股的人進行投票,由此產生101位代表 , 我們可以將其理解爲101個超級節點或者礦池,而這101個超級節點彼此的權利是完全相等的。從某種角度來看,DPOS有點像是議會制度或人民代表大會制度。如果代表不能履行他們的職責(當輪到他們時,沒能生成區塊),他們會被除名,網絡會選出新的超級節點來取代他們。DPOS的出現最主要還是因爲礦機的產生,大量的算力在不瞭解也不關心比特幣的人身上,類似演唱會的黃牛,大量囤票而絲毫不關心演唱會的內容。

  比特股引入了見證人這個概念,見證人可以生成區塊,每一個持有比特股的人都可以投票選舉見證人。得到總同意票數中的前N個(N通常定義爲101)候選者可以當選爲見證人,當選見證人的個數(N)需滿足:至少一半的參與投票者相信N已經充分地去中心化。

  見證人的候選名單每個維護週期(1天)更新一次。見證人然後隨機排列,每個見證人按序有2秒的權限時間生成區塊,若見證人在給定的時間片不能生成區塊,區塊生成權限交給下一個時間片對應的見證人。DPoS的這種設計使得區塊的生成更爲快速,也更加節能。

  DPoS充分利用了持股人的投票,以公平民主的方式達成共識,他們投票選出的N個見證人,可以視爲N個礦池,而這N個礦池彼此的權利是完全相等的。持股人可以隨時通過投票更換這些見證人(礦池),只要他們提供的算力不穩定,計算機宕機,或者試圖利用手中的權力作惡。

  比特股還設計了另外一類競選,代表競選。選出的代表擁有提出改變網絡參數的特權,包括交易費用、區塊大小、見證人費用和區塊區間。若大多數代表同意所提出的改變,持股人有兩週的審查期,這期間可以罷免代表並廢止所提出的改變。這一設計確保代表技術上沒有直接修改參數的權利以及所有的網絡參數的改變最終需得到持股人的同意。

 

七.Ripple共識算法。

  Ripple(瑞波)是一種基於互聯網的開源支付協議,可以實現去中心化的貨幣兌換、支付與清算功能。在Ripple的網絡中,交易由客戶端(應用)發起,經過追蹤節點(tracking node)或驗證節點(validating node)把交易廣播到整個網絡中。追蹤節點的主要功能是分發交易信息以及響應客戶端的賬本請求。驗證節點除包含追蹤節點的所有功能外,還能夠通過共識協議,在賬本中增加新的賬本實例數據。  

  Ripple的共識達成發生在驗證節點之間,每個驗證節點都預先配置了一份可信任節點名單,稱爲UNL(Unique Node List)。在名單上的節點可對交易達成進行投票。每隔幾秒,Ripple網絡將進行如下共識過程:

  1)每個驗證節點會不斷收到從網絡發送過來的交易,通過與本地賬本數據驗證後,不合法的交易直接丟棄,合法的交易將彙總成交易候選集(candidate set)。交易候選集裏面還包括之前共識過程無法確認而遺留下來的交易。

  2)每個驗證節點把自己的交易候選集作爲提案發送給其他驗證節點。

  3)驗證節點在收到其他節點發來的提案後,如果不是來自UNL上的節點,則忽略該提案;如果是來自UNL上的節點,就會對比提案中的交易和本地的交易候選集,如果有相同的交易,該交易就獲得一票。在一定時間內,當交易獲得超過50%的票數時,則該交易進入下一輪。沒有超過50%的交易,將留待下一次共識過程去確認。  

  4)驗證節點把超過50%票數的交易作爲提案發給其他節點,同時提高所需票數的閾值到60%,重複步驟3)、步驟4),直到閾值達到80%。

  5)驗證節點把經過80%UNL節點確認的交易正式寫入本地的賬本數據中,稱爲最後關閉賬本(Last Closed Ledger),即賬本最後(最新)的狀態。

 

 Ripple共識過程節點交互示意圖

 

Ripple共識算法流程

 

  在Ripple的共識算法中,參與投票節點的身份是事先知道的,因此,算法的效率比PoW等匿名共識算法要高效,交易的確認時間只需幾秒鐘。當然,這點也決定了該共識算法只適合於權限鏈(Permissioned chain)的場景。Ripple共識算法的拜占庭容錯(BFT)能力爲(n-1)/5,即可以容忍整個網絡中20%的節點出現拜占庭錯誤而不影響正確的共識。

 


 

  以上主要是目前主流的共識算法。 但說起哪種共識機制更好或更具替代作用? 我認爲DPOS來單獨替代POW,POS或者POW+POS不太可能,畢竟存在即合理。每種算法都在特定的時間段、場景下具有各自的意義,無論是技術上,還是業務上。如果跳出技術者的角度,更多結合政治與經濟的思考方式在裏面,或許還會不斷出現更多的共識機制。

  對於算法的選擇,一句話總結如下:

 在區塊鏈網絡中,由於應用場景的不同,所設計的目標各異,不同的區塊鏈系統採用了不同的共識算法。一般來說,在私有鏈和聯盟鏈情況下,對一致性、正確性有很強的要求。一般來說要採用強一致性的共識算法。而在公有鏈情況下,對一致性和正確性通常沒法做到百分之百,通常採用最終一致性(Eventual Consistency)的共識算法。

  通俗點就是:共識算法的選擇與應用場景高度相關,可信環境使用paxos 或者raft,帶許可的聯盟可使用pbft ,非許可鏈可以是pow,pos,ripple共識等,根據對手方信任度分級,自由選擇共識機制。

REFERENCE

  1. Diego Ongaro and John Ousterhout Stanford University In Search of an Understandable Consensus Algorithm (Extended Version)
  2. 《區塊鏈技術指南》鄒均張海寧唐屹李磊 著
  3. Raft協議 https://blog.csdn.net/dc_726/article/details/48832405/
發佈了54 篇原創文章 · 獲贊 16 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章