前言:一篇好文章的誕生,需要你不斷地搜集資料、整理思路,本站小編為你收集了豐富的區塊鏈技術優缺點主題范文,僅供參考,歡迎閱讀并收藏。
摘 要:介紹區塊鏈共識機制的基本功能,闡述工作量證明(Proof-of-Work,POW)和權益證明(Proof-of-Stake,POS)的基本原理,對比分析兩種共識機制的優缺點――POW機制簡單、安全,但浪費能源;POS機制環保、共識快,但其安全性缺乏嚴格的數學證明。
關鍵詞:區塊鏈;共識機制;POW;POS
一般而言,在介紹區塊鏈時都會提到兩個核心要點:一是分布式賬本,二是拜占庭將軍問題(Byzantine Generals Problem)。使用分布式賬本目的是讓每個節點都能夠驗證交易,而拜占庭將軍問題與賬本的一致性有關,即本文要討論的共識機制(consensus)。
區塊鏈上的共識機制主要解決由誰來記賬,以及如何維護賬本統一的問題,該問題的理論基礎是拜占庭容錯(Byzantine Fault Tolerant,BFT)。拜占庭容錯從20世紀80年代開始被研究,目前已經是一個被研究得比較透徹的理論,存在解的前提條件及具體實現都有現成算法。本文不打算從BFT說起,因為要分析的是區塊鏈共識機制的演進之路,而中本聰并沒有采用BFT,其實在筆者研究比特幣伊始,即便在理解了POW(Proof-of-Work,工作量證明方式)機制之后的很長一段時間,并不了解拜占庭將軍問題。下文在分析 HyperLedger Fabric的PBFT(Practical Byzantine Fault Tolerant)算法以及小蟻項目的DBFT算法時再全面闡述拜占庭將軍問題及傳統分布式一致性算法(PAXOS、RAFT)。
POW
其實“共識機制”一詞在這一兩年才被頻繁使用,以前一般叫證明方式(Proof),因為比特幣采用工作量證明方式(POW)。隨著大家對分布式賬本一致性問題的不斷探索,很多算法被提出來,尤其近期有很多項目回歸了對傳統BFT算法的改進,在算法思路上已經跳出了“證明”的語義,進一步高度概括為共識機制。筆者記得第一次碰到POW這一概念時感到很費解,對這種表述方式很頭疼,掌握了POW機理后才真正明白其本意為“通過工作以獲得指定成果,用成果來證明曾經付出的努力”。其實我們日常工作生活中經常使用POW,比如學生考試成績、畢業證、駕照等,這種證明方式的一個顯著特征是往往需要很大的工作量才能拿到指定成果,且這個成果很容易驗證。之所以如此是因為我們一般很難去實時監督一個人是否真的付出了這些工作量。
再回到比特幣的設計思路,中本聰已經使用非對稱密碼解決了電子貨幣的所有權問題,用區塊時間戳解決了交易的存在性問題,用分布式賬本解決了剔除第三方結構后交易的驗證問題,剩下需要解決的問題是雙重支付,這要求所有節點賬本統一,而真正的平等又必須賦予人人都有記賬的權利,記賬是一件簡單的事情,每個人都可以做,顯然最終會存在眾多大同小異的賬本,而其實我們只需要其中的一個賬本就夠了。
中本聰想到給記賬加入成本,總賬本由各個分頁按照時間先后排序,o每個賬本分頁設立一個評判標準,以區分賬本分頁是否合格,這給記賬增加了難度,同時給每個賬本分頁加入一個隨機元素,用以調節記賬難度以保證一定時間段內只有一個人生成合格的賬本分頁。增加的成本就是工作量,合格的賬本分頁就是工作量證明。對于比特幣而言,所謂的賬本分頁就是一個區塊,區塊通過巧妙設計形成區塊鏈,合格的區塊可以表述為
F(Nonce) < Target
其中Nonce是隨機元素,Target是合格區塊的量化,每個記賬節點的Target一致。Target根據過往一段時間內的平均區塊間距時間與預期間距時間的差異來自動調節。此外POW的成功運行還需要配合如下兩條約定。
(1)Best chain原則:將最長的鏈條視為正確的鏈條。
(2)激勵原則:找到合格的區塊有獎勵收益。
第(1)條約定為硬性規則,所有人必須無條件遵守,畢竟大家共同的目標是找到一致性賬本,而最長的鏈條代表最大的工作量。如果沒有這條約定,每個人都只會構造自己的區塊鏈,無法統一。第(2)條為工作量激勵,既然記賬有成本,那唯有收益才能驅動大家都去記賬,參與記賬構造區塊變成投資行為,其成本和收益風險在第(1)條約束下形成博弈,驅動所有節點按約定規則老老實實地夠造區塊,最終達到納什均衡。
具體實現方式是比特幣采用哈希(Hash)算法。邏輯上比特幣是對整個區塊進行哈希運算,但真正實現并非將整個區塊數據作為哈希函數的參數,區塊數據大體可以分為區塊頭和交易列表兩部分,如圖1所示。交易列表通過構造成Merkle樹最終濃縮成Merkleroot內置于區塊頭,區塊頭只有6個字段,共80字節。如此設計的好處是方便哈希運算,每次運算只需要80字節的參數輸入,而不是整個區塊輸入。
比特幣采用SHA256哈希運算,且每次都是連續進行兩次SHA256運算才能作為最終結果,前一次運算的結果作為后一次運算的輸入,即Double SHA256,一般簡稱SHA256D,擴展上面的公式,比特幣合格區塊判斷依據如上:
公式(1)的各項參數釋義如下。
nVersion:版本號,4字節。
hashPrevBlock:前一個區塊hash值,32字節。
hashMerkleRoot:包含進本區塊的所有交易構造的Merkle樹根,32字節。
nTime:Unix時間戳,4字節。
nBits:記錄本區塊難度,4字節。
nNonce:隨機數,4字節。
MAXTARGET:最大目標值,常量。
Diff:當前區塊難度,全網難度一致。
MAXTARGET/Diff即通常所說的當前目標值,可見難度Diff越大,當前目標值越小,找到一個合格區塊的概率就越小。
很顯然,POW的核心要義為算力越大,挖到塊的概率越大,維護區塊鏈安全的權重越大。相對其他共識機制而言,POW邏輯簡單,容易實現,容錯達50%,其安全有嚴格的數學論證。
POS
POW缺點也很明顯,其中被指責最多的主要有兩點,一是浪費能源,二是風險和收益博弈必然導致聯合挖礦,而大算力礦池可能會對系統的去中心化構成威脅。
于是在2011年,一個名為Quantum Mechanic的數字貨幣愛好者在Bitcointalk論壇提出Proof-of-Stake(POS)證明機制,該機制被充分討論之后證明具有可行性。如果說POW主要比拼算力,算力越大,挖到一個塊的概率越大,POS則是比拼余額,通俗說就是自己的手里的幣越多,挖到一個塊的概率越大。POS合格區塊的評判標準可以表述為
F(Timestamp) < Target × Balance (2)
與POW相比,公式(2)左邊的搜索空間由Nonce變為Timestamp,Nonce本質是無限的,而Timestamp極其有限,一個合格區塊的區塊時間必須在前一個區塊時間的規定范圍之內,時間太早或者太超前的區塊都不會被其他節點接納。公式(2)右邊的目標值引入一個乘積因子余額,可見余額越大,整體目標值(Target × Balance)越大,找到一個合格區塊的概率就越大。因為Timestamp有限,POS鍛造區塊成功率主要與Balance有關。
POS只是代表一種共識機制理念,具體有多種實現方式,下面重點解析兩種比較經典的實現思路。
Peercoin
Peercoin(點點幣,PPC)于2012年8月,最大創新是其采礦方式混合了POW及POS兩種方式,其中POW主要用于發行代幣,未來預計隨著挖礦難度上升,產量降低,系統安全主要由POS維護。目前區塊鏈中存在兩種類型的區塊,POW區塊和POS區塊。PPC的作者為同樣不愿意公開身份的密碼貨幣極客Sunny King,同時也是Primecoin的研發者。
要掌握Peercoin的POS機制,需要重點理解Sunny King專門為PPC設計的幾個核心概念:Coinstake,Kernel,Stake Modifier,Modifier Interval,StakeReward,Coinage等。
Coinstake
為了實現POS,Sunny King專門設計了一種特殊類型交易,叫Coinstake,Coinstake的設計借鑒于中本聰的Coinbase設計。本質上Coinbase和Coinsake都是一筆交易,只是對他們的輸入、輸出做了一些硬性限制,這樣才不會擾亂系統原有的POW機制。
(1)Coinbase結構要求:
(1)輸入數量必須等于1,且輸入的Prevout字段(指定前一筆交易的輸出)必須置空值。
(2)輸出數量必須大于等于1。
(2)CoinstakeY構要求(如圖2所示)。
(1)輸入數量大于等于1,且第一個輸入的Prevout字段不能為空,即要求Kernel必須存在。
(2)輸出數量大于等于2,且第一個輸出必須置空值。
這兩種特殊交易在區塊鏈中存放的位置也有特殊要求,中本聰規定每個區塊的第一筆交易必須放置Coinbase,反之,Coinbase不能出現在區塊的其他位置。Sunny King顯然不想破壞這個規則,他增加了一條規則,對于POS區塊,第二筆交易必須放置Coinstake,反之,Coinstake不能出現在其他地方。換言之,只要第二筆交易是Coinstake,那么這個區塊就當POS區塊來處理。
Coinbase和Coinstake都不應該被單獨廣播,而只存在于區塊中,因此客戶端節點一般都不允許進入內存池,當花費這兩種交易時,都需要檢測是否已經成熟。
Kernel Protocal
Coinstake的第一個輸入(Input 0)叫Kernel,Kernel在POS機制里確實起到核心作用,合格區塊的判定與之息息相關。合格區塊表述為
SHA256D(nStakeModifier + txPrev.block.-nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)< bnTarget × nCoinDayWeight (3)
公式(3)中的每一個參數都有明確的設計目的。
nStakeModifier:專門為POS設計的調節器,按照以上公式,如果沒有參數nStakeModifier,當一個人收到一筆幣之后,他立即就能提前計算得知自己在未來何時可以鍛造區塊,這顯然不符合設計目標,Sunny King希望POS礦工和POW礦工一樣做盲目探索,以實時在線維護區塊鏈,nStakeModifier的設計就是為了防止POS礦工提前計算。nStakeModifier可以理解為POS區塊的一個屬性,每一個區塊對應一個nStakeModifier值,但nStakeModifier并不是每個區塊都變動,不過協議規定每隔一定時間(modifier interval)必須重新計算一次,取值與前一個nStakeModifier以及最新區塊哈希值有關,因此POS礦工無法提前計算,因為他不知道未來的區塊哈希值。
也就是說,在PPC系統中,除了存在區塊鏈、幣鏈(幣的交易簽名歷史),還隱藏著一個很少被提及的鏈條――權益調節器鏈條。
值得一提的是,Sunny King是在PPC后來的版本才加入這個調節器的,一開始他使用nBits。
txPrev:Kernel對應的前一筆交易。
txPrev.block.nTime:txPrev所在區塊的時間戳,一筆交易被納入區塊的時間是交易發起者不能確定的,節點有可能通過提前計算預估到未來對自己有利的時間戳,這個參數就是為了防止節點利用這種預估優勢提前生成大批交易。
txPrev.offset:txPrev在區塊中的偏移量,用以降低網路節點同時生成Coinstake的概率。
txPrev.nTime:txPrev構造時間,設計目標如txPrev.offset。
txPrev.vout.n:Kernel在txPrev中的輸出下標,設計目標如txPrev.offset。
bnTarget:全網當前目標難度基準值,類似POW中的當前難度值,由nbits記錄。
nCoinDayWeight:Kernel消耗的幣齡,加入了一個時間權重。
從以上公式可以看出,Sunny King一方面希望能給所有POS礦工足夠的隨機性,另一方面,搜索空間始終控制在只局限于Coinstake的時間戳Time,影響找到合格區塊鏈最大的因素是Kernel消耗的幣齡。
節點在鍛造區塊時,首先從自己所有的UTXO中選定一個作為Kernel,構造Coinstake,計算hash,如果不合格,重新構造Coinstake,此時Time已經改變,也可以改變Kernel,以得到不同的Coinstake,如此往復,直到找到合格區塊。
Coinage
上面提到了幣齡,也叫幣天,假如1.5個幣存在于區塊鏈中10天,幣齡數值為
Coinage = 1.5×10 = 15
PPC采用幣齡,而不是直接采用余額(Balance)來計算。
stakeReward
權益激勵,俗稱獲得利息,計算公式為
stakeReward = Coinage × 33 / (365 ×33 + 8) ×0.01 ×COIN
公式(4)可簡化為
stakeReward = (0.01 ×Coinage / 365) × COIN
其中,Coinage即上文f的幣齡,COIN可理解為“幣”,1 COIN即通常所說的1個幣,本質是一個常量,中本聰在比特幣系統里定義為100 000 000,如此設計主要是為了避免浮點數運算,比特幣支持8位小數源于此。
由公式(4)、(5)可知,收益按輸入幣齡總和的1%年利率計算。