區塊鏈pow演算法模擬實現
1. 區塊鏈怎麼校驗
POA(ProofofActivity)區塊鏈共識演算法POA(ProofofActivity)演算法是一個區塊鏈的共識演算法,基本原理是結合POW(Proofofwork)和POS(Proofofstake)演算法的特點進行工作,POW演算法和POS演算法的具體內容可以參考:
POW演算法:
POS演算法:
POA演算法相比於其他演算法可以改進網路拓撲,維持在線節點比例,需求更少的交易費同時減少共識演算法過程中的能量損耗。
POA演算法需求的網路中同樣包含兩類節點,礦工和普通參與者,其中普通參與者不一定一直保持在線。POA演算法首先由礦工構造區塊頭,由塊頭選出N個幣,這N個幣的所有者參與後續的校驗和生成塊的過程。
從這里可以看到POA演算法不僅與算力有關,後續的N個參與者的選舉則完全由參與者在網路中所擁有的幣的總數量決定。擁有越多幣的參與者越有機會被選為N個後續的參與者。而後續N個參與者參與的必要條件是這N個參與者必須在線,這也是POA命名的由來,POA演算法的維護取決於網路中的活躍節點(Active)。
POA演算法的一個理想的基本流程是,類似於POW協議,礦工構造出一個符合難度要求的塊頭,通過礦工得到的塊頭計算衍生出N個幣的編號,從區塊鏈中追溯可以得到這幾個幣目前所述的參與者。礦工將這個塊頭發送給這N個參與者,其中前N-1個參與者對這個塊進行校驗和簽名,最後第N個參與者校驗並將交易加入到該塊中,將這個區塊發布出去,即完成一個區塊的出塊。
一個理想過程如下圖所示:
在實際運行中,無法保證網路上所有參與者都在線,而不在線的參與者則無法進行校驗和簽名,這個無法被校驗和簽名的塊頭則會被廢棄。
即在實際運行中,應該是一個礦工構造出塊頭後廣播給各個參與者簽名,同時繼續重新構造新的塊頭,以免上一個塊頭衍生的N個參與者存在有某一個沒有在線,而導致塊頭被廢棄。
因此,在這種情況下,一個塊是否被確認不僅與礦工的計算能力有關同時也與網路上的在線比例有關。
與純POW相比,在與比特幣(POW)同樣10分鍾出一個塊的情況下,POA由於會有參與者不在線而產生的損耗,因此,10分鍾內礦工可以構造的塊的數量會更多,即塊頭的難度限制會降低,那麼礦工在挖礦過程中會造成的能量損耗也會降低。
與純POS相比,可以看到POA的出塊流程並不會將構造區塊過程中的相關信息上鏈,可以明顯減少區塊鏈上用於維護協議產生的冗餘信息的量。
本節對上訴協議中一些參數設置進行分析
在礦工構造出塊頭後對塊頭進行校驗和區塊構造的N個參與者的數量選定比較類似於比特幣中每一個塊的出塊時間的選取。比特幣中選擇了10分鍾作為每一個塊的期望出塊時間並通過動態調節難度來適應。
這里N的取值同樣可以選擇選定值或者動態調節。動態調節需要更加復雜的協議內容,同時可能會帶來區塊鏈的數據膨脹,而復雜的協議也增加了攻擊者攻擊的可能性。另外暫時沒有辦法證明動態調節可以帶來什麼好處。靜態調節在後續的分析(4安全分析)中可以得到N=3的取值是比較合適的。
從上面的描述可以看到,構造新的區塊的除了礦工還有從塊頭中衍生出來的N個幣所有者。在構造出一個新的區塊後,這些參與者同樣應該收到一定的激勵,以維持參與者保持在線狀態。
礦工與參與者之間的非配比例與參與者的在線狀態相關。給予參與者的激勵與參與者保持在線狀態的熱情密切相關,越多參與者保持在線狀態,能更好地維持網路的穩定。因此,可以在網路上在線參與者不夠多的時候,提高參與者得到的激勵分成比例,從而激發更多的參與者上線。
如何確定當前參與者的在線情況呢?可以最後第N個參與者構造區塊時,將構造出來但是被廢棄的塊頭加入到區塊中,如果被丟棄的塊頭數量過多,說明在線人數過低,應當調節分成比例。
同時最後第N個參與者與其他參與者的分成同樣需要考慮,第N個參與者需要將交易加入區塊中,即需要維護UTXO池,同時第N個參與者還需要將被丟棄的塊頭加入新構建的區塊中。
為了激勵其將廢棄區塊頭加入新構建的區塊中,可以按照加入的區塊頭,適當增加一點小的激勵。雖然加入更多的區塊頭,可以在下一輪的時候增加分成的比例,應當足夠激勵參與者往區塊中加入未使用的塊頭了(這里參與者不可能為了增加分成而更多地加入區塊頭,每一個區塊頭都意味著一位礦工的工作量)。
一個參與者如果沒有維護UTXO池則無法構造區塊,但是可以參與前N-1個的簽名,因此為了激勵參與者維護UTXO池,作為最後一個構造區塊的參與者,必須給予更多的激勵,比如是其他參與者的兩倍。
從3.2的描述中可以知道一個用戶必須在線且維護UTXO池才可能盡可能地獲得利益。這種機制勢必會導致一些用戶將自己的賬戶託管給一個中心化的機構。這個機構一直保持在線,並為用戶維護其賬戶,在被選為構造區塊的參與者時參與區塊的構建並獲取利益。最後該機構將收益按照某種形式進行分成。
上面說到參與者必須用自己的密鑰進行簽名,而託管給某個機構後,這個機構在可以用這個密鑰簽名構造區塊的同時,也有可能使用這個密鑰消費用戶的財產。這里可以採用一種有限花銷的密鑰,這個密鑰有兩個功能,一個是將賬戶中的部分財產消費出去,另一個是將所有財產轉移到一個指定賬戶。在託管的時候可以使用這個密鑰,在被通知部分財產被花費後可以立即將所有財產轉移到自己的另一個賬戶下,以保證財產的安全。
從上面的分析可以看到,POA的安全性與攻擊者所擁有的算力和攻擊者所擁有的股權有關。假設攻擊者擁有的在線股權佔比為,則攻擊者的算力需要達到其他所有算力的倍才能達成分叉。假設攻擊者股權總佔比為,網路中誠實用戶的在線比例為,則攻擊者的算力需要達到其他所有算力的倍才能達成攻擊。
攻擊的分析表格如下:
從上文的分析可以看到,POA演算法相比於其他演算法可以改進網路拓撲,維持在線節點比例,需求更少的交易費同時減少共識演算法過程中的能量損耗。同時,PoA協議的攻擊成本要高於比特幣的純PoW協議。
參考文獻:ProofofActivity:ExtendingBitcoin』sProofofWorkviaProofofStake
利用區塊鏈技術實現不記密碼加密存儲驗證,解決離線安全存儲問題本文介紹一種利用區塊鏈技術配合個人存儲設備進行網路安全驗證的方法
以微嘟為代表的不記密碼快捷加密存儲設備,已經完美做到了快捷安全存儲,但美中不足的是無法通過網路查詢設備何時被使用,以及無法預知極端情況下設備被離線破解等。
利用區塊鏈技術可以解決此問題,具體工作原理:
在設備連接PC端,並檢測到射頻ID驗證通過後,接入設備內的特定硬體,此時自動通過安裝在PC端的程序向特定的區塊鏈網路上廣播設備打開時間的等信息。在得到區塊鏈網路確認後,才授權設備後級存儲用戶重要數據的存儲顆粒接入。因為每次設備打開都需要網路授權及相關的信息都存儲在區塊鏈網路上了,所以有效的避免了不明目的的人在用戶不知情的情況下偷偷地打開設備。
多了一層區塊鏈的網路驗證是不是發現設備的安全性提高了好多?
下面以微嘟鏈安全驗證為示意:
區塊鏈---共識演算法
PoW演算法是一種防止分布式服務資源被濫用、拒絕服務攻擊的機制。它要求節點進行適量消耗時間和資源的復雜運算,並且其運算結果能被其他節點快速驗算,以耗用時間、能源做擔保,以確保服務與資源被真正的需求所使用。
PoW演算法中最基本的技術原理是使用哈希演算法。假設求哈希值Hash(r),若原始數據為r(raw),則運算結果為R(Result)。
R=Hash(r)
哈希函數Hash()的特性是,對於任意輸入值r,得出結果R,並且無法從R反推回r。當輸入的原始數據r變動1比特時,其結果R值完全改變。在比特幣的PoW演算法中,引入演算法難度d和隨機值n,得到以下公式:
Rd=Hash(r+n)
該公式要求在填入隨機值n的情況下,計算結果Rd的前d位元組必須為0。由於哈希函數結果的未知性,每個礦工都要做大量運算之後,才能得出正確結果,而算出結果廣播給全網之後,其他節點只需要進行一次哈希運算即可校驗。PoW演算法就是採用這種方式讓計算消耗資源,而校驗僅需一次。
?
PoS演算法要求節點驗證者必須質押一定的資金才有挖礦打包資格,並且區域鏈系統在選定打包節點時使用隨機的方式,當節點質押的資金越多時,其被選定打包區塊的概率越大。
POS模式下,每個幣每天產生1幣齡,比如你持有100個幣,總共持有了30天,那麼,此時你的幣齡就為3000。這個時候,如果你驗證了一個POS區塊,你的幣齡就會被清空為0,同時從區塊中獲得相對應的數字貨幣利息。
節點通過PoS演算法出塊的過程如下:普通的節點要成為出塊節點,首先要進行資產的質押,當輪到自己出塊時,打包區塊,然後向全網廣播,其他驗證節點將會校驗區塊的合法性。
?
DPoS演算法和PoS演算法相似,也採用股份和權益質押。
但不同的是,DPoS演算法採用委託質押的方式,類似於用全民選舉代表的方式選出N個超級節點記賬出塊。
選民把自己的選票投給某個節點,如果某個節點當選記賬節點,那麼該記賬節點往往在獲取出塊獎勵後,可以採用任意方式來回報自己的選民。
這N個記賬節點將輪流出塊,並且節點之間相互監督,如果其作惡,那麼會被扣除質押金。
通過信任少量的誠信節點,可以去除區塊簽名過程中不必要的步驟,提高了交易的速度。
?
拜占庭問題:
拜占庭是古代東羅馬帝國的首都,為了防禦在每塊封地都駐扎一支由單個將軍帶領的軍隊,將軍之間只能靠信差傳遞消息。在戰爭時,所有將軍必須達成共識,決定是否共同開戰。
但是,在軍隊內可能有叛徒,這些人將影響將軍們達成共識。拜占庭將軍問題是指在已知有將軍是叛徒的情況下,剩餘的將軍如何達成一致決策的問題。
BFT:
BFT即拜占庭容錯,拜占庭容錯技術是一類分布式計算領域的容錯技術。拜占庭假設是對現實世界的模型化,由於硬體錯誤、網路擁塞或中斷以及遭到惡意攻擊等原因,計算機和網路可能出現不可預料的行為。拜占庭容錯技術被設計用來處理這些異常行為,並滿足所要解決的問題的規范要求。
拜占庭容錯系統:
發生故障的節點被稱為拜占庭節點,而正常的節點即為非拜占庭節點。
假設分布式系統擁有n台節點,並假設整個系統拜占庭節點不超過m台(n≥3m+1),拜占庭容錯系統需要滿足如下兩個條件:
另外,拜占庭容錯系統需要達成如下兩個指標:
PBFT即實用拜占庭容錯演算法,解決了原始拜占庭容錯演算法效率不高的問題,演算法的時間復雜度是O(n^2),使得在實際系統應用中可以解決拜占庭容錯問題
?
PBFT是一種狀態機副本復制演算法,所有的副本在一個視圖(view)輪換的過程中操作,主節點通過視圖編號以及節點數集合來確定,即:主節點p=vmod|R|。v:視圖編號,|R|節點個數,p:主節點編號。
PBFT演算法的共識過程如下:客戶端(Client)發起消息請求(request),並廣播轉發至每一個副本節點(Replica),由其中一個主節點(Leader)發起提案消息pre-prepare,並廣播。其他節點獲取原始消息,在校驗完成後發送prepare消息。每個節點收到2f+1個prepare消息,即認為已經准備完畢,並發送commit消息。當節點收到2f+1個commit消息,客戶端收到f+1個相同的reply消息時,說明客戶端發起的請求已經達成全網共識。
具體流程如下:
客戶端c向主節點p發送REQUEST,o,t,c請求。o:請求的具體操作,t:請求時客戶端追加的時間戳,c:客戶端標識。REQUEST:包含消息內容m,以及消息摘要d(m)。客戶端對請求進行簽名。
主節點收到客戶端的請求,需要進行以下交驗:
a.客戶端請求消息簽名是否正確。
非法請求丟棄。正確請求,分配一個編號n,編號n主要用於對客戶端的請求進行排序。然後廣播一條PRE-PREPARE,v,n,d,m消息給其他副本節點。v:視圖編號,d客戶端消息摘要,m消息內容。PRE-PREPARE,v,n,d進行主節點簽名。n是要在某一個范圍區間內的[h,H],具體原因參見垃圾回收章節。
副本節點i收到主節點的PRE-PREPARE消息,需要進行以下交驗:
a.主節點PRE-PREPARE消息簽名是否正確。
b.當前副本節點是否已經收到了一條在同一v下並且編號也是n,但是簽名不同的PRE-PREPARE信息。
c.d與m的摘要是否一致。
d.n是否在區間[h,H]內。
非法請求丟棄。正確請求,副本節點i向其他節點包括主節點發送一條PREPARE,v,n,d,i消息,v,n,d,m與上述PRE-PREPARE消息內容相同,i是當前副本節點編號。PREPARE,v,n,d,i進行副本節點i的簽名。記錄PRE-PREPARE和PREPARE消息到log中,用於ViewChange過程中恢復未完成的請求操作。
主節點和副本節點收到PREPARE消息,需要進行以下交驗:
a.副本節點PREPARE消息簽名是否正確。
b.當前副本節點是否已經收到了同一視圖v下的n。
c.n是否在區間[h,H]內。
d.d是否和當前已收到PRE-PPREPARE中的d相同
非法請求丟棄。如果副本節點i收到了2f+1個驗證通過的PREPARE消息,則向其他節點包括主節點發送一條COMMIT,v,n,d,i消息,v,n,d,i與上述PREPARE消息內容相同。COMMIT,v,n,d,i進行副本節點i的簽名。記錄COMMIT消息到日誌中,用於ViewChange過程中恢復未完成的請求操作。記錄其他副本節點發送的PREPARE消息到log中。
主節點和副本節點收到COMMIT消息,需要進行以下交驗:
a.副本節點COMMIT消息簽名是否正確。
b.當前副本節點是否已經收到了同一視圖v下的n。
c.d與m的摘要是否一致。
d.n是否在區間[h,H]內。
非法請求丟棄。如果副本節點i收到了2f+1個驗證通過的COMMIT消息,說明當前網路中的大部分節點已經達成共識,運行客戶端的請求操作o,並返回REPLY,v,t,c,i,r給客戶端,r:是請求操作結果,客戶端如果收到f+1個相同的REPLY消息,說明客戶端發起的請求已經達成全網共識,否則客戶端需要判斷是否重新發送請求給主節點。記錄其他副本節點發送的COMMIT消息到log中。
?
如果主節點作惡,它可能會給不同的請求編上相同的序號,或者不去分配序號,或者讓相鄰的序號不連續。備份節點應當有職責來主動檢查這些序號的合法性。
如果主節點掉線或者作惡不廣播客戶端的請求,客戶端設置超時機制,超時的話,向所有副本節點廣播請求消息。副本節點檢測出主節點作惡或者下線,發起ViewChange協議。
ViewChange協議:
副本節點向其他節點廣播VIEW-CHANGE,v+1,n,C,P,i消息。n是最新的stablecheckpoint的編號,C是2f+1驗證過的CheckPoint消息集合,P是當前副本節點未完成的請求的PRE-PREPARE和PREPARE消息集合。
當主節點p=v+1mod|R|收到2f個有效的VIEW-CHANGE消息後,向其他節點廣播NEW-VIEW,v+1,V,O消息。V是有效的VIEW-CHANGE消息集合。O是主節點重新發起的未經完成的PRE-PREPARE消息集合。PRE-PREPARE消息集合的選取規則:
副本節點收到主節點的NEW-VIEW消息,驗證有效性,有效的話,進入v+1狀態,並且開始O中的PRE-PREPARE消息處理流程。
?
在上述演算法流程中,為了確保在ViewChange的過程中,能夠恢復先前的請求,每一個副本節點都記錄一些消息到本地的log中,當執行請求後副本節點需要把之前該請求的記錄消息清除掉。
最簡單的做法是在Reply消息後,再執行一次當前狀態的共識同步,這樣做的成本比較高,因此可以在執行完多條請求K(例如:100條)後執行一次狀態同步。這個狀態同步消息就是CheckPoint消息。
副本節點i發送CheckPoint,n,d,i給其他節點,n是當前節點所保留的最後一個視圖請求編號,d是對當前狀態的一個摘要,該CheckPoint消息記錄到log中。如果副本節點i收到了2f+1個驗證過的CheckPoint消息,則清除先前日誌中的消息,並以n作為當前一個stablecheckpoint。
這是理想情況,實際上當副本節點i向其他節點發出CheckPoint消息後,其他節點還沒有完成K條請求,所以不會立即對i的請求作出響應,它還會按照自己的節奏,向前行進,但此時發出的CheckPoint並未形成stable。
為了防止i的處理請求過快,設置一個上文提到的高低水位區間[h,H]來解決這個問題。低水位h等於上一個stablecheckpoint的編號,高水位H=h+L,其中L是我們指定的數值,等於checkpoint周期處理請求數K的整數倍,可以設置為L=2K。當副本節點i處理請求超過高水位H時,此時就會停止腳步,等待stablecheckpoint發生變化,再繼續前進。
?
在區塊鏈場景中,一般適合於對強一致性有要求的私有鏈和聯盟鏈場景。例如,在IBM主導的區塊鏈超級賬本項目中,PBFT是一個可選的共識協議。在Hyperledger的Fabric項目中,共識模塊被設計成可插拔的模塊,支持像PBFT、Raft等共識演算法。
?
?
Raft基於領導者驅動的共識模型,其中將選舉一位傑出的領導者(Leader),而該Leader將完全負責管理集群,Leader負責管理Raft集群的所有節點之間的復制日誌。
?
下圖中,將在啟動過程中選擇集群的Leader(S1),並為來自客戶端的所有命令/請求提供服務。Raft集群中的所有節點都維護一個分布式日誌(復制日誌)以存儲和提交由客戶端發出的命令(日誌條目)。Leader接受來自客戶端的日誌條目,並在Raft集群中的所有關注者(S2,S3,S4,S5)之間復制它們。
在Raft集群中,需要滿足最少數量的節點才能提供預期的級別共識保證,這也稱為法定人數。在Raft集群中執行操作所需的最少投票數為(N/2+1),其中N是組中成員總數,即投票至少超過一半,這也就是為什麼集群節點通常為奇數的原因。因此,在上面的示例中,我們至少需要3個節點才能具有共識保證。
如果法定仲裁節點由於任何原因不可用,也就是投票沒有超過半數,則此次協商沒有達成一致,並且無法提交新日誌。
?
數據存儲:Tidb/TiKV
日誌:阿里巴巴的DLedger
服務發現:Consuletcd
集群調度:HashiCorpNomad
?
只能容納故障節點(CFT),不容納作惡節點
順序投票,只能串列apply,因此高並發場景下性能差
?
Raft通過解決圍繞Leader選舉的三個主要子問題,管理分布式日誌和演算法的安全性功能來解決分布式共識問題。
當我們啟動一個新的Raft集群或某個領導者不可用時,將通過集群中所有成員節點之間協商來選舉一個新的領導者。因此,在給定的實例中,Raft集群的節點可以處於以下任何狀態:追隨者(Follower),候選人(Candidate)或領導者(Leader)。
系統剛開始啟動的時候,所有節點都是follower,在一段時間內如果它們沒有收到Leader的心跳信號,follower就會轉化為Candidate;
如果某個Candidate節點收到大多數節點的票,則這個Candidate就可以轉化為Leader,其餘的Candidate節點都會回到Follower狀態;
一旦一個Leader發現系統中存在一個Leader節點比自己擁有更高的任期(Term),它就會轉換為Follower。
Raft使用基於心跳的RPC機制來檢測何時開始新的選舉。在正常期間,Leader會定期向所有可用的Follower發送心跳消息(實際中可能把日誌和心跳一起發過去)。因此,其他節點以Follower狀態啟動,只要它從當前Leader那裡收到周期性的心跳,就一直保持在Follower狀態。
當Follower達到其超時時間時,它將通過以下方式啟動選舉程序:
根據Candidate從集群中其他節點收到的響應,可以得出選舉的三個結果。
共識演算法的實現一般是基於復制狀態機(Replicatedstatemachines),何為復制狀態機:
簡單來說:相同的初識狀態+相同的輸入=相同的結束狀態。不同節點要以相同且確定性的函數來處理輸入,而不要引入一下不確定的值,比如本地時間等。使用replicatedlog是一個很不錯的注意,log具有持久化、保序的特點,是大多數分布式系統的基石。
有了Leader之後,客戶端所有並發的請求可以在Leader這邊形成一個有序的日誌(狀態)序列,以此來表示這些請求的先後處理順序。Leader然後將自己的日誌序列發送Follower,保持整個系統的全局一致性。注意並不是強一致性,而是最終一致性。
日誌由有序編號(logindex)的日誌條目組成。每個日誌條目包含它被創建時的任期號(term),和日誌中包含的數據組成,日誌包含的數據可以為任何類型,從簡單類型到區塊鏈的區塊。每個日誌條目可以用[term,index,data]序列對表示,其中term表示任期,index表示索引號,data表示日誌數據。
Leader嘗試在集群中的大多數節點上執行復制命令。如果復製成功,則將命令提交給集群,並將響應發送回客戶端。類似兩階段提交(2PC),不過與2PC的區別在於,leader只需要超過一半節點同意(處於工作狀態)即可。
leader、follower都可能crash,那麼follower維護的日誌與leader相比可能出現以下情況
當出現了leader與follower不一致的情況,leader強制follower復制自己的log,Leader會從後往前試,每次AppendEntries失敗後嘗試前一個日誌條目(遞減nextIndex值),直到成功找到每個Follower的日誌一致位置點(基於上述的兩條保證),然後向後逐條覆蓋Followers在該位置之後的條目。所以丟失的或者多出來的條目可能會持續多個任期。
?
要求候選人的日誌至少與其他節點一樣最新。如果不是,則跟隨者節點將不投票給候選者。
意味著每個提交的條目都必須存在於這些伺服器中的至
2. 最易於小白讀透的POW和POS概念詳解(內含波卡)
POW(工作量證明)與POS(權益證明)是兩種不同的區塊鏈共識機制,它們各有優劣。POW機制通過計算強度來驗證交易,如比特幣的挖礦,誰的計算能力更強,獲得新區塊的可能性越大,但這也導致了能源消耗和算力集中。而POS機制,如EOS的DPoS和波卡的NPOS,持有代幣者通過質押來參與驗證,持有越多,獲得獎勵的機會越多,較為節能,但安全性主要依賴於代幣分散度。在EOS中,21個節點通過質押競爭網路獎勵,而在波卡中,通過隨機性分散節點來提高公平性。
在性能方面,POS通常具有更高的吞吐量和較低的創建區塊成本,因為不依賴於現實能耗。然而,POS的共識需要大多數驗證者達成一致,可能導致網路狀態確認困難。波卡採用分片技術,降低對每個節點的要求,提高了網路的靈活性和安全性。
POW與POS在資源利用上也有所不同。POW挖礦消耗大量電力和硬體資源,而POS幾乎不消耗除網路帶寬以外的資源。POW形成了一套產業鏈,但其挖礦過程的實際效用有限,而POS則相對環保。
在去中心化方面,POW有天然的抗集中風險,但可能導致算力集中,而傳統POS易出現大戶控制。波卡的NPOS通過隨機性降低了集中化的風險,但提高安全性需要結合其他演算法。
總的來說,POW和POS各有優缺點,選擇哪種機製取決於具體應用場景和安全需求。POW以公平性和可靠性見長,而POS強調效率和資源節約,但安全性需要額外的措施來保障。兩者的發展都體現了區塊鏈技術的不斷優化和進步。
3. 區塊鏈中PoW是指什麼
是指工作量證明機制,是區塊鏈的一種共識機制。指在區塊鏈系統中,根據每個節點在運算的過程中所做出的貢獻來確定許可權的一種演算法。工作量證明機制是現在區塊鏈應用最為廣泛的一種共識機制。共識機制是區塊鏈系統中很重要的一部分,如果出現問題,那麼整個系統都會出問題,在區塊鏈開發中是必須要注意的。這是之前我一個在煊凌科技上班的人告訴我的,他雖然只是裡面的銷售,但是對區塊鏈的了解也比大部分人要全面。
4. 區塊鏈pow解決了什麼(區塊鏈pocc合法嗎)
兩種共識機制對比(PoWvsPoS)區塊鏈中最核心的架構就是共識機制,可以說是區塊鏈的驅動引擎,發展這么多年,目前主流比較明確經得住考驗的就只剩下PoW(ProofofWork)與PoS(ProofofStake)兩種機制。簡單概述下,PoW系統的特點是通過消耗大量算力來計算特定演算法的解(典型如哈希),第一個算出結果的有權生成區塊,同時也會得到coin作為獎勵(這也是coin的生產與分發過程,形象地稱為Mining),採用PoW的典型區塊鏈有Bitcoin和Ethereum,目前PoW也是運行時間最長,被公認為是最可靠安全的共識機制;其本質是通過消耗大量算力來實現系統內的逆熵過程,保證系統的長期安全與穩定。但PoW被廣為詬病的也是其消耗太多的能源資源,這方面PoS就被認為是更為綠色的解決方案,顧名思義PoS是通過質押系統中的資產即coin來成為一個質押者(staker),這樣就有權產出區塊,質押份額越多,獲得產出區塊權的概率就越高,也代表著獎勵越多。
在分布式系統中有一個CAP定理,是指一個分布式系統中存在著三元悖論,即不可能同時滿足這三個特性:一致性(Consistency)、可用性(Availability)和分區容錯性(Partitiontolerance),而只能滿足其中兩個。區塊鏈作為一種分布式網路,這個定理也逐漸演變成了區塊鏈的三元悖論,即安全性(Security)、去中心化(Decentralization)和可擴展性(Scalability),也是同時只能滿足兩個特性。
整體上看PoW系統更注重的是安全性(Security)與去中心化(Decentralization),放棄可擴展性(Scalability),這也是Bitcoin網路的吞吐量非常慢的原因。而PoS系統更關注的是可擴展性(Scalability)與去中心化(Decentralization),但就PoS能否真的實現去中心化(Decentralization),我是比較持懷疑態度的。從保守主義與系統的更長期穩定的角度出發,我個人是堅定地站在PoW這邊的,可能跟自身保守的性格有關,並不是特別看好PoS作為基礎層能比較穩定。特別是像這次5月份的Luna事件,事件大概的過程是Luna鏈上的演算法穩定幣UST缺乏價值支撐最終脫錨,其核心問題在於UST的錨定設計試圖用一個PoS股權系統去支撐其錨定美元,而且還超發了太多UST,再加上UST與Luna的兌換設計缺陷最終導致Luna自身的死亡螺旋。但這個事件更大的意義應該是敲響了一個警鍾,PoS機制在面對空頭資本砸盤時真的還能維持穩定、維持所謂的去中心化嗎?可能到時節點數量萎縮的速度會很快,逐漸趨於中心化。
所有系統設計都需要根據自身定位來折中,以下從價值錨定的角度,簡單分析下為什麼長期來看PoW會更有優勢。
在PoW系統中三股主要的參與者分別是研發人員,投資者(或者叫用戶)與Miner,這三者的相互制衡,使得這個系統達到一個穩定平衡的狀態。而PoS系統中,將Miner這個重要的制衡力量移除了,投資者和Miner變成了同一群體質押者(stakers),因此該群體濫用權力的行為會變得相對不受限制,並且該鏈隨後的發展方向也可能會更加不平衡,更容易傾向有利於質押者(stakers)群體的方向。
PoW系統很好的闡述了什麼是被普遍認可的價值,抽象上來看就是高代價的稀缺性,高代價與稀缺性兩者缺一不可。PoS最多隻能實現其中一個稀缺性。
Miner為了在鏈上生產區塊賺取coin,不僅需要持續支付高額電力成本,還必須不斷投入研發、升級硬體、優化基礎設施和運營規模來保持其競爭力。最終結果是,能夠長期持續盈利的Miner並不會是一個一層不變的群體,而是總在競爭中淘汰掉效率太低的Miner,使高效率的Miner能存活下來。這也更有利於去中心化(Decentralization),因為不斷變化的Miner群體意味著沒有一個Miner可以在相當長的時間內保持網路的大部分算力,除非他們通過嚴酷的競爭考驗,不斷優化自身來提供更多的算力。
而PoS系統中的質押者實際上並多少真正的風險投入,也沒有優勝劣汰的嚴酷競爭機制,他們只需要簡單地運行一個staker節點就可以躺著賺利息,本質上只是將自己在銀行系統里的錢簡單的轉化為鏈上資本,就可以坐地收割後進入這個系統的新人。這種行為並沒有太多難度,只是簡單地賺取「無風險」利息,他們並沒有將資本轉化為任何形式的需要面臨風險考驗的投資。
而且當發生硬分叉時,PoW的Miner選擇支持哪條鏈時會更為謹慎,因為他們需要投入高昂的電力成本來為他們的選擇背書,一旦選錯了將損失所有投入成本。PoS系統如果發生硬分叉,質押的coin作為系統內部狀態的一部分,硬分叉後質押者將在兩條不同鏈上都擁有相同數量的資產,由於沒有什麼沉默成本,導致質押者更願意兩邊都支持,從而使硬分叉更容易且更頻繁地出現,這被稱為nothingatstake問題。
PoW是真正能做到無准入限制的(Permissionless),就是說已經在這個系統中的老人無法限制新人加入,只要你有能力提供算力,就能直接接入網路中產出coin。而PoS系統中,新人要進入,都不得不先從老人手中買coin。
而且PoW中Miner為了支付各種高昂成本(電力,設備,基礎設施等),產出coin後也不得不賣出一些以彌補成本,這同時也是一種把coin分發給更多人的過程;特別是在熊市,Miner為了維持開銷也不得不低價賤賣coin,這樣新人才有機會以相對低的成本獲得籌碼入場,這才是一個健康的生態擴張過程。而PoS中由於質押者並沒有什麼運行成本,也不需要面對太多競爭,質押者出塊得到coin後不需要急著賣出,更容易哄抬價格,其實會變相激勵場內老人剝削新入場者,不給後來人更多機會;整個系統會趨向於更封閉,逐漸演變成一個有限游戲,長期運行下去只會越來越中心化;系統中財富越來越集中,富者更富,窮者更窮,從而更不可能實現去中心化(Decentralization)。
由於PoW系統中是以提供工作量的方式產出區塊的,隨著時間的推移這些工作量都會被累積起來並使鏈不斷向前延伸,這也是為什麼叫區塊鏈;這些累積的工作量也給攻擊者造成了巨大障礙,如果想要反轉整條鏈,不僅需要非常高的算力,還需要相當長的時間,這也為應對攻擊提供了足夠長的時間緩沖。
而PoS系統其實只是維護一個分布式賬本,並沒有工作量累積的概念,一旦攻擊成功,要反轉整條鏈就是相當容易的,幾分鍾就可以搞定。
嚴格來說由PoW算力支撐的BTC不應歸為高科技類,由於它整個系統架構更保守更穩定,提供的更多的是一種物化價值(objectivecostliness),更能作為價值之錨,所以數字黃金這個稱號很貼切。而像ETH(目前還是PoW,2.0升級後為PoS)這些更接近科技類創新平台,PoS本質上更像是一種股權系統,其實PoS系統反而是需要中心化,偏向更依靠整個社區的生命力,需要依靠核心團隊的創新與開拓能力往前走;而PoW則需要去中心化,更偏向穩定與提供物化價值(objectivecostliness)。
區塊鏈作為一個價值分配系統,算力是它的價值之錨,如果沒有算力,就會退化為一個股權系統。算力在哪,資金就會跟去哪。目前的發展趨勢也是逐漸往多層網路的方向發展,類似TCP/IP的多層協議棧。從作為基礎層(BaseLayer)的角度看,更需要的是長期穩定與提供價值支撐,因此PoW系統更合適;而PoS可能更多的是可以作為Layer2以實現可擴展性(Scalability),彌補PoW基礎層的吞吐量不足,並通過錨定在PoW基礎層上來獲取算力安全性與價值支撐。
最後順帶說下最近市場行情,5,6月份以來的瀑布令很多人很恐慌,恐慌指數一度長時間停留在個位數;其實我覺得也沒必要那麼恐慌,要在這個圈子長期活下去,面對這種大波動的心理預期還是要有的。想起之前紅杉資本的沈南鵬經常提到一個詞Grit,沙礫,它是礫石在千萬次打磨後留下來的細小顆粒;Grit代表了勇氣和持之以恆的一種堅持,有種經常被按地上摩擦但依然勇往直前的感覺。這個和塔勒布講的反脆弱性有異曲同工之妙,承載價值的東西就應該具有這種品質,PoW系統肯定是有反脆弱性的。
回望2017年入圈後經歷過的各種事件,其實像這樣的大波動近乎每年都有(除了2019年一年比較順利外);像2017年國內的94事件,2018年一整年的大熊市,2020的312事件,2021的519事件,再到2022今年的5,6月份市場轉熊,每次經歷大波動後,市場都會淘汰掉該淘汰的,出清掉該出清的風險,對整個行業發展也是好事。眼光還是應該放遠一點,至少看5到10年後的變化,科技發展過程中所帶來的波動和風險是不可避免的,日光之下無新鮮事,每次科技革命過程中總會夾雜著眾多的反對、質疑,還有眾多的投機、騙局;這個過程也總是通過各種暴雷、回歸,清除泡沫後價值重估,夯實了基礎後積蓄能量再次進入躍升到新的發展階段。價值互聯網的到來是一件無法迴避的事情,當理解和看清了這種趨勢後,規避掉各種坑和市場噪音,遠離合約杠桿和各種山寨的誘惑,握住核心資產,時間本身就會帶來回報。
在公鏈項目早期,為什麼PoW是一個更好選擇?在傳統的互聯網公司或金融機構中,如果一家公司,在一年之內,被委託的交易結算的總量為萬億美元的話,這家公司要麼擁有可靠的技術和雄厚的資本,要麼就是其它大公司及政府為其信用來做背書。而比特幣卻在沒有政府或公司背書的情況下,在過去一年內支持了相當於一萬億美元的交易。這是因為比特幣的工作量證明(PoW)機制確保了全世界的比特幣礦工以點對點的方式去分布式地維護賬本,且保證了其正確性和不可篡改性。
實際上,PoW?協議並不完美,它在運行過程中需要消耗大量的能量來計算哈希函數的結果,以保護區塊鏈系統不被攻擊。很多人認為這是一種「無用的能源消耗」。為了避免這種消耗,股權證明協議(PoS)便作為替代方案被提出。包括以太坊在內的幾個著名的項目也開始探索股權證明協議(PoS),?甚至有人認為,PoS協議在未來將完全取代PoW協議。
但是,在對PoS?協議進行了深入的技術剖析之後,我們會發現:在一個公鏈項目的早期階段,PoS?協議會帶來很多問題,而這些問題在PoW協議下是可以避免。首先,使用PoS協議啟動主網的公鏈項目,會不可避免地存在共識中心化的問題,因為主網上線的時候股權分布往往是相對集中的。此外,純?PoS?協議還面臨著遠程攻擊(LongRangeattack)的威脅。最嚴重的遠程攻擊會導致新加入的節點必須信任一些中心化的網站給出的信息,而這會導致?PoS?公鏈成為一個本質上中心化的網路。去使用PoW協議啟動主網的區塊鏈則可以實現分散的共識,從而避免這些問題。當PoW公鏈經過一段時間的發展,股權分布相對分散以後,還可以選擇PoW/PoS復合機制。
除此之外,還有一點值得注意的是,很多人誤以為比特幣的擴容問題是PoW機制的局限性造成的。我們經常在媒體網站或白皮書中看到這樣的句子,「比特幣因為使用了PoW機制,所以只能處理每秒3-7筆交易」。而事實上,經過適當的設計,例如,GHOST,Conflux?這樣的PoW演算法可以顯著提高出塊效率,達到每秒處理數千筆交易,且每筆交易都能得到全網節點的驗證。
PoWv.s.PoS:如何確定投票權
關於PoW和PoS之間的主要區別,就是在於如何確定區塊鏈共識中的投票權。?在PoW中,系統中的投票權與節點的計算能力成正比。每秒可以計算哈希函數次數越多,節點就越有可能贏得區塊鏈中下一個區塊的出塊權。而在PoS中,系統的投票權與持有的股權比例成正比。節點擁有資金越多,能為確定的下一個區塊投的票數就越多。
在公鏈早期階段,股權中心化將導致共識中心化
對於一個公有鏈來說,其上線初期往往是股權最集中的時候。在主網上線伊始,創始塊中分配的幣絕大多數屬於項目方和私募投資人,而這些人的數量往往非常有限。對於PoW共識機制,初始股權的集中不會帶來安全性問題,因為它的出塊和安全性不依賴於股權持有的分散,而是依賴於算力的分散。對於使用反?ASIC?礦機的挖礦演算法的公有鏈來說,任何人只要擁有顯卡和網路就可以成為礦工,這有助於促進更多人參與挖礦,實現早期算力的分散。只要超過50%的算力來自於誠實的礦工,區塊鏈中的交易就是安全不可逆轉的。
然而,在PoS共識機制下,股權集中會導致共識協議的參與者集中。區塊鏈的出塊權只能由少數在創世塊中擁有股權的玩家決定。如果這些人合謀對區塊鏈進行攻擊,則完全可以成功的實現雙花攻擊(Doublespendingattack).?盡管開發者和投資人出於利益考慮不會進行這樣的攻擊來摧毀他們自己的公鏈,但PoS公鏈也無可避免的在主網上線後就被這些人壟斷和支配。更糟的是,如果出塊可以獲得大量獎勵和交易費用,這些壟斷者就會將大量股權牢牢控制在自己的手裡,使得PoS公鏈成為一個本質上由巨頭控制的網路。
我們不要忘了,區塊鏈的核心價值是什麼?是去中心化的共識協議,保證了區塊鏈系統中每筆交易的正確性、不可篡改性。如果共識協議無法保證參與者的分散,區塊鏈就無法做到無需信任的安全性,那麼區塊鏈和傳統的分布式系統相比就沒有任何優勢了,甚至傳統的分布式系統能做得更經濟更高效。因此,公鏈項目在早期使用PoW,?是避免共識中心化,保護區塊鏈核心價值的明智選擇。
「長程攻擊」與「主觀依賴」問題
在一個公有鏈中,一個攻擊者如果擁有當下足夠多的算力或股權,無疑是可以打破公有鏈安全性完成攻擊的。但是在PoS?公鏈中,如果攻擊者獲得了一些賬戶的私鑰,這些私鑰在歷史上某一時刻控制了超過51%的股權,也可以完成攻擊,這種攻擊的方式被稱為長程攻擊(LongRangeAttack)。
在長程攻擊中,攻擊者首先獲得一些私鑰,只要這些私鑰在歷史上曾經獲得了足夠多的股權,便可以從這一時刻開始分叉進行51%?攻擊,製造一條分叉鏈出來。而?PoS?的出塊不需要進行工作量證明,攻擊者可以短時間內讓重寫歷史的分叉鏈追趕上原本的主鏈,從而造成PoS鏈的分叉和防篡改性被打破。
攻擊者能夠取得這些私鑰不是天方夜譚。如果PoS公鏈的早期投資人在二級市場將持有的代幣賣掉後,將賬戶私鑰賣給攻擊者,攻擊者就可以從創世塊進行長鏈攻擊,從而可以打破一個鏈的安全性。如果一些投資者追求短期收益而非價值投資,攻擊者從他們手裡獲得私鑰就成為了一個可能的事情。
而為了應對長程攻擊,則有各種各樣的解決方案被提出:例如使用密鑰演化演算法更新密鑰,以避免密鑰被盜。但是如果早期投資者一開始就決定通過出售私鑰獲利,那麼他完全可以保留密鑰種子以繞開這一限制。還有一些解決方案基於這樣一個事實:如果攻擊者挖了一條完全不同的鏈,長期在系統中運行的節點或許有能力探測出這種異常。但是,這些方案依然存在如下問題:
PoS?長程攻擊造成的分叉與?PoW?的分叉有所不同。PoW?的分叉鏈難以獲得比特幣全網算力,比特幣礦工很容易從總算力中辨別誰是真正的比特幣。鑒於PoS共識協議在實際運行時,絕大多數股權持有者只是區塊鏈的使用者,並不會一直運行一台伺服器。攻擊者只要在一個歷史節點擁有了相當與PoS實際參與者的股權比例,就可以製造出一條難以辨別的分叉鏈出來。配合女巫攻擊(SybilAttack),攻擊者可以從區塊歷史和節點數量上都獲得和被攻擊主鏈接近的水平,令新加入的節點無法區分,只能通過人工指定的方式選擇。這樣新參與者必須咨詢受信任節點來安全地加入系統,這一問題被稱為「主觀依賴」(WeakSubjectivity)
無利害攻擊
無利害攻擊(NothingatStake)是另一種PoS攻擊方式。當一個?PoS?鏈因為網路延遲、長程攻擊或其他原因出現分叉時,PoS?礦工可以選擇在兩個分叉的鏈上同時出塊,以獲取最大收益。而這違反了共識協議。
在PoW?鏈中,如果一個礦工想同時在多個分叉上挖礦,就必須將自己的算力分散在多個分叉上,所有分叉上分配的算力總和不會超過礦工擁有的總算力。對於多數礦工而言,將自己的全部算力投入到協議指定的鏈上是最優的選擇。
然而,在PoS?多個分叉上同時出塊所帶來的額外成本可以忽略不計,而選擇同時出塊可以保證無論哪一條分叉鏈最終勝出都可獲得收益。如果礦工遵守共識協議,只在協議指定的鏈上挖礦。一旦這個鏈被丟棄,礦工將會失去挖礦獎勵。只追求挖礦收益最大化的礦工會在兩邊同時參與,不惜因此打破協議——這會導致鏈長時間維持分叉的狀態。
與長程攻擊不同,精巧的激勵機制設計可以避免這一攻擊。但無利害攻擊依然表明讓PoS鏈正確地運行是一件很困難的事情。
總結
雖然PoS?具有節省能源等優勢,從而很多項目表示將採用PoS。但我們在分析區塊鏈安全性假設後發現,避免了計算「無用的哈希」之後會引入很多攻擊情形,而且目前沒有很完美的解決方案。誠然PoS有能源效率的優勢,但也帶來了很多安全性威脅。在PoS很好地解決這些威脅之前,PoW消耗的能源,就像和平時期國家軍隊用掉的軍費一樣,阻擋了很多潛在的威脅。最重要的是,其中許多威脅在區塊鏈項目早期顯得尤其致命。這也是我們為什麼相信新的公鏈項目應該從PoW開始。
POW&POS,傻傻分不清楚的共識機制什麼是共識機制?
我在開更的第一篇文章,就簡單講解了數字貨幣世界的16個最高頻名詞,其中一個就是共識機制,還記得嗎?
為什麼要有共識機制呢?
這就必須要解釋一下在分布式系統中不得不了解的「拜占庭將軍問題」了。
拜占庭將軍問題(TheByzantineGeneralsProblem)可以總結為一句話:
在古代,11位忠誠的、不同位置的將軍,如何排除叛徒的影響,對進攻或撤退達成一致。
當然,拜占庭將軍問題並不是如今才提出的,我們大中華在春秋戰國時期就發明了「虎符」這個神奇的方式來保障命令的正確執行。
在分布系數系統中,各個節點就是「拜占庭將軍」,演算法執行中的任意一個錯誤就是「叛徒」。
為了盡可能地排除錯誤、快速達成一致,來讓系統有效地、正確地運行,便應運而生了各種「共識機制」。
————————————————
下面,我們就來一起學習數字貨幣世界中常見的幾種共識機制:
PoW,工作量證明ProofofWork
PoW是比特幣所採用的共識機制,最早是由AdamBack為了解決垃圾郵件的問題而開發的一個「哈希現金Hashcash」程序。
比特幣採用的是SHA256的單向函數,其具體的工作原理實在太專業,我們只需要理解到「SHA256的結果很容易驗證,但是要將其計算出來,需要不斷嘗試運算,直到匹配到某個隨機數;技術上而言,任何新增區塊都需要經過232394億運算才能得到」的程度,感興趣的小夥伴可以搜索SHA256去深入學習。
因此,只要礦工出示運算結果,那通過PoW,全網節點就認可了他所付出的成本,承認新的區塊獎勵屬於他。
如此大量的運算相當浪費資源,實際上並沒有任何科學或實際用途,只是為了實踐工作量證明機制、阻止攻擊者偽裝成節點來控制網路。
雖然在2009年時為了構建這種去中心化的、允許所有人可以免費參與的全球貨幣網路,沒有更好的選擇;但是發展到如今,已經有了其他不需要大量浪費算力的證明機制,比如我們下面就要提到的,PoS權益證明。
————————————————
PoS,權益證明ProofofStake
主要思想是:節點記賬權的獲得難度與節點持有的權益成反比,也就是說,一個節點擁有的幣越多、時間越久,越容易獲取記賬權,也就越容易獲取區塊獎勵。
實際上,最初的PoS是PoW的一種升級,根據每個節點的幣齡,來等比例地降低挖礦難度,從而加快找到隨機數的速度。
什麼是幣齡呢?
幣齡=數量*擁有天數。
由於區塊鏈中的每筆交易記錄都會被標記時間戳,這個時間戳就可以作為幣齡的證明,因此幣齡也不可能被輕易偽造。
比如A從B那裡收到10個幣,並且持有了90天,那麼,A就擁有了900的幣齡;如果A賣了這10個幣,這900幣齡就被消耗了;
後來,為了徹底擺脫PoW這種依靠算力的共識機制,PoS引入了「利息」的概念;年利率是在PoS機制最初確認時就設定的,一般不會變化。
利息=(幣齡*年利率)/365,如果利率是1%,在上個例子中,A就可以得到0.02466個幣的利息。
如此一來,PoS區塊鏈的作用過程就可以這樣描述:
在初期,通過PoW機制,產生創世幣;
在創世幣達到一定規模時,PoS機制開始作用,交易時消耗幣齡、獲得產生區塊的優先權,並獲取利息,同時PoW機制由於消耗太多資源、浪費算力而逐漸淡出;
最終系統中僅剩PoS來維持正常運作。
目前大家所熟悉的以太坊,主要還是採用PoW的機制,不過正在轉向PoS。
————————————————
大家了解了PoW和PoS,在遇到其他共識機制的時候,相信也會比較快得就能理解。
比如:股份授權證明DPOS,類似於董事會投票;燃燒證明POB;沉澱證明POD;能力證明POC;消逝時間證明PODT,等等。
就不在這里為大家一一展開了,感興趣的同學可以網路或知乎一下~
區塊鏈共識機制之一:POW工作量證明機制區塊鏈可以理解為一個不可篡改的公共賬本,所有參與者都能驗證交易並進行記賬,即為分布式賬本。那到底由誰來記賬?又如何保證賬本的一致性、准確性呢?也就是區塊鏈的共識機制是如何的?
區塊鏈的共識機制就是解決由誰來記賬(構造區塊),以及如何維護區塊鏈的一致性問題。目前區塊鏈項目採用的共識機制有多種,如:POW工作量證明機制,POS權益證明機制,DPOS股份授權證明機制等等。本文說明POW工作量證明機制。
區塊鏈的第一個成功應用比特幣系統採用的POW工作量證明機制。即以比特幣系統為例說明POW機制,首先比特幣系統有一套激勵機制讓所有參與者競爭記賬的權利,即誰擁有記賬權誰將獲取構造新區塊的比特幣獎勵(目前獎勵為12.5比特幣),同時獲取新區塊內所有交易的手續費作為獎勵。
參與者如何競爭記賬權利呢?參與者通過自己的算力計算一道數學難題,誰先計算的結果,誰就擁有了記賬的權利,也就可獲得構造新區塊的獎勵。這道數學難題就是尋找一個隨機數Nonce,使得對區塊頭的哈希計算的結果小於目標值,Nonce本身是區塊頭中的一個欄位,所以通過不斷的嘗試Nonce的值,以滿足區塊頭的哈希計算結果小於目標值。通過動態調整目標值,即可調整計算的Nonce值的難度。
關於哈希計算Nonce的過程通常類比為擲篩子游戲,基於參與游戲的篩子的個數通過調整擲得篩子的點數可調整游戲的難度。例如:100個人參與擲篩子,總共有100個篩子,要求擲得點數為100為贏,則100個人誰先擲得點數100即為勝利者,即擁有了記賬權。如果發現大家擲出100點的時間太快,則可增加難度,要求擲得點數為80為贏。如果又有100個人參與游戲,則游戲中增加了篩子數,如:篩子數增加為200個,同樣通過設置擲得點數來調整游戲的難度。
篩子類似於比特幣網路的算力,擲得點數類似於比特幣網路可動態調整的目標值。
區塊鏈以最長的鏈條視為正確的鏈條,如果存在同時出現兩個區塊,會暫時並行記錄兩個區塊,後續再生成的區塊基於其中的某一個
5. 區塊鏈 --- 共識演算法
PoW演算法是一種防止分布式服務資源被濫用、拒絕服務攻擊的機制。它要求節點進行適量消耗時間和資源的復雜運算,並且其運算結果能被其他節點快速驗算,以耗用時間、能源做擔保,以確保服務與資源被真正的需求所使用。
PoW演算法中最基本的技術原理是使用哈希演算法。假設求哈希值Hash(r),若原始數據為r(raw),則運算結果為R(Result)。
R = Hash(r)
哈希函數Hash()的特性是,對於任意輸入值r,得出結果R,並且無法從R反推回r。當輸入的原始數據r變動1比特時,其結果R值完全改變。在比特幣的PoW演算法中,引入演算法難度d和隨機值n,得到以下公式:
Rd = Hash(r+n)
該公式要求在填入隨機值n的情況下,計算結果Rd的前d位元組必須為0。由於哈希函數結果的未知性,每個礦工都要做大量運算之後,才能得出正確結果,而算出結果廣播給全網之後,其他節點只需要進行一次哈希運算即可校驗。PoW演算法就是採用這種方式讓計算消耗資源,而校驗僅需一次。
PoS演算法要求節點驗證者必須質押一定的資金才有挖礦打包資格,並且區域鏈系統在選定打包節點時使用隨機的方式,當節點質押的資金越多時,其被選定打包區塊的概率越大。
POS模式下,每個幣每天產生1幣齡,比如你持有100個幣,總共持有了30天,那麼,此時你的幣齡就為3000。這個時候,如果你驗證了一個POS區塊,你的幣齡就會被清空為0,同時從區塊中獲得相對應的數字貨幣利息。
節點通過PoS演算法出塊的過程如下:普通的節點要成為出塊節點,首先要進行資產的質押,當輪到自己出塊時,打包區塊,然後向全網廣播,其他驗證節點將會校驗區塊的合法性。
DPoS演算法和PoS演算法相似,也採用股份和權益質押。
但不同的是,DPoS演算法採用委託質押的方式,類似於用全民選舉代表的方式選出N個超級節點記賬出塊。
選民把自己的選票投給某個節點,如果某個節點當選記賬節點,那麼該記賬節點往往在獲取出塊獎勵後,可以採用任意方式來回報自己的選民。
這N個記賬節點將輪流出塊,並且節點之間相互監督,如果其作惡,那麼會被扣除質押金。
通過信任少量的誠信節點,可以去除區塊簽名過程中不必要的步驟,提高了交易的速度。
拜占庭問題:
拜占庭是古代東羅馬帝國的首都,為了防禦在每塊封地都駐扎一支由單個將軍帶領的軍隊,將軍之間只能靠信差傳遞消息。在戰爭時,所有將軍必須達成共識,決定是否共同開戰。
但是,在軍隊內可能有叛徒,這些人將影響將軍們達成共識。拜占庭將軍問題是指在已知有將軍是叛徒的情況下,剩餘的將軍如何達成一致決策的問題。
BFT:
BFT即拜占庭容錯,拜占庭容錯技術是一類分布式計算領域的容錯技術。拜占庭假設是對現實世界的模型化,由於硬體錯誤、網路擁塞或中斷以及遭到惡意攻擊等原因,計算機和網路可能出現不可預料的行為。拜占庭容錯技術被設計用來處理這些異常行為,並滿足所要解決的問題的規范要求。
拜占庭容錯系統 :
發生故障的節點被稱為 拜占庭節點 ,而正常的節點即為 非拜占庭節點 。
假設分布式系統擁有n台節點,並假設整個系統拜占庭節點不超過m台(n ≥ 3m + 1),拜占庭容錯系統需要滿足如下兩個條件:
另外,拜占庭容錯系統需要達成如下兩個指標:
PBFT即實用拜占庭容錯演算法,解決了原始拜占庭容錯演算法效率不高的問題,演算法的時間復雜度是O(n^2),使得在實際系統應用中可以解決拜占庭容錯問題
PBFT是一種狀態機副本復制演算法,所有的副本在一個視圖(view)輪換的過程中操作,主節點通過視圖編號以及節點數集合來確定,即:主節點 p = v mod |R|。v:視圖編號,|R|節點個數,p:主節點編號。
PBFT演算法的共識過程如下:客戶端(Client)發起消息請求(request),並廣播轉發至每一個副本節點(Replica),由其中一個主節點(Leader)發起提案消息pre-prepare,並廣播。其他節點獲取原始消息,在校驗完成後發送prepare消息。每個節點收到2f+1個prepare消息,即認為已經准備完畢,並發送commit消息。當節點收到2f+1個commit消息,客戶端收到f+1個相同的reply消息時,說明客戶端發起的請求已經達成全網共識。
具體流程如下 :
客戶端c向主節點p發送<REQUEST, o, t, c>請求。o: 請求的具體操作,t: 請求時客戶端追加的時間戳,c:客戶端標識。REQUEST: 包含消息內容m,以及消息摘要d(m)。客戶端對請求進行簽名。
主節點收到客戶端的請求,需要進行以下交驗:
a. 客戶端請求消息簽名是否正確。
非法請求丟棄。正確請求,分配一個編號n,編號n主要用於對客戶端的請求進行排序。然後廣播一條<<PRE-PREPARE, v, n, d>, m>消息給其他副本節點。v:視圖編號,d客戶端消息摘要,m消息內容。<PRE-PREPARE, v, n, d>進行主節點簽名。n是要在某一個范圍區間內的[h, H],具體原因參見 垃圾回收 章節。
副本節點i收到主節點的PRE-PREPARE消息,需要進行以下交驗:
a. 主節點PRE-PREPARE消息簽名是否正確。
b. 當前副本節點是否已經收到了一條在同一v下並且編號也是n,但是簽名不同的PRE-PREPARE信息。
c. d與m的摘要是否一致。
d. n是否在區間[h, H]內。
非法請求丟棄。正確請求,副本節點i向其他節點包括主節點發送一條<PREPARE, v, n, d, i>消息, v, n, d, m與上述PRE-PREPARE消息內容相同,i是當前副本節點編號。<PREPARE, v, n, d, i>進行副本節點i的簽名。記錄PRE-PREPARE和PREPARE消息到log中,用於View Change過程中恢復未完成的請求操作。
主節點和副本節點收到PREPARE消息,需要進行以下交驗:
a. 副本節點PREPARE消息簽名是否正確。
b. 當前副本節點是否已經收到了同一視圖v下的n。
c. n是否在區間[h, H]內。
d. d是否和當前已收到PRE-PPREPARE中的d相同
非法請求丟棄。如果副本節點i收到了2f+1個驗證通過的PREPARE消息,則向其他節點包括主節點發送一條<COMMIT, v, n, d, i>消息,v, n, d, i與上述PREPARE消息內容相同。<COMMIT, v, n, d, i>進行副本節點i的簽名。記錄COMMIT消息到日誌中,用於View Change過程中恢復未完成的請求操作。記錄其他副本節點發送的PREPARE消息到log中。
主節點和副本節點收到COMMIT消息,需要進行以下交驗:
a. 副本節點COMMIT消息簽名是否正確。
b. 當前副本節點是否已經收到了同一視圖v下的n。
c. d與m的摘要是否一致。
d. n是否在區間[h, H]內。
非法請求丟棄。如果副本節點i收到了2f+1個驗證通過的COMMIT消息,說明當前網路中的大部分節點已經達成共識,運行客戶端的請求操作o,並返回<REPLY, v, t, c, i, r>給客戶端,r:是請求操作結果,客戶端如果收到f+1個相同的REPLY消息,說明客戶端發起的請求已經達成全網共識,否則客戶端需要判斷是否重新發送請求給主節點。記錄其他副本節點發送的COMMIT消息到log中。
如果主節點作惡,它可能會給不同的請求編上相同的序號,或者不去分配序號,或者讓相鄰的序號不連續。備份節點應當有職責來主動檢查這些序號的合法性。
如果主節點掉線或者作惡不廣播客戶端的請求,客戶端設置超時機制,超時的話,向所有副本節點廣播請求消息。副本節點檢測出主節點作惡或者下線,發起View Change協議。
View Change協議 :
副本節點向其他節點廣播<VIEW-CHANGE, v+1, n, C , P , i>消息。n是最新的stable checkpoint的編號, C 是 2f+1驗證過的CheckPoint消息集合, P 是當前副本節點未完成的請求的PRE-PREPARE和PREPARE消息集合。
當主節點p = v + 1 mod |R|收到 2f 個有效的VIEW-CHANGE消息後,向其他節點廣播<NEW-VIEW, v+1, V , O >消息。 V 是有效的VIEW-CHANGE消息集合。 O 是主節點重新發起的未經完成的PRE-PREPARE消息集合。PRE-PREPARE消息集合的選取規則:
副本節點收到主節點的NEW-VIEW消息,驗證有效性,有效的話,進入v+1狀態,並且開始 O 中的PRE-PREPARE消息處理流程。
在上述演算法流程中,為了確保在View Change的過程中,能夠恢復先前的請求,每一個副本節點都記錄一些消息到本地的log中,當執行請求後副本節點需要把之前該請求的記錄消息清除掉。
最簡單的做法是在Reply消息後,再執行一次當前狀態的共識同步,這樣做的成本比較高,因此可以在執行完多條請求K(例如:100條)後執行一次狀態同步。這個狀態同步消息就是CheckPoint消息。
副本節點i發送<CheckPoint, n, d, i>給其他節點,n是當前節點所保留的最後一個視圖請求編號,d是對當前狀態的一個摘要,該CheckPoint消息記錄到log中。如果副本節點i收到了2f+1個驗證過的CheckPoint消息,則清除先前日誌中的消息,並以n作為當前一個stable checkpoint。
這是理想情況,實際上當副本節點i向其他節點發出CheckPoint消息後,其他節點還沒有完成K條請求,所以不會立即對i的請求作出響應,它還會按照自己的節奏,向前行進,但此時發出的CheckPoint並未形成stable。
為了防止i的處理請求過快,設置一個上文提到的 高低水位區間[h, H] 來解決這個問題。低水位h等於上一個stable checkpoint的編號,高水位H = h + L,其中L是我們指定的數值,等於checkpoint周期處理請求數K的整數倍,可以設置為L = 2K。當副本節點i處理請求超過高水位H時,此時就會停止腳步,等待stable checkpoint發生變化,再繼續前進。
在區塊鏈場景中,一般適合於對強一致性有要求的私有鏈和聯盟鏈場景。例如,在IBM主導的區塊鏈超級賬本項目中,PBFT是一個可選的共識協議。在Hyperledger的Fabric項目中,共識模塊被設計成可插拔的模塊,支持像PBFT、Raft等共識演算法。
Raft基於領導者驅動的共識模型,其中將選舉一位傑出的領導者(Leader),而該Leader將完全負責管理集群,Leader負責管理Raft集群的所有節點之間的復制日誌。
下圖中,將在啟動過程中選擇集群的Leader(S1),並為來自客戶端的所有命令/請求提供服務。 Raft集群中的所有節點都維護一個分布式日誌(復制日誌)以存儲和提交由客戶端發出的命令(日誌條目)。 Leader接受來自客戶端的日誌條目,並在Raft集群中的所有關注者(S2,S3,S4,S5)之間復制它們。
在Raft集群中,需要滿足最少數量的節點才能提供預期的級別共識保證, 這也稱為法定人數。 在Raft集群中執行操作所需的最少投票數為 (N / 2 +1) ,其中N是組中成員總數,即 投票至少超過一半 ,這也就是為什麼集群節點通常為奇數的原因。 因此,在上面的示例中,我們至少需要3個節點才能具有共識保證。
如果法定仲裁節點由於任何原因不可用,也就是投票沒有超過半數,則此次協商沒有達成一致,並且無法提交新日誌。
數據存儲:Tidb/TiKV
日誌:阿里巴巴的 DLedger
服務發現:Consul& etcd
集群調度:HashiCorp Nomad
只能容納故障節點(CFT),不容納作惡節點
順序投票,只能串列apply,因此高並發場景下性能差
Raft通過解決圍繞Leader選舉的三個主要子問題,管理分布式日誌和演算法的安全性功能來解決分布式共識問題。
當我們啟動一個新的Raft集群或某個領導者不可用時,將通過集群中所有成員節點之間協商來選舉一個新的領導者。 因此,在給定的實例中,Raft集群的節點可以處於以下任何狀態: 追隨者(Follower),候選人(Candidate)或領導者(Leader)。
系統剛開始啟動的時候,所有節點都是follower,在一段時間內如果它們沒有收到Leader的心跳信號,follower就會轉化為Candidate;
如果某個Candidate節點收到大多數節點的票,則這個Candidate就可以轉化為Leader,其餘的Candidate節點都會回到Follower狀態;
一旦一個Leader發現系統中存在一個Leader節點比自己擁有更高的任期(Term),它就會轉換為Follower。
Raft使用基於心跳的RPC機制來檢測何時開始新的選舉。 在正常期間, Leader 會定期向所有可用的 Follower 發送心跳消息(實際中可能把日誌和心跳一起發過去)。 因此,其他節點以 Follower 狀態啟動,只要它從當前 Leader 那裡收到周期性的心跳,就一直保持在 Follower 狀態。
當 Follower 達到其超時時間時,它將通過以下方式啟動選舉程序:
根據 Candidate 從集群中其他節點收到的響應,可以得出選舉的三個結果。
共識演算法的實現一般是基於復制狀態機(Replicated state machines),何為 復制狀態機 :
簡單來說: 相同的初識狀態 + 相同的輸入 = 相同的結束狀態 。不同節點要以相同且確定性的函數來處理輸入,而不要引入一下不確定的值,比如本地時間等。使用replicated log是一個很不錯的注意,log具有持久化、保序的特點,是大多數分布式系統的基石。
有了Leader之後,客戶端所有並發的請求可以在Leader這邊形成一個有序的日誌(狀態)序列,以此來表示這些請求的先後處理順序。Leader然後將自己的日誌序列發送Follower,保持整個系統的全局一致性。注意並不是強一致性,而是 最終一致性 。
日誌由有序編號(log index)的日誌條目組成。每個日誌條目包含它被創建時的任期號(term),和日誌中包含的數據組成,日誌包含的數據可以為任何類型,從簡單類型到區塊鏈的區塊。每個日誌條目可以用[ term, index, data]序列對表示,其中term表示任期, index表示索引號,data表示日誌數據。
Leader 嘗試在集群中的大多數節點上執行復制命令。 如果復製成功,則將命令提交給集群,並將響應發送回客戶端。類似兩階段提交(2PC),不過與2PC的區別在於,leader只需要超過一半節點同意(處於工作狀態)即可。
leader 、 follower 都可能crash,那麼 follower 維護的日誌與 leader 相比可能出現以下情況
當出現了leader與follower不一致的情況,leader強制follower復制自己的log, Leader會從後往前試 ,每次AppendEntries失敗後嘗試前一個日誌條目(遞減nextIndex值), 直到成功找到每個Follower的日誌一致位置點(基於上述的兩條保證),然後向後逐條覆蓋Followers在該位置之後的條目 。所以丟失的或者多出來的條目可能會持續多個任期。
要求候選人的日誌至少與其他節點一樣最新。如果不是,則跟隨者節點將不投票給候選者。
意味著每個提交的條目都必須存在於這些伺服器中的至少一個中。如果候選人的日誌至少與該多數日誌中的其他日誌一樣最新,則它將保存所有已提交的條目,避免了日誌回滾事件的發生。
即任一任期內最多一個leader被選出。這一點非常重要,在一個復制集中任何時刻只能有一個leader。系統中同時有多餘一個leader,被稱之為腦裂(brain split),這是非常嚴重的問題,會導致數據的覆蓋丟失。在raft中,兩點保證了這個屬性:
因此, 某一任期內一定只有一個leader 。
當集群中節點的狀態發生變化(集群配置發生變化)時,系統容易受到系統故障。 因此,為防止這種情況,Raft使用了一種稱為兩階段的方法來更改集群成員身份。 因此,在這種方法中,集群在實現新的成員身份配置之前首先更改為中間狀態(稱為聯合共識)。 聯合共識使系統即使在配置之間進行轉換時也可用於響應客戶端請求,它的主要目的是提升分布式系統的可用性。