《迅雷链精品课》第十二课:PoW 共识算法
上一節課我們了解了常用的幾種共識算法,今天我們詳細地分析PoW(Proof-of-Work,工作量證明)共識算法,了解其來源和優缺點。
在學習課程的時候,你也可以領取BaaS平臺為期一個月的試用機會,免費使用高性能區塊鏈服務(點擊鏈接即可免費領取https://blockchain.xunlei.com/baas/try.html)。課程學習結合實踐操作,讓你迅速成為區塊鏈大牛!
*以下為第十二課的內容~
第十二課 PoW共識算法
1. 概述
PoW(Proof-of-Work,工作量證明)是比特幣采用的共識機制。由于比特幣在加密貨幣中的重要地位,PoW也成為后續加密貨幣系統的主流共識機制之一。
PoW是一種針對拒絕服務攻擊的應對方法,其要求客戶端執行某些需要消耗資源的運算,而其答案能被服務方快速驗算,以耗用的時間、設備與能源做為擔保成本,以確保服務無法被惡意節點所濫用。
2. PoW機制的來源
這個概念由Cynthia Dwork 和Moni Naor 1993年在學術論文《 Pricing via Processing, Or, Combatting Junk Mail, Advances in Cryptology》中首次提出;而“Proof of Work”一詞則是在1999年由Markus Jakobsson與Ari Juels發表的論文《Proofs of Work and Bread Pudding Protocols》中提出正式的定義;PoW技術最初在Hashcash中應用。Hashcash是Adam Back 在1997年提出的,作為一種遏制互聯網系統資源被濫用的措施,例如反垃圾電子郵件應用。
Hashcash要求郵件客戶端生成一個字符串,用SHA-1算法計算這個字符串得到的哈希值中,有特定數量的0前綴。SHA-1算法的碰撞非常困難,而且要求的哈希值的前綴0的數量越多,客戶端要找到符合條件的字符串需要的計算量就越大。在電子郵件的應用中,為了給發出的消息加上戳記,只需要向電子郵件添加頭部字段即可:用于電子郵件的每一個 To: 或 Cc: 接收者的 X-Hashcash 頭。例如,某個想給adam@cypherspace.org這個郵箱發送消息的人可能會在消息中包含一個X-Hashcash消息頭:
X-Hashcash:
1:20:1303030600:adam@cypherspace.org::McMybZIhxKXu57jd:ckvi
服務端可以通過檢查戳記的SHA-1散列來校驗它,如下所示:
00000b7c65ac70650eb8d4f034e86d7d5cd1852f
可見,哈希結果有5個前綴字符是0,每個字符占4個比特,因此這個哈希值的前20個比特為零,即前綴0的比特數量為20。
Hashcash的頭部格式為:1:bits📅resource:ext:salt:suffix,包括 7 個域:
版本號。
前綴為0的比特數量。若其哈希值的0前綴數量少于此數,那么它就是非法的。
生成戳記的日期。可以認為當前時間之后的戳記以及那些在很久以前的戳記是非法的。
戳記為哪個資源而生成。可能是一個電子郵件地址,但是也可能是一個 URI 或者其他命名的資源。
特定應用程序可能需要的擴展,通常為空。
隨機因子(salt)。用于將該戳記與其他人為相同的資源在同一日期生成的戳記區別開來。
后綴字符串。是算法真正起作用的部分。由于在特定的時間,A給B發郵件,前 6 個域就已經是固定的,為了生成一個通過期望數目的前導零進行散列的的戳記,客戶端必須嘗試很多連續的后綴值。
通過讓郵件客戶端做這樣的計算,能有效防止垃圾郵件的泛濫。生成一個 20比特0前綴哈希的字符串只需要幾秒鐘的時間,當你一天中只發送幾十封電子郵件時,這個代價并不大。但是,對那些想要發送數百萬消息的垃圾郵件制造者來說,這就是無法承受的消耗。
在比特幣出現之前,Hashcash的PoW算法也被Hal Finney以可重復使用的工作量證明(RPOW)的形式用于一種比特幣之前的加密貨幣實驗中。另外,Wei Dai的B-money、Nick Szabo的Bit-Gold這些數字貨幣的先行者,都是基于Hashcash的PoW機制下進行挖礦的。
3. 比特幣的PoW共識機制
比特幣網絡于2009年上線。比特幣網絡的PoW共識機制使用基于Hashcash的PoW來挖礦,挖礦節點發布自己的計算結果,由比特幣P2P網絡上的去中心化節點負責驗證。比特幣的PoW計算難度會被周期性的調整,以保證出塊時間的穩定。
3.1. 哈希函數的選擇
由于SHA-1已被證明不安全,比特幣采用了SHA-2系列的SHA-256算法作為哈希函數。使用SHA-256作為哈希函數時,無論輸入長度為多少,輸出總有一個固定的256位(32字節)長度。
由于PoW嚴重依賴于哈希算法,因此哈希算法的安全性至關重要。若使用了不安全的哈希算法,則惡意節點能付出遠小于其它誠實節點的計算量,就能找到符合要求的字符串,這樣惡意節點就可能承包所有的出塊,獲得所有的獎勵,并能隨意篡改數據。
理論上進行暴力破解SHA-1至少需要2的80次方(哈希循環的一個周期)才能碰撞破解。但是在2005年,中國密碼學家王小云院士提出哈希函數的碰撞攻擊理論,只用了2的69次方次就完成了SHA-1的循環碰撞周期。
不容忽視的是,SHA-1和SHA-2使用了相同的Merkle-Damgard引擎,這意味著對SHA-1的成功攻擊行為會影響到SHA-2的安全,即使還沒有宣布一個全輪回的SHA-2被成功攻破,但毫無疑問,攻擊機制正被私下的研發。這也是NIST贊助SHA-3競賽的一個原因,NIST感覺需要一個與之前算法不同的哈希算法。
NIST設置的篩選SHA-3的標準為:
l 候選散列函數必須好實現。它應該消耗最少的資源即使散列大量的消息文本。許多候選算法實際上無法達到這個要求。
l 候選算法在安全性方面必須是保守的。它應該抵御已知的攻擊,同時保持一個大的安全系數。它應該同SHA-2相同的四個散列大小(224bit、256bit、384bit或512bit),但如果需要能夠支持更長的散列位寬。
l 候選算法必須接受密碼分析。源代碼和分析結果公開為感興趣的第三方審查和評論。在分析過程中發現的任何缺陷都需要解決,通過調整或通過重新設計。
l 候選算法必須使代碼多樣性。它不能使用Merkle-Damgard引擎產生消息散列。
2012年10月2日,Keccak哈希算法被選為NIST散列函數競賽的勝利者。Keccak算法(讀作為“ket-chak”)是Guido Bertoni, Joan Daemen, Michael Peters, and Giles Van Assche的工作,在2008年10月被提交作為SHA-3的一個候選算法。
Keccak采用了創新的的“海綿引擎”散列消息文本,它抗碰撞性好、快速、設計簡單、方便硬件實現。Keccak已可以抵御最少復雜度為2的n次方的攻擊,其中N為散列的大小(比特位數),具有廣泛的安全界限。至目前為止,第三方密碼分析已經顯示出Keccak沒有嚴重的弱點。盡管如此,Keccak的創建者已經啟動Crunchy加密比賽,挑戰人們去發現和報告成功且可驗證的對Keccak的攻擊方法。
2015年, NIST 批準了SHA-3的標準草案,Keccak哈希算法正式成為SHA-3標準。根據wikipedia,SHA家族函數的比較情況如下:
圖1. SHA家族函數對比(資料來自wikipedia.org)
3.2. 比特幣的PoW
比特幣的PoW共識機制也常被稱為Nakamoto 共識或中本聰共識,以比特幣的發明者中本聰Satoshi Nakamoto命名。
比特幣用區塊頭部的其中6個字段作為工作量證明的輸入字符串。參與PoW計算的6個字段總大小為80字節,由4字節的版本號、32字節的上一個區塊的散列值、32字節的Merkle Root Hash、4字節的時間戳(當前時間)、4字節的當前難度值、4字節的隨機數組成,如下表所示:
表1. 參與哈希計算的區塊頭
比特幣的PoW,就是要求挖礦節點找到一個合適的 nonce, 即令nonce從0開始遞增,直到使得這區塊頭部經過2次SHA-256計算(即SHA256(SHA256(BlockHeader)))的哈希值小于當前區塊的目標閾值。比特幣的nonce是一個4字節的無符號整數,若嘗試完所有的4字節無符號整數還是沒找到符合要求的值,則可以修改time,或修改coinbase交易以改變mrkl_root,然后再重新尋找滿足條件的nonce值。
由于SHA-256的哈希值是256-bit的,因此目標閾值(target threshold)也是一個256-bit(32字節)的無符號整型,要求區塊頭的哈希值必須小于等于此值。
比特幣的難度值是動態調整的。每出2016個區塊就調整一次難度值,如果區塊產生的速率比10分鐘快則增加難度,比10分鐘慢則降低難度。調整公式如下:
難度值 = 舊難度值 * ( 過去2016個區塊花費時長 / 20160 分鐘 )
而使用這個難度值來計算目標閾值的計算公式為:
目標閾值 = 最大目標值 / 難度值
其中最大目標值為一個恒定值:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
根據上述公式可知,目標值的大小與難度值成反比。難度值越大,則目標值越小,即符合要求的哈希值的前綴0的數量越多,導致查找隨機數(nonce)的計算時間就越長。
比特幣將這個32字節長度的目標閾值通過類似科學計數法的方法將其壓縮為4字節的表示,結果即為區塊頭部的bits字段。比特幣規定,bits編碼由兩個部分組成:bits值的最高位的1個字節為冪(exponent),接下來3個字節為系數(coefficient),這樣,計算目標閾值的公式為:
Target = coefficient * 256^(exponent – 3)
3.3. 區塊頭實例解析
下面以比特幣的實際區塊為例說明區塊頭部組成和目標閾值的計算方法。我們可以在 https://www.blockchain.com/explorer,查看區塊數據,例如區塊高度為552020的頁面顯示如下:
圖2. 552020的區塊頭
在這個頁面可以看到區塊頭的全部字段,例如區塊生成時間是“2018-11-30 09:14:39”;區塊的bits值為388648495;nonce值為2211011375;區塊的hash值為:0000000000000000001a8fece3de933223b7464b8467c951b65a651b2155675e。通過 https://blockchain.info/rawblock接口可查看包含所有交易數據在內的區塊的全部內容:https://blockchain.info/rawblock/0000000000000000001a8fece3de933223b7464b8467c951b65a651b2155675e
其中區塊頭如下:
接下來我們可以算下這個區塊的目標閾值。從上圖可以看到,這個區塊的bits值為388648495,先將其轉換成16進制表示為:0x172A4E2F,如前所述,這個值包含兩個部分,最高位的1個字節為冪:exponent = 0x17
接下來3個字節為系數:coefficient = 0x2A4E2F
代入目標閾值的計算公式:
Target = coefficient * 256^(exponent – 3)= 0x2A4E2F * 256^(0x17– 3)= 0x2A4E2F0000000000000000000000000000000000000000
由于目標閾值是32字節的,這個值為23個字節,只要在高位補9個字節的0,即為目標閾值:0x0000000000000000002A4E2F0000000000000000000000000000000000000000
也就是說,552020這個區塊的哈希值要小于等于這個目標值。區塊的實際哈希值0x0000000000000000001a8fece3de933223b7464b8467c951b65a651b2155675e,是滿足條件的。而使哈希值滿足條件而找到的nonce值為2211011375。
3.4. 交易確認
比特幣系統在挖礦的過程中每10分鐘生成一個區塊,所有節點可以利用這10分鐘的時間,來完成接收,打包,見證的工作,同時將產生的交易在整個網絡里進行廣播。PoW要面對的一個問題是區塊分叉,為此比特幣規定每個交易需要至少有5個驗證過的區塊在其后面得到驗證才能算作確認,也就是說比特幣的共識機制認為等待6個確認的情況下,分叉切換的概率就足夠低了(例如按一個節點1%的算力來計算,6個區塊后被長度被趕超的概率是100的6次方分之1),因此,比特幣的交易確認時間在1小時以上。
4. 以太坊的PoW共識機制
4.1. Ethash算法
以太坊設計了ethash作為工作量證明算法,包括找到算法的隨機數輸入以使結果低于特定的難度閾值。它的特點是計算的效率不僅與CPU相關,還與內存大小和內存帶寬相關。該算法的一般流程如下:
首先根據塊信息計算一個種子。
使用這個種子,計算出一個16MB的cache數據。
通過cache,計算出一個1GB(初始大小)的數據集(DAG)。DAG可以理解為是一個完整的搜索空間,全客戶端和礦工需要存儲完整的DAG,挖礦過程中需要從DAG中重復的隨機抽取數據拿去和其他數據計算哈希值(類似于比特幣挖礦中查找合適Nonce)。
DAG中每個元素的生成只依賴于cache中的少量數據,驗證者可以從Cache快速計算DAG指定位置的元素,以執行哈希驗證。
每3000個區塊的DAG完全不同,并且它的大小也隨時間線性增長,從1G開始,每年大約增長7G左右。
由于僅根據cache就可以使用少量內存快速的計算出DAG中指定位置的數據,所以輕客戶端只需要存儲cache就可以高效的進行校驗。
參與哈希計算的區塊頭內容,以太坊和比特幣之間最主要的的區別是,以太坊區塊不僅包含交易列表也包含最近狀態(merkle patricia trie結構的根hash編碼在狀態中更精確)。除此之外,另外兩個值,區塊數和難度,也儲存在區塊中。
借助DAG結構,Ethash工作量證明是內存難解的,也就是需要大量的內存用于存儲數據,并且計算過程需要頻繁訪問內存,占用大量的內存帶寬,這使它能抵抗類似比特幣那樣的ASIC礦機 ,以支持礦工可以用電腦的CPU挖礦。但自從GPU礦工的效率高出兩個數量級,CPU挖礦就不再盈利了。
4.2. 交易確認
與比特幣類似,以太坊的交易同樣需要等待6區塊以確認交易。以太坊的難度調整的方式是每15秒整個網絡會產生一個區塊,這個"心跳"基本上主要強調系統狀態同步,保證不可能維持一個分叉(允許double spend)或被惡意分子重寫歷史,除非攻擊者有半數以上的網絡挖礦能力(即所謂的 51% 攻擊)。
5. 小結
目前業界普遍認為PoW是最適合公鏈的共識機制,優點是開放,任何人都可以參與進來;不需要任何權威機構的介入也能保證安全。
然而其缺點也同樣明顯,例如速度慢、能耗巨大、導致集中化的礦池等。而且從長遠來看,隨著技術的發展,依靠算力的機制也終會被算力打敗,PoW共識機制將變得不再安全,例如,有人可能會制造一臺量子計算機,算力可能比其他人快百億倍,能夠在一秒鐘內破壞比特幣或以太坊區塊鏈。因此,人們也有充足的理由和動力去研發其它的共識機制。
總結
以上是生活随笔為你收集整理的《迅雷链精品课》第十二课:PoW 共识算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 压缩导出 导入,EXP直接
- 下一篇: 三国人物共现网络