關於共識機制的討論已經有很多,但這些分析大多不全。在碳鏈價值舉辦的 “碳話” 線下沙龍第一期活動中,Conflux 研究總監楊光博士用一萬三千餘字,全面分析了 POW 與 POS 共識機制的原理,運行時遇到的問題,以及其中的優劣比較。

首先給大家簡單介紹一下我們的 Conflux 團隊:
我們團隊的核心是姚班的幾個同學以及師弟,並且有幸請到姚期智先生擔任我們的首席科學家和顧問。 來,是因為這個行業裡邊有很多非常重要也很複雜的新問題 – 以我最熟悉的密碼學和博弈論為例,區塊鏈面對的和要解決的很多問題已經是學術界最 這些問題不是單靠工程師就可以解決的,而是需要更多學術界的力量參與進來,大家一起合作才能推動整個區塊鏈行業往前發展得更好。
01 女巫攻擊與區塊鏈共識協議
我們先來回顧一下最典型的區塊鏈共識協議:大家把交易打包成塊,通過哈希引用把塊連接成一條鏈,就得到了一個共享的帳本 。但是直接這樣用一個帳本肯定是很不安全的,因為壞人也可以造一個帳本,然後把兩個帳本同時擺在你面前,那個是真的其中是假的,我們應該相信哪一個,這就變成一個問題。

如果是中心化的,當然這個問題非常好解決 – 我用支付寶,支付寶說我帳戶有多少錢,那就是多少錢。如果和事實無關的話,我有不同意見可以去法院告他。但如果是去中心化的,這件事就很難說了。去中心化的時候,大家沒有一個這樣一槌定音的機構,需要通過其他方式達成共識,才能有一個公正的帳本。那麼在去中心化的環境下,應該怎樣做共識呢?一個很容易想到的辦法就是我們投票,大家共同投票,投出來一個帳本,然後都相信這個就行。
但是,既然說到投票,那麼首先就有一個投票的公平性問題:投票權要怎麼分配?某種今天我們大家一起投票,然後我手上有一百票,在坐的各位每人一票,我們這個不叫投票,我有一百票,基本上我說什麼想投什麼,結果就是某種的。在線下投票權分配的問題其實比較容易解決:我們就簡單的一人一票即可。大家都有身份證,然後投票的時候登記一下就行了。但是線上的話,要想實現一人一票就非常困難。

首先,你在線上的環境中,特別是去中心化的環境中,如何定義 “什麼叫做一個人” ,這就是一個很大的問題。你是把一個帳戶當一個人還是一個 IP 當一個人,還是說你用別的什麼方法去確定?在網上的話,大家都是以匿名的方式存在的,你在聊天的時候,你甚至都無法判斷網路另一邊跟你聊天的到底是一個摳腳大漢還是一條狗。因此,我們就需要一個抗女巫攻擊的機制。
我們先簡單講一下什麼是女巫攻擊:它是說攻擊者可以校準地製造很多帳戶,然後控制這些帳戶一塊兒去行動,讓別人看起來以為人多勢眾的樣子。會見到有水軍引導輿論,再一些電影評分的網站也會有人專門去組織去在上面刷評論刷分。如果說有很多這種水軍馬甲的帳號在攻擊的話,你最後投票得到的結果就不是真實的。有可能有人通過這種方式投出非常多的票,最後投票的結果就是完全受這一個人控制的。
在傳統的網路環境下,我們有很多對抗女巫攻擊的方式,有所增加每個帳戶的註冊成本。大家在網上要註冊一個帳號的時候,常常需要輸入一個驗證碼,這件事就是計算機實現起來比較麻煩,即使能寫程式做也比較困難,但人去做的話就很簡單;還有的網站註冊的時候要求綁定一個手機號,或者檢測 IP 地址,這都是比較常見的抗女巫攻擊的方式。
但是在去中心化的環境下,以上那些方式就不好用了。因為去中心化的環境下,誰去發布這個驗證碼,誰去判斷驗證碼填得對不對?然後誰去驗證手機號?即使用 IP 地址的話,其實也是一個非常不公平的方式。因為我們知道並不是每個人都平等地所有權一個靜態的 IP 地址的。
所以在區塊鏈鏈中,我們實際上用到的解決方案最常見的就是一個工作量證明(PoW),一個是權益證明(PoS),另外包括代理的權益證明(DPoS)。還有一些其他的證明方式,某些說證明你擁有多少空間,或者證明你燃燒了多少貨幣,還有別的一些方法,但是目前最主要最常見的還是 PoW 和 PoS 這兩種。無論 PoW 還是 PoS 還是別的什麼 PoX,都是抗女巫攻擊的機制,是共識算法(協議)裡邊一個重要的組成部分,但它們本身不等價於共識算法。
02 工作量證明
接下來我先講一下大家都比較比較的工作量證明。
工作量證明的基本思想就是算力決定出塊權。如果你能解出一個 PoW 計算難題,你就可以出塊。粗糙的地面下,可以理解為一個 CPU 一票,或者一個 GPU,一台礦機的票,大概是這麼個意思。它的好處首先是這個系統是無許可的。參與者不需要任何人許可,只要有機器有算力就可以參與-理論上什至都不一定需要機器。如果說你可以手動算出一個區塊的哈希,並及時把這個上傳上去,別人也會承認這是一個合法的區塊鏈。還有一個是 PoW 投票行為本身成本是比較高的,不管用 CPU,這跟我們之前說的驗證碼,其實形式上有一點像,對吧?有一些驗證碼,人看了以後還是要花一點時間去識別裡邊的數字或者字母到底是什麼,然後才能打上去通過驗證。成功以後,除非是投票者本人也修改不了投票的內容。
按照工作量證明的一般邏輯,投票的時候需要先打包出一個塊,然後再對這個塊做工作量證明,如果做出來證明就相當於投出去一票,但是這個時候打包的塊已經沒有辦法修改了。例如我的礦機跑一天可以投出很多票,但是如果我想把之前一天的算力集中到新的一個塊上,這是辦不到的;替代,如果我想要回滾掉自己出的塊,我也必須付出和回滾別人的塊時候所需的同等的算力。這是 PoW 一個特別好的特點。
當然這個 PoW 機制去做共識算法也有一些缺點。最初這個缺點就是重複比較高,因為我們把交易打包到區塊鏈以後,這個區塊不是馬上就成為一個有效的替代區塊鏈,至少還要完成一個。在這裡,至少從打包好區塊鏈到做完區塊的工作所以說甚至比特幣不是等六個塊確認,或者看到一個塊就確認,確認一筆交易平均也要等十分鐘時間。PoW 機制另一個被人詬病的點就是通常特別高,不環保。對於這一點,工作量證明的狀況是否必要,我覺得是見仁見智的,可以持保留意見。量證明,那麼這個工作量怎麼也是沒辦法省掉的,如果省掉的話它就叫別的名了。

我們看一下如何解決基於 PoW 的共識的主要問題。
第一個是說確認速度慢。以比特幣為例,出一個塊平均要十分鐘,確認的話還要再等六個塊,就平均要一個小時。很清楚,比特幣在這點上已經被人批評好幾年了。然後第三點就是一直高不環保。但是第三點,既然我們要用 PoW,這點就是避免不了的,所以我們也就不想著去解決這個問題了。
對這兩個問題,確認速度慢和爆炸低。實際上這兩個問題看起來都有一個很簡單的解決方法 – 降低 PoW 問題的目標難度,提高出塊速度。實際上萊特幣就是這樣做的。它把目標缺陷從比特幣的 10 分鐘降到 2.5 分鐘,然後一下子出塊速度就比特幣快四倍。塊從 1M 先擴大到 8M,然後又擴大到 32M,甚至後來又不得不說要改到 128M。
是不是這麼簡單就可以解決比特幣確認速度慢和存儲量低的問題呢?當然不會。要真這麼簡單的話,比特幣也不會現在是十分鐘 1M 的設定了。為什麼剛才說的方法不能解決問題呢?因為當我們我們出塊速度快了以後,區塊鏈就會很容易地出現分叉,特別是當你出塊的速度超過廣播速度的時候,分叉的情況就會特別嚴重。
如果我們降低 PoW 問題的缺點,提高出塊速度,然後增加區塊容量,實際上在網路條件一定的情況下,肯定是會降低廣播速度的。因為區塊鏈,廣播得就越慢。然後如果說你出塊速度快但是廣播速度慢,則我在收到別人新出的一個塊之前,自己也能挖到一個塊,這樣的話就會出現分叉。大的話,分叉就會特別多。
分叉多了以後有什麼不好?最大的不好就是會降低安全性。在比特幣裡邊我們常說壞人攻擊需要51% 的算力。的話,好人有 49% 集中在上面,壞人有 51% 才能攻擊。但如果真的出現這種替代分叉的情況,比如說我在分叉 A 上有 30% 的算力,在分叉 B 上有 40% 的算力。這個時候壞人想把分叉 B 給回滾改到分叉 A,它不需要很多,它只需要 11% 算力就可以。所以如果真的簡單粗暴地去改比特幣的參數,最後安全性肯定會降低。
但是我認為這個安全性降低實際上不能怪 PoW。PoW 在這裡邊只是一個抗女巫攻擊的機制,而且它的難度是可以調的。不是 PoW 去背。為什麼會分叉多安全性低?其實是因為比特幣採用了連續鏈共識。在延長鏈機制下,如果出現分叉,誠實的算力很可能會跟著分叉,也就意味著誠實的人投票就會分叉,這樣的話壞人就更容易操縱最後的結果。
然後下一個問題:基於 PoW 的最長鏈共識為什麼會分叉?是不是說如果大家都是好人,就不會分叉?
這個也不是的。我們用圖裡邊每條線表示是一個計數器,向右的這個箭頭表示的時間。當這個計數器產生一個區塊的時候,它需要把區塊鏈廣播出去,但是廣播出去要消耗時間,所以會形成一個 “事件光錐”。新區塊鏈。除非只有在這個黃色區域及以後其他的表現才能看到你這邊產生的一個區塊鏈。既然有光錐,相應的也有光錐外的區域,也就是圖上綠色的部分。當一個例程處在這個光錐外區域的時候,他是不可能知道你這邊剛剛產生了一個區塊的,因為還沒有廣播過來。而是,如果網絡裡產生的下一個區塊鏈是在後邊黃色的這部分,那麼當然很安全,因為這個時候所有的斷路器都看到最新的區塊了,然後他們再生產區塊鏈都會跟在後面就不會出現分叉-如果大家都是好人的話。

但是如果說出塊的速度比較快,我在綠色的光錐外區域就產生區塊鏈,那就必然會出現分叉,然後最後會出現孤塊,對吧?不可能引用的。所以簡單的來估計一下,孤塊率基本上是等於光錐外這個區域的面積除以期望的出塊間隔的總面積。估計,綠色的光錐外區域面積所佔的比例越小,就表示出現孤塊的可能就越低。
但實際中我們肯定不會只有四個例程,我們例程會非常多,而例程多了以後,廣播的時間自然就會變長。廣播的時間變長,就意味著光錐外的區域面積會變大,我們的出塊間隔也需要變長,這樣才能確保孤塊會被控制在一個比較小的範圍以內。因為實際上孤塊本身也是對安全性有影響的,大約有 20% 的孤塊率的話,,只需要 41% 而不是 51% 的算力就可以完成攻擊了。因此,為了提高安全性,為了降低孤塊,我們必須拉長出塊的間隔。十分鐘當然不是完全不能改的,只是改過以後以後安全性肯定會受到一點影響。

拉長出塊間隔以後,整個系統的效率都會降低,特別是對爆炸造成的影響很大。 是大家在傳輸最終會加到共識裡邊的交易;還有一部分帶寬(紅色部分)是大家在傳輸一些不加入共識的數據,包括整個協議的開銷,還有一些可能是最終沒有被加入共識的作廢 如果說我們用 PoW 做抗女巫攻擊機制,再用長期鏈的協議去計算最後的共識的話,我們對利益的 善於其實是非常低的。
以比特幣為例,我們 600 秒產生 1MB 有效的區塊鏈,期望 600 秒才有 1MB 有效的這一塊,就算我這一個區塊再擴大一次,整個網路裡面 600 秒的時間,我有效利用的 存儲的訊息量可能還不到 20MB 吧?但現在網路的平均速度已經是 600 秒傳幾個 GB 了。所以它對整個網路帶寬的消耗也就在 1% 左右,浪費還是非常嚴重的。如果說我們用一些技術把廣播的速度變快,或者說用緻密區塊鏈的技術,那麼綠色的光錐外的區域這段時間就會變短。 但是,即使是這麼提高,只要我們是用連續鏈並且要控制孤塊率,可以浪費的卻仍然高不到哪兒去。
一般來說,一個公鏈網路可能會有幾千甚至上萬個節點,如果要廣播的話,平均可能要十次甚至更多次轉發。以需要十次轉發為例,從出塊的這個節點開始,發送給下一個節點,然後這個節點接受到區塊並且驗證過以後再發送給下一個節點,就這種過程要重複十次。在這十次轉發的全過程以內,如果我要降低孤塊率,就需要全網別的節點不要在這段時間內產生第二個區塊,或者說只有很低的概率產生第二個區塊。也就是說,這麼長的時間,大家其實只在廣播一個區塊。第一個人傳給第二個人以後,第二個人傳給第三個人的時候,第一個人就處於一個閒著的狀態了,對吧?所以最終的帶寬利用率自然不高。可能會比之前有一個常數倍的改進,但也是遠遠不可能把整個帶寬用滿的,能用到 1/10 就已經算很不錯了。
既然這樣的話,如果說我們想避免分叉,不可避免的帶寬就用不滿,帶寬用不滿的話,TPS 就不可能高到哪去。因為你一共同步的數據就那麼多,那它裡邊能放的交易就是有一個上限的——如果交易的尺寸不變的話(交易尺寸縮小也是可以提高 TPS 的,但是其他所有區塊鏈也可以用同樣的技術,相對的劣勢依然不變)
其實剛才要解決的問題,就是說出現分叉以後誠實算力不集中,會降低安全性。但這個解決方案並不是說只有降低分叉概率這一種方案去解決。比如我們也可以用基於 DAG 的有向無環圖去解決。

以太坊選擇分叉的時候用的不是最長鏈而是 GHOST 協議。其實以太坊用的是一個稍微修改過的版本,這個協議核心思想是遇到分叉時候選擇擁有最重子樹的分支而不是有最長子鏈的。這樣的話就不管你有沒有分叉,有多少分叉,安全性的問題都不大。因為即使是分叉的誠實的礦工,依然會對之前的選擇貢獻安全性。比如說礦工在靠後的一個區塊分叉,但是對於分叉之前的某個地方的分支應該如何選擇,礦工依然是貢獻安全性的。它會在應該選擇的分支的子樹上貢獻一個重量。
但是 GHOST 協議有一個缺點:雖然說它可以把帶寬用得比較充分,但同時浪費也很嚴重。因為那些最終沒有被確定在最重子樹那條鏈上的區塊,它們裡面的交易都是不算數的。大家挖到了一些區塊,但是最後都沒有加入共識,這些區塊的吞吐量就被浪費掉了。而我們的 Conflux 其實和GHOST 用了比較相似的方式去確定一條樞軸鏈,等確定好以後,我們再把所有的區塊排一個順序,這樣所有區塊裡邊的交易都會對整個系統的吞吐量作出貢獻。當然排過順序以後,還需要把裡邊有衝突的或者重複的交易去做一些處理,衝突的交易肯定不能都執行。如果我們從帶寬的角度去解釋的話, GHOST 這個協議可以把帶寬利用得非常好,但它整個系統的開銷比較大,因為傳輸過很多沒有被加入共識的區塊,會浪費掉一些帶寬。
Conflux 雖然說也會有一些重複的交易,但是因為它對整個帶寬的利用比較充分,而且在這個前提下,有效的帶寬利用率也遠比 GHOST 更高,所以就可以把整個系統的吞吐量提高。如果做對比的話,由於比特幣的總帶寬利用率特別低(~1%),所以即使它再怎麼降低協議開銷,吞吐量上跟 Conflux 的差距依然非常明顯。
這些是關於PoW的一些簡單的介紹,近期會再推出權益證明的相關專欄
Conflux 臉書專頁: https://lihi1.com/KPBED
Conflux 高中生區塊鏈寫作大賽:https://pse.is/3e6z6s
Conflux Line社群:https://lihi1.com/JF4Ak