聊聊容量證明(PoC)挖礦
最近有朋友私信詢問PoC挖礦的問題,使用PoC演算法的兩種幣BitcoinHD(BHD)和BurstCoin(BURST)也鋪天蓋地的在各種群中傳播,大有取代PoW的架勢。
相比PoW,PoC可以大大節約能源和計算資源,確實有可能成為未來的一種趨勢。
下面就讓我們來看看,這個PoC到底是怎麼回事兒。
什麼是容量證明(PoC)
PoC是Proof of Capacity的縮寫,翻譯成漢語就是容量證明。
顧名思義,就是通過儲存容量的多少來決定區塊生成權的演算法。
PoC並不是一個剛出現的概念,第一個應用PoC演算法的加密貨幣是BurstCoin。
BurstCoin早在2014年8月便釋出了,並一直存活至今。
最早的PoC演算法就是BurstCoin提出並實現的。
只是在2014年的熊市中,沒有得到足夠的關注。
2017年的狂熱中,又被一堆礦機廠商鼓吹的PoW所掩蓋,一直默默無聞。
PoC準確的說應該是一類演算法的統稱,就像PoW演算法有X16R、X11、Ethash等一樣。
目前出現的PoC演算法並不多,只有兩種加密貨幣在使用,並只有一種演算法實現,就是BurstCoin的PoC演算法。
容量證明的優點
傳統的PoW演算法通過把區塊的生成與晶片需要消耗電力這一物理規律繫結,無人可以逾越這個規律,成功的解決了區塊鏈的安全問題。
但是PoW也存在諸多缺點:
- 消耗大量能源
- 對挖礦裝置有較高要求。從最開始的CPU、GPU,慢慢演變到ASIC,需要專門生產和購買
以上的缺點不可避免的造成了PoW挖礦門檻逐漸提高。
擁有廉價電力的礦場和礦機廠商逐漸壟斷了挖礦市場,礦霸開始出現,並造成了諸多問題。
礦難時,大量ASIC裝置因為只能挖礦不能做其他用途而被廢棄,浪費資源,汙染環境。
BurstCoin的設計者把去中心化作為第一目標,力求人人可以參與,最終,他們成功地提出了一種PoC演算法。這個BurstCoin還真是低調,都沒給自己實現的PoC演算法起個名字。
為了不造成混淆,我們把BurstCoin的PoC實現稱為BurstCoin-PoC演算法。
BurstCoin-PoC演算法有如下特點:
- 儲存硬化,強制佔滿所有用來挖礦的儲存空間。
這意味著,提高挖礦效率最有效也是唯一可行的方法是增加用於挖礦的儲存容量。
- I/O不敏感,對儲存裝置的讀寫速度要求不高。
這意味著,並不需要RAID、SSD、甚至是記憶體等較為昂貴和特殊的儲存裝置,挖礦的門檻大大降低。
- 網路頻寬不敏感,挖礦的搜尋過程本身是離線的,僅接收、廣播交易和區塊時,才需要網路。
這意味著,不需要大量使用網路頻寬這種高度中心化的資源。
- 計算資源不敏感,一旦挖礦所需的資料生成完畢,實際挖礦過程中,幾乎不需要計算資源參與。
這意味著,挖礦不再需要強大的CPU、GPU,不再需要消耗大量能源。
結合這些特點,每臺計算機都有的機械硬碟成了挖礦的最佳選擇,這幾乎是人人都可以達到的,大大降低了挖礦的門檻,甚至,部分大容量的手機、平板電腦等裝置也可以參與挖礦,避免造成挖礦中心化。挖礦裝置為硬碟,即使遭遇礦難,也不再會像ASIC一樣,不能做任何其他用途,只能變成電子垃圾,汙染環境,浪費資源。硬碟的能耗遠低於其他計算型硬體,有利於節約能源。
PoC演算法的核心是將區塊的生成與儲存裝置的儲存密度不能無限提高這一物理規律相繫結,從而限制區塊的生成,保障區塊鏈的安全,最終使整個區塊鏈達成共識。
BurstCoin-PoC演算法的原理
在電腦科學中,一些經常需要用到的資料和中間結果,會被存下來,這就是快取。
快取是一種非常常見的做法,讓我們舉一個例子,假如我們要做如下的計算:
- 45 x 55
- 45 x 55 + 934
- 45 x 55 + 723
- 45 x 55 + 98
如果所有計算都正常執行的話,需要4次乘法和3次加法。
聰明的你一定發現了,45 x 55出現了四次,幹嘛每次都要重新算,只算一次,然後把結果記錄下來,下次再遇到,就直接用結果,不需要再次計算。
於是,完成同樣的工作,我們只需要1次乘法和3次加法。
不過,節約計算量也不是沒代價的,代價就是我們需要一塊兒空間,來儲存這個中間結果。
這種做法就叫 空間換時間 ,越是複雜的計算,快取就越能提高效能。
PoW演算法為了保證公平性,對每個區塊進行競爭時,求解的謎題都是全新的,完全沒有任何可以複用的中間結果。
BurstCoin-PoC同樣設計了一種很消耗計算資源的演算法,但與PoW不同的是,這個計算過程中,最複雜的部分是可以快取的,這就造成了消耗儲存空間進行快取的做法可以獲得巨大的優勢。
正如我們之前提到的,越是複雜的計算,消耗儲存空間進行快取的做法就可以獲得越大的優勢,也就更可以保證礦工選擇更大的儲存空間而不是更強的計算能力進行競爭。
但是,計算複雜度是不能無限提高的,因為,非礦工的使用者在校驗區塊的PoC結果時,是需要針對這個結果重新進行一遍計算的,我們不能要求一個不挖礦的使用者也配備大量儲存資源進行快取。
過高的計算複雜度會造成普通使用者校驗區塊速度很慢。因此,計算複雜度的高低需要一定的均衡,既不能太複雜造成校驗困難,也不能太簡單造成快取優勢不足,從而退化成PoW。
用足夠高的計算複雜度,人為造成空間換時間的巨大優勢 ,這就是BurstCoin-PoC演算法的原理。
BurstCoin-PoC演算法的實現
BurstCoin-PoC演算法的核心是一個雜湊函式:Shabal。
美國國家標準與技術研究院(NIST)在2007年舉辦了一個競賽,為制定下一代雜湊函式標準徵集方案,Shabal就是其中的候選方案。這個方案通過了第一輪的篩選,很遺憾,它沒有通過第二輪,無緣決賽。不過,Shabal依然是一個很好的雜湊演算法,至今也沒有發現明顯的安全弱點。
實際上,這次競賽中的很多演算法,雖然最終沒有獲勝,卻因為各自優秀的特性而被加密貨幣選中,PoW演算法X11中的11種雜湊演算法,很多就是出自這次競賽的候選方案。
下面就讓我們看看BurstCoin-PoC演算法具體是怎麼實現的。
BurstCoin-PoC需要生成大量的快取資料,這些快取被稱為 Plot 檔案。
第一步:選擇一個8位元組的隨機數 Nonce ,加上你的 Account ID 一起進行Shabal256計算,得到一個Hash結果。這個Account ID是從你的私鑰推倒出來的,可以用來標識你的身份,之所以要在計算中加上Account ID,是為了避免幾個人共用同一套快取資料來作弊,也增加了搜尋空間的範圍。雜湊結果被稱為Hash #8191,這不是錯誤,下面會解釋為什麼這麼命名。

然後,把第一步得到的Hash #8191新增到Account ID和Nonce前面,再進行一次Shabal256計算,得到Hash #8190。

以後的計算中,每次都把得到的Hash值新增到資料的前面,當資料的長度超過4096位元組後,每次只取最近的4096位元組資料進行雜湊。
比如計算Hash #7000的時候,其實只會取Hash #7001-7128這128個雜湊值進行計算。
因為每個雜湊值的長度是32位元組,128個正好是4096位元組。
當完成了8192次迴圈後,你會得到8192個雜湊值,用來計算雜湊值的資料也會變成這樣:

你需要對所有這些資料再進行一次Shabal256計算,得到一個Final Hash。
最後,把之前的8192個雜湊值逐個和Final Hash進行異或運算,得到的8192個異或後的雜湊值儲存下來,這些資料就是未來挖礦時需要搜尋的範圍。
這8192個雜湊值會兩兩一組,稱為一個Scoop,一個Scoop是挖礦使用的最小資料單位,一個Scoop是64位元組。

現在可以解答前面的問題了,其實Hash的編號是倒著來的,這就是為什麼第一次Hash運算的結果叫Hash #8191而不是Hash #0了。
對每個礦工來說,Account ID是固定的,上面生成的8192個Hash值其實只和Nonce有關,Nonce是8位元組的,取值範圍在0-18446744073709551615,這是個非常大的數字。
一個Nonce對應的資料量是32位元組*8192 = 256KB。
如果想儲存所有Nonce對應的資料,需要256KB x 18446744073709551615 = 4096ZB的空間,而人類目前所有資料加起來,據說不超過40ZB,事實上想預先存完所有Nonce的資料是不可能的。
礦工只會儘可能多地快取Nonce和對應的4096個Scoop來提高自己找到解的概率。
儲存的優化
記得之前我們說過的嗎?
BurstCoin-PoC還有一個設計要求,那就是對I/O要求要儘可能低。
降低I/O要求有兩種方法:
- 減少要讀取的資料量
- 優化資料排布,減少I/O次數
BurstCoin-PoC演算法採用了第一種方法。
事實上,BurstCoin-PoC進行搜尋的時候,只會搜尋所某個固定編號的Scoop。
假設某個礦工快取瞭如下的資料:

這張表格並不完整,只是為了說明問題,省略了很多Scoop,也只畫出了5個Nonce,真實的礦工會快取比這多得多的資料。
某個區塊挖掘時,選擇了Scoop2進行掃描,於是,礦工只需要掃描4096個Scoop中的一個即可,大大減少了需要讀取的資料量。
不要擔心礦工會刪除其他的Scoop,因為不同區塊會近乎隨機的選擇需要使用的Scoop,如果不儲存某個Scoop,就意味著他將不能參與需要這個Scoop的區塊的挖礦,成比例地降低了挖礦效率。如果他儲存的Nonce不夠多,那麼他能搜尋的範圍就會減小,也會成比例地影響他的挖礦效率。
我們來算一下,即使礦工使用目前單盤容量最大的硬碟,比如希捷酷狼14T。

14T硬碟實際可用12.7T左右,即使快取滿了資料,也只需要掃描12.7T x 1 / 4096=3100.5859MB的資料。
BurstCoin的區塊時間是4分鐘,只要硬碟可以在這4分鐘內完成掃描即可。
3100.5859MB / 240s = 12.91910792MB/s,只要硬碟的讀寫速度超過這個值即可,一般機械硬碟的讀寫速度都超過150MB/s。
BurstCoin-PoC幫礦工減少了每個區塊需要掃描的資料量,礦工們也很聰明,他們使用了第二種方法,減少I/O次數,進一步優化。
想象下,你去超市買東西,可樂和啤酒都放在同一個架子上,你只要跑一趟就都拿到了。
相反,尿布和啤酒可能離得非常遠,你就要跑兩趟了。
超市發現了很多人同時買了啤酒和尿布,於是把他們放在了同一個貨架上,大家又可以只跑一次就拿到兩件東西了,這就是超市對商品排布的優化。
與超市的例子非常類似,對機械硬碟來說,資料是儲存在碟片上的不同位置的,如果資料儲存的位置離得很近,就可以在一次I/O中完成讀取。
讓我們看個例子吧:
Plot檔案剛剛生成的時候,是按Nonce儲存的,相同Nonce的不同編號的Scoop儲存在一起。
相同顏色代表儲存在靠近的位置,不同顏色代表儲存的位置相隔較遠。

但是,挖礦時是按Scoop來進行掃描的,如果這樣排列,我們掃描0-5六個Nonce的Scoop2需要6個I/O。
這會大大影響掃描的效率,也會影響硬碟的壽命。
於是,聰明的礦工會在Plot檔案生成後,對資料進行一個重排,就像下面這樣:

把Nonce拆散,相同的Scoop放在一起,這樣的話,訪問一個Scoop就只需要一次I/O啦,是不是很機智?
事實上,在這兩種優化的作用下,絕大多數硬碟只需要不到30秒就可以掃描完所有的資料,幾乎不會對計算機的正常使用造成影響,真正做到挖礦和正常使用兩不耽誤。你可以一邊玩著遊戲,一邊挖著礦,美美的。
不知不覺這篇文章已經這麼長了。
BurstCoin-PoC也並不是毫無弱點的,它也在不斷的改進。
BurstCoin的區塊是如何生成的,挖礦的具體流程是什麼?
PoC演算法需要消耗大量的儲存空間來儲存一些只能用來挖礦的資料,想必有人又要大呼浪費空間了,PoC演算法是不是可以存一些有意義的資料呢?
這些都先挖個坑吧,過幾天我們再來更新。
感興趣的小夥伴,關注起來吧。
我是李明陽,用通俗易懂的語言講區塊鏈知識。