我們先從常見的拜占庭將軍問題中理解一下什么是共識。
拜占庭將軍問題
拜占庭位于如今的土耳其的伊斯坦布爾,是東羅馬帝國的首都。由于當時拜占庭羅馬帝國國土遼闊,為了防御目的,因此每個軍隊都分隔很遠,將軍與將軍之間只能靠信差傳消息。在戰爭的時候,拜占庭軍隊內所有將軍和副官必須達成一致的共識,決定是否有贏的機會才去攻打敵人的陣營。但是,在軍隊內有可能存在叛徒和敵軍的間諜,左右將軍們的決定又擾亂整體軍隊的秩序。將軍們采用投票的策略來決定是進攻還是撤退,也就是說如果多數人決定進攻,就沖上去,如果多數人決定撤退,就撤退(比如10位將軍中,有6位選擇進攻,那么就進攻)。
這時候,在已知有成員謀反的情況下(或者是有奸細的情況下,他們亂投票,或者擅自修改軍令),其余忠誠的將軍在不受叛徒的影響下如何達成一致的協議,拜占庭問題就此形成。
拜占庭將軍問題是一個協議問題,拜占庭帝國軍隊的將軍們必須全體一致的決定是否攻擊某一支敵軍。問題是這些將軍在地理上是分隔開來的,并且將軍中存在叛徒。叛徒可以任意行動以達到以下目標:欺騙某些將軍采取進攻行動;促成一個不是所有將軍都同意的決定,如當將軍們不希望進攻時促成進攻行動;或者迷惑某些將軍,使他們無法做出決定。如果叛徒達到了這些目的之一,則任何攻擊行動的結果都是注定要失敗的,只有完全達成一致的努力才能獲得勝利。
所以,拜占庭將軍是一個分布式系統中的共識問題,也是一個分布式容錯系統的問題。拜占庭將軍問題不是說要讓將軍達成進攻的決定,而是讓所有忠誠將軍達成共識,要么全都進攻,要么全都撤退,不至于被敵方各個攻破。
目前拜占庭將軍問題也有很多經典解法,常見的有實用拜占庭容錯系統(PBFT)和Raft。PBFT的解法前提是需要n ≥ 3t+1,其中t是故障節點個數(也就是謀反將軍的個數),n是總節點個數(也就是所有將軍的總數)。這些方式雖然能達成共識,也各有優點,但是都有不同的假設條件,自帶局限性。
目前在區塊鏈系統中,PBFT和Raft是聯盟鏈和私有鏈上常用的共識算法,而在公有鏈上,常用的是POW,POS,DPOS等共識算法。
區塊鏈的共識
我們平時支付的時候使用支付寶刷一下就行了,其實并沒有進行實際貨幣的轉移,而是支付寶在它的數據庫里記了一筆賬。現在的貨幣系統其實是一個記賬貨幣,而記賬的主體是國家央行或者支付寶等第三方機構,這是一種中心化記賬形式。而中心化記賬雖然很效率高,但是也面臨著各種問題,比如中心化節點引發的單點失敗,萬一一顆流星正好掉到了阿里巴巴的數據庫機房上;再比如操作人員造假,萬一阿里巴巴的數據庫管理員哪天心情不好,然后先刪庫再跑路。當然這些事件的可能性都很小,但是黑天鵝事情要么不發生,要發生就可能是毀滅性的打擊。所以,對這種可能存在的小概率事情,解決方案一般以預防為主,比如備份數據,多建幾個分布式節點,對人員進行SOP培訓,還有一種解決方案,就是使用更可靠,更安全的系統。
區塊鏈的去中心化記賬,從技術上解決了上面提到的中心化記賬的弱點。因為它沒有中心節點,通過計算機算法、密碼學、經濟學,結合智能合約,點對點傳輸,不可篡改。區塊鏈的每個區塊相當于賬本頁,每個區塊中記錄的是相應的交易內容。但是,去中心化記賬行為的一個很重要的問題,就是各個節點賬本的一致性。
從去中心化賬本系統看,每個加入這個系統的節點都需要保存一份完整的賬本,但是卻不能有兩個節點同時記賬,因為節點處于不同的環境,接收到的交易信息不一致,如果同時記賬的話,就會導致賬本的不一致。所以,需要通過共識機制來:
- 公平公正地決定由哪個節點來記賬。目前常用的就是POW,POS等。
- 某個節點記賬后保持全網賬本同步。目前常用的是最長鏈策略。
POW:Proof of Work,工作量證明
比特幣系統設計了以每個節點的計算能力,即“算力”來競爭記賬權的機制。簡單說,POW就是一份確定工作端做過一定量工作的證明。舉個例子來說,就是我去面試的時候,招聘網站上寫的該崗位需要本科以上學歷。那我怎么證明我是本科畢業生呢?把本科畢業證show給面試官看就可以了,就是這么簡單。但是我要怎么得到這個畢業證呢?需要上4年的大學,在此之前還要上高中,初中,小學,上大學時還不能天天玩樂,還要上課,考試,考試還不能掛科,這是一個艱辛的過程。對面試官而言,一張畢業證就足以證明我上過大學,而且還不笨。
所以,POW方式的主要特點就是計算的不對稱性。工作端需要做一定難度的工作才能得到一個結果,但驗證方卻很容易通過結果來檢查工作端是不是做了相應的工作。具體做法是通過對一個區塊鏈頭部中的父區塊哈希,Merkle樹根和nonce值三個字段進行哈希運算,如果結果小于目標值,則計算成功,如果大于目標值,則改變nonce值,重復運算,直到結果小于目標值為止。
怎么理解pow的工作方和驗證方呢?再舉個例子。
工作方:假設輸入值是 blockchain1,對它進行哈希運算,尋找結果前3位為0的哈希值,那么計算過程是:
blockchain1 -> ef7797e13d3a75526946a3bcf00daec9fc9c9c4d51ddc7cc5df888f74dd434d1
blockchain2 -> db0b9c1cb5e9c680dfff7482f1a8efad0e786f41b6b89a758fb26d9e223e0a10
......
blockchain515 -> 0063e58fb6e3789fcb5eb64d05d7a9b909c5e9e1b60b18cb566a3326c1fd54c
......
blockchain2688 -> 0005f2ee930eafef21d06545c0058ddfcf2ac9dfa542b745021f51ceb9e9f43c
可以看出,經過2688次運算才能找到前三位為0的哈希值。隨著0個數的增加,那么計算難度是成指數級增加的。
驗證方:驗證方拿到工作方得到數值blockchain2688,只需要一次計算就可以知道工作方的工作有沒有做出來。
對于pow,如果要尋找特定字符串后面的隨機nonce,滿足前n位均為0的SHA256值,需要進行多次哈希值的運算。一般來說,由于哈希值的偽隨機性,要尋找3個前導0的哈希值,預期大概要進行2的12次方次嘗試,這個數學期望的計算次數,就是所謂的“工作量”。整個工作量證明活動,就是我們常說的“挖礦”所做的工作。
在上面的例子中,實際的比特幣系統中有幾個比較關鍵的地方,比如nonce值是怎么改變的,目標值的0的個數是怎么確定的等,可以參考比特幣挖礦一文。
比特幣網絡中的任何一個節點,如果想生成一個新的區塊并寫入區塊鏈,必須解出比特幣網絡出的POW問題。這道題有三個關鍵要素:
- 工作量證明函數
- 區塊
- 難度值/目標值
比特幣系統中使用的工作量證明函數是SHA256,SHA是安全哈希算法(Secure Hash Algorithm)的縮寫,是一種密碼哈希函數家族,SHA256是其中的一種,輸出256位的哈希算法。比特幣的區塊是由區塊頭和該區塊所包含的交易列表組成,區塊中包含了一個指向前一區塊的哈希指針,使得記錄了不同交易的單個區塊被關聯起來,形成區塊鏈。難度值是比特幣系統中的節點在生成區塊時的重要參考指標,它決定了節點大概需要多少次哈希運算才能產生一個哈法的區塊,難度值會隨著全網算力的變化進行調整,將產生區塊的速率保持在10分鐘一個。
因此,POW成功的決定因素就是算力大小,如果你的算力是n,全網算力是m,那么你在一次工作量證明,也就是一次挖礦活動中能夠成功的概率是n/m ,經過 m/n 次挖礦中可以成功一次。比如我的筆記本算法大概是1GH/s,現在全網算力是21EH/s,那么我大概需要進行200億次工作量證明,每次大概10分鐘,有生之年肯定是挖不出來一個的。
POS:Proof of Stake,權益證明
現在我們知道如何對比特幣進行挖礦了,那就是需要購買挖礦設備和支付電耗,以此來獲取新幣作為挖礦的獎勵。這基本上是一個很消耗資源的過程。而且有兩個明顯的弊端,一方面,pow的前提是,節點和算力是均勻分布的,因為中本聰當初的設計是通過CPU挖礦,這樣節點數和算力值可以大致匹配,但是隨著GPU,FPGA直到礦機,使得節點數和算力值漸漸失配。另一方面,pow實在太浪費了,比特幣網絡每秒可完成數百萬億次SHA256計算,這些計算除了使得惡意攻擊者不能輕易打垮比特幣網絡外,好像并沒有更多的實際價值。當然相對于它所帶來的好處,這點浪費也許只是很小的代價。
但浪費總歸是不好的,有沒有辦法把挖礦設備和能耗這一環節去掉呢?畢竟這個過程只是要選出一個記賬的節點,有沒有其他方式可以實現呢?于是,人們提出了一些工作量證明的替代者,其中有一種就叫做POS。
權益認證是由Quantum Mechanic 2011年在比特幣論壇講座上提出來的,然后由PPC(點點幣)和NXT(未來幣)以不同的思路實現。POW就是根據計算能力隨機,POS根據擁有財產隨機。這就是這兩個共識機制的本質。但是,另一個問題是,POW是一個在比特幣出現之前就有了的東西,而因為比特幣的成功,POW基本上特指比特幣的POW。但相反,POS是個新東西,目前并沒有成熟的POS應用,所以,當提到POS的時候,并不是指某一個算法,而是一類,而且,這類算法目前各有優劣。并且,目前為止,沒有一個算法的可靠性通過了實踐的檢驗。所以,要對比POW和POS的優劣,我只能以POS這一大類為例。我們現在常說的POS,其實都在說PPCoin的POS,也就是最早的POS,那個東西是有根本缺陷的,例如幣齡攻擊(save-up attack),都僅僅是對PPC使用,而并不是POS的問題。
Quantum Mechanic提出POS概念的時候,說了下面這段話:
I'm wondering if as bitcoins become more widely distributed, whether a transition from a proof of work based system to a proof of stake one might hAppen. What I mean by proof of stake is that instead of your "vote" on the accepted transaction history being weighted by the share of computing resources you bring to the network, it's weighted by the number of bitcoins you can prove you own, using your private keys.
他的意思就是說,節點記賬權的獲得與節點持有的幣的數量,也就是權益有關。兩者成反比關系,持有幣數越多,獲得記賬權就越容易。這種決定由誰記賬的方式,去掉了POW中需要大量計算的過程,但是依然需要進行哈希運算來獲取記賬權。
在POW中,一個用戶可能會拿1000美元來購買礦機并加入到網絡中挖礦,從而得到獎勵,在POS中,用戶會拿1000美元來買等價的代幣,并把這些代幣當作押金放入POS機制中,這樣就有機會產生新區塊而得到獎勵。
簡單來說,就是這個系統中會存在一個持幣人的集合,他們把一定的代幣放pos機制中,于是他們就變成了驗證者,擁有了驗證交易和產生區塊的權利。然后pos算法就會在這個集合中隨機選取一個節點,給他權利產生下一個區塊。如果在一定時間里,這個節點沒有產生一個區塊,則選出第二個節點代替之。在這個過程中,被選中的概率和他們投入的代幣量有關,比如一個節點投入了10000代幣,那么他被選擇的概率,是投入1000代幣節點的10倍。
點點幣(PPC)
PPC是最先采用權益證明算法的數字資產,它在Quantum Mechanic提出的權益證明思想的基礎上,引入了幣齡的概念。幣齡是幣的數量和幣所擁有的天數的乘積。
簡單來說,就是一個根據你持有貨幣的量和時間,給你發利息的一個制度,在PPC的POS模式下,每個幣每天產生1幣齡,比如你持有100個幣,總共持有了30天,那么,此時你的幣齡就為3000,這個時候,如果你發現了一個POS區塊,你的幣齡就會被清空為0。你每被清空365幣齡,你將會從區塊中獲得0.05個幣的利息(假定利息可理解為年利率5%,點點幣PPCoin是1%年利率),那么在這個案例中,利息 = 3000 * 5% / 365 = 0.41個幣,這下就很有意思了,持幣有利息。
PPC其實是權益證明和工作量證明的一種結合體,因為它也需要挖礦。為了挖到區塊,點點幣的礦工也需要像比特幣礦工那樣去進行一個SHA256的解謎運算,只不過,這個解謎運算的難度會隨著他們想消耗多少幣齡而調整。當一些幣齡被消耗后,找到有效區塊會變得十分容易。這個運算解謎的效果主要是要保證,在兩個礦工嘗試消耗同樣大小幣齡的情況下,這個過程仍然是隨機的。
對于POS而言,除了PPC,還有其他不同形式的設計。在這些設計中,一定數量的幣被消耗用于使運算解謎變得極為簡單,這使得解謎運算不再是挖礦過程中最主要的挑戰。
POW和POS
兩者最直接的區別是,POW依賴算力,而POS依賴持有幣數。所以要想擁有記賬權,POW得買礦機,POS得買代幣。
工作量證明資源消耗大,可監管性差,共識機制強,需要全網算力共同參與效率低。優點也很明顯就是完全去中心化和節點自由進出。權益證明一定程度縮短了達成共識時間,但還是需要挖礦,只是不需要消耗大量的能源。兩種方案都沒有從本質上極大解決成本降低效率提升這個用戶痛點。只是優化方案,所以在這2種方式的邏輯里面做項目必然有被替代的情況出現。比如說更優化的方案,或是徹底解決痛點的新機制出現。
DPOS:Delegated Proof of Stake,委任權益證明
POW和POS雖然都能解決記賬一致性的共識問題,但是POW太依賴算力,一是浪費資源,一是某些礦池巨大的算力儼然成為了一個中心。而POS依據權益結余來選擇,會導致首富賬戶的權力更大,有可能支配記賬權。于是,又有人提出了DPOS算法。本質上來講,DPOS是對POS的一種改進,就像PPC是對POS的一種改進一樣,只不過PPC是一種具體的數字資產,而DPOS是一種思想。
比特股(BitShare)
BitShare是一種采用了DPOS機制的數字資產,它提出了見證人(也就是代理人,或者說代表)的概念,期望通過引入一個技術民主層來減少中心化的負面影響。類似董事會投票,持幣者投出一定數量的節點,進行代理驗證和記賬。
BitShare的DPOS工作原理是:每個持有比特股的節點都相當于一個股東,都有投票選出代表的權利,每個股東將其投票權授予一名代表。獲得票數最多的前N個(N通常是101)代表來生成區塊。當選成代理人需滿足,至少一半的股東參與了投票。
代理人的候選名單每個維護周期(1天)更新一次。代理人隨機排列,每個代理人按需有2秒的時間來生成區塊。如果在規定時間內不能生成區塊,則交由下一個時間片的代理人完成。
DPOS充分利用了持股人的投票,以公平公正的方式達成共識。他們選出的N個代理人,可以視為N個礦池,這N個礦池的權利是完全相等的。持股人可以隨時通過投票更換這些代理人,只要他們提供的算力不穩定,計算機宕機或者試圖作惡等。
DPOS的優點是可以大幅度縮小參與驗證和記賬節點的數量,可以達到秒級的共識驗證,但是缺點是整個共識機制還是依賴于代幣,而很多商業應用是不需要代幣的。
除了POW,POS,DPOS這三種主流共識機制外,實際區塊鏈應用中衍生出了許多變種機制。這些機制各有優劣,比如POW在安全性和公平性上比較有優勢,也依靠其先發優勢已經形成了成熟的挖礦產業鏈,但是其對能源的消耗令人詬病。新興的機制比如POS,DPOS等則更為環保和高效,但是在安全性和公平性方面比不上POW。