應(yīng)用型公鏈挖礦應(yīng)回歸到普適性時代
大家聽到“挖礦”這個詞應(yīng)該是從第一批比特幣淘金者那里聽到的。比特幣區(qū)塊鏈?zhǔn)秦泿判偷墓?,挖取的是“?shù)字黃金”。隨著共識面得擴(kuò)大,最初的礦工賺了大錢,后來的人們就像馬蜂一樣進(jìn)入到這里面來。這種比特幣挖礦潮很像當(dāng)年的淘金熱,當(dāng)時的淘金熱很多淘金者下海淘金,最終只有很少的人變得富有,很多人卻失去了一切。中本聰設(shè)計(jì)的比特幣網(wǎng)絡(luò)初衷是去中心化和普適性,但是隨著機(jī)器算力越來越集中,比特幣挖礦呈現(xiàn)出再中心性化的趨勢,出現(xiàn)“富者越富,貧者恒貧”的狀況,大量的普通用戶已經(jīng)很難參與進(jìn)來,這與現(xiàn)實(shí)社會里貴金屬開采有著驚人的相識,其他類似的貨幣型公鏈也存在這種現(xiàn)象。區(qū)塊鏈?zhǔn)侨祟惿鐣么a傳遞信任的重大變革,區(qū)塊鏈3.0時代一定是應(yīng)用的時代,大力發(fā)展應(yīng)用型公鏈?zhǔn)潜厝悔厔?,?yīng)用型公鏈挖礦必須回歸到普適性時代,讓更多用戶參與進(jìn)來。
挖礦到底是一件什么樣的事情
如果你想成為比特幣的礦工,你首先要加入到比特幣的網(wǎng)絡(luò)當(dāng)中與其他礦工進(jìn)行連接。在連接完成之后我們還有一些任務(wù)要完成:
1.監(jiān)聽交易廣播: 在整個比特幣網(wǎng)絡(luò)中每個時間段都有一些交易的廣播,然后需要驗(yàn)證礦工們的簽名是正當(dāng)有效的,交易沒有被重復(fù)支付。
2.維護(hù)區(qū)塊鏈的網(wǎng)絡(luò)并且負(fù)責(zé)監(jiān)聽新的區(qū)塊: 礦工的首要職責(zé)就是維護(hù)區(qū)塊鏈,為了保證這一點(diǎn),中本聰設(shè)計(jì)的非常完善,礦工在一開始就需要要求其他的礦工和節(jié)點(diǎn)把當(dāng)時你還沒有加入?yún)^(qū)塊鏈之前的歷史記錄同步到本地。然后監(jiān)聽那些被廣播到網(wǎng)絡(luò)上的新區(qū)塊,你的工作就是驗(yàn)證每個廣播后你所收到的每一個區(qū)塊,驗(yàn)證的目的是為了保證區(qū)塊里的每筆交易都是有效的。而且每一個區(qū)塊都包含了一個有效隨機(jī)數(shù)【1】。
3.生成備選區(qū)塊:如果你備份完畢了所有的區(qū)塊數(shù)據(jù),你就可以生成你自己的區(qū)塊了。但是你想要做到這一點(diǎn)你就要把所監(jiān)聽到的數(shù)據(jù)進(jìn)行打包并且放到新的區(qū)塊當(dāng)中,然后把這個區(qū)塊排在整條鏈的最新區(qū)塊的后面。但是你必須要保證里面的數(shù)據(jù)是真實(shí)有效的。
4.找到讓你的區(qū)塊變得有效的隨機(jī)數(shù)。這個工作量是巨大的,也是最難的一部分,這里取決于你的機(jī)器算力與全網(wǎng)算力的比例值。隨著全網(wǎng)算力的大幅提高,許多礦機(jī)被升級成算力更高的專業(yè)礦機(jī),并且為了提高比例值,專業(yè)礦機(jī)并聯(lián)形成大規(guī)模專業(yè)礦場。
5.讓全網(wǎng)接受你的區(qū)塊:即使你找到了一個隨機(jī)數(shù),也不能保證該區(qū)塊會成為共識鏈的一部分。其實(shí)這是有一部分運(yùn)氣成分在里面的。接受你的區(qū)塊并且從該區(qū)塊繼續(xù)傳承下去,而不是從其他礦工那里獲得的區(qū)塊開始傳承。
6.利潤:如果其他的礦工都接受了你的區(qū)塊,那你就可以獲得相對應(yīng)的比特幣了【2】。在這里補(bǔ)充一點(diǎn),除了新區(qū)塊產(chǎn)生的獎勵以外,還有一種費(fèi)用是額外收入的。但是比較低,那就是交易手續(xù)費(fèi),這里大約是一個區(qū)塊默認(rèn)獎勵的1%。
7. 尋找有效區(qū)塊:
現(xiàn)在我來解釋如何找到使區(qū)塊變得有效的隨機(jī)數(shù)。身為一名礦工,首先需要從你的交易池中選出一些有效的交易并且編譯成梅克爾樹。你可以任意選擇編譯的交易數(shù)量但是前提是不超過每個區(qū)塊的隨機(jī)數(shù)的交易上限。然后組裝出一個新的區(qū)塊【3】。你需要嘗試不同的臨時隨機(jī)數(shù)直到該隨機(jī)數(shù)能使整個區(qū)塊的哈希值小于目標(biāo)值。這個目標(biāo)值一般用零開始的特定位數(shù)的數(shù)值來體現(xiàn)。也就是從0開始,每次增加數(shù)值1,直到該隨機(jī)數(shù)能使區(qū)塊有效為止。
在很多情況下,隨機(jī)數(shù)試過所有的32位以后取的數(shù)值仍然不能產(chǎn)生一個有效的哈希值,這個時候就要做出更多的改變。但是當(dāng)在整個梅克爾樹上的數(shù)值發(fā)生變化的時候整個都會發(fā)生變化,最重要的是在梅克爾樹上不會改變coinbase,因?yàn)閏oinbase會向上傳遞所以改變這個值會計(jì)算更多,所以只改變頭部的隨機(jī)數(shù)是一個很好的選擇。在嘗試2^32次以后還沒有找到有效區(qū)塊才會改變coinbase。當(dāng)你找到這個數(shù)值以后就需要立刻宣布,你就有機(jī)會獲得區(qū)塊獎勵。
8 。決定難度:
當(dāng)?shù)V工挖出每2016個區(qū)塊,挖礦難度就會改變一次。這個難度的改變是根據(jù)前2016個區(qū)塊的挖礦效率來決定的。我們的公式如下進(jìn)行表示:
下一個區(qū)塊的難度=上一個難度*2016*10min/產(chǎn)生上2016個區(qū)塊所花費(fèi)的時間
注:2016*10min=兩周,這里的兩周是沒有意義的,只是權(quán)衡之下的產(chǎn)物而已。
中本聰為了要平衡這種動態(tài)值,因?yàn)樗驯忍貛抛鳛閿?shù)字黃金的存在。所以他決定把難度讓市場決定。挖礦難度會受到有多少新的礦工加入而產(chǎn)生影響,因?yàn)樾录尤氲牡V工是因?yàn)槭艿搅吮忍貛艃r格的波動而加入的。
挖礦之所以那么難的核心問題是因?yàn)榈V工要對SHA-256哈希函數(shù)進(jìn)行運(yùn)算,SHA-256是一個通用的密碼學(xué)哈希函數(shù),也是一個256位的狀態(tài)機(jī)。這256個狀態(tài)被分割成8個32位字段,這樣可以很優(yōu)化的運(yùn)行在32位的硬件上。每一輪運(yùn)算選擇一定數(shù)量的字段,最終進(jìn)行32位模加法運(yùn)算,然后運(yùn)算結(jié)果被一道狀態(tài)最左的第一個字段,這樣使得整個狀態(tài)進(jìn)行向右位置。
一個完整的SHA-256運(yùn)算要做64次這樣的迭代運(yùn)算,在每一輪運(yùn)算中,會志勇稍微不同的常數(shù),所以所有的迭代運(yùn)算都不一樣。礦工就是盡可能快的進(jìn)行這種函數(shù)運(yùn)算,礦工就是比運(yùn)算速度。
CPU挖礦
在當(dāng)初的時候,大家挖取比特幣都是使用家庭普通電腦進(jìn)行挖礦的,也就是CPU挖礦。按照現(xiàn)在比特幣網(wǎng)絡(luò)的情況還想指望CPU來進(jìn)行挖比特幣是根本不可能了,在過去幾年里面還執(zhí)著于用CPU挖類似比特幣(貨幣型公鏈)之類的的礦工是根本不知道比特幣的運(yùn)作原理。應(yīng)用型公鏈要回歸到普適性時代,CPU挖礦是重要的第一步,CPU挖礦能讓普通PC用戶更加方便地參與進(jìn)來。
GPU挖礦
第二代礦工用GPU挖礦的原因是因?yàn)镚PU有高吞吐量和高并行處理功能,這兩點(diǎn)是對于挖礦非常有利的條件。在2010年的時候OPENCL語言誕生了,這個語言可以讓GPU進(jìn)行非圖像處理工作,這個語言讓GPU挖礦成為了當(dāng)時的主流。GPU可以進(jìn)行超頻,舉個例子,如果超頻讓你的吞吐量變成1.5倍,運(yùn)算成功率降為0.7,但是乘機(jī)為1.05.也就意味著你獲得了5%的增幅。最后一條就是一個CPU可以帶多個GPU,讓每個GPU區(qū)分別負(fù)責(zé)不同的事情,大大縮短時間。
GPU挖礦也是優(yōu)缺點(diǎn)的。GPU有大量的浮點(diǎn)運(yùn)算單元,但是這些內(nèi)置硬件并不完全被用在挖礦這件事情上,對于SHA-256的運(yùn)算沒有起到任何幫助性作用。同時,GPU沒有很強(qiáng)大的散熱功能,而且很耗電。隨后出了幾個月的FPGA挖礦,但是由于要一支超頻使用就變得經(jīng)常報(bào)錯,導(dǎo)致人們不得已放棄這種挖礦方式。
GPU同時也是大型3D游戲、美工等家用及工作軟件所必需硬件,應(yīng)用型公鏈的普適性不排除GPU算力,但是應(yīng)限制GPU的無限拓展。
ASIC挖礦
當(dāng)今的挖礦市場主要被ASIC芯片所主導(dǎo)。這些芯片被設(shè)計(jì)出來就是為了貨幣型公鏈挖礦而存在的。制作這種芯片是需要非常專業(yè)的知識,開發(fā)周期也非常的長。但是最為奇妙的是,在這個行業(yè)里面芯片的開發(fā)速度居然打破了芯片行業(yè)的世界紀(jì)錄。由于當(dāng)時開發(fā)速度過快導(dǎo)致設(shè)計(jì)缺陷過多,造成了很多人的抱怨。
絕大部分早期的ASIC芯片壽命十分短暫,6個月就被淘汰了,這就導(dǎo)致了廠商的出貨速度決定了用戶的回報(bào)率,不然用戶買回家的就是一對廢銅爛鐵。由于現(xiàn)在比特幣的網(wǎng)絡(luò)已經(jīng)穩(wěn)定下來了,所以現(xiàn)在的礦機(jī)還是有比較高的穩(wěn)定性,但是在早期,礦機(jī)客戶控訴廠商的事情還是發(fā)生的很普遍的。
反ASIC
大致上說,我們想抑制為了挖礦而特別定制的設(shè)備的優(yōu)勢。這也可以理解為,設(shè)計(jì)一個解謎程序,讓現(xiàn)有的普通電腦成為最廉價和最有效率的解謎運(yùn)算設(shè)備。但這在現(xiàn)實(shí)中不可能,畢竟所有的通用電腦的中央處理器里已經(jīng)針對一些特殊目的進(jìn)行了優(yōu)化。并不是所有的電腦都有相同的優(yōu)化配置,并且它們隨著時代而變化。比如,過去的10年中,英特爾(Intel)和AMD在芯片里加入特殊指令(通常叫作“增加硬件支持”)來更加有效地計(jì)算高級加密標(biāo)準(zhǔn)(Advanced Encryption Standard,簡稱AES)的區(qū)塊密碼。所以有些電腦在挖礦這個事情上總是會比其他電腦更加低效。另外,很難想象設(shè)計(jì)一個挖礦解密程序,而這些程序是依賴普通個人電腦諸如音響或顯示器這些特性的,所以去除了那些通用特性的具體特殊目的的設(shè)備,很可能會更有效率,并且成本更低。
更加實(shí)際地說,我們有一個適中的目標(biāo):設(shè)計(jì)一個解謎程序,盡可能地減少最有效率的定制運(yùn)算設(shè)備與通用電腦之間的效率差距。ASIC還是會不可避免地成為更加有效的礦機(jī),但是我們可以將其運(yùn)算效能限制在一定范圍內(nèi),讓他的投入和損耗得不到合適的回報(bào),從而限制ASIC礦機(jī)的發(fā)展,讓普通用戶使用他們已有的通用電腦來挖礦仍具備一定的經(jīng)濟(jì)效應(yīng)。
1、剛性內(nèi)存解謎
大多數(shù)被設(shè)計(jì)成反ASIC的解謎程序中,最普遍被應(yīng)用的叫作剛性內(nèi)存解謎(memory-hard puzzles)-----解謎需要大量的內(nèi)存來計(jì)算,而不是靠大量的CPU時間。一個類似但又不一樣的概念是內(nèi)存限制解謎(memory-bound puzzles),花在讀取內(nèi)存上的時間,占據(jù)了這種程序大部分的計(jì)算時間。一個解謎可以是剛性內(nèi)存類而不是內(nèi)存限制類,或是內(nèi)存限制類而不是剛性內(nèi)存類,或是二者兼而有之。一個微妙但重要的區(qū)別在于,雖然CPU的速度是計(jì)算時間的瓶頸,但平行運(yùn)算大量解謎的成本,還是被內(nèi)存的成本所左右,或者反之亦然。通常對于運(yùn)算類的解謎程序,我們要做到剛性內(nèi)存和內(nèi)存限制,就需要保證在運(yùn)算過程中大量的內(nèi)存被要求使用,使之成為一個限制性因素。
為什么剛性內(nèi)存解謎或內(nèi)存限制解謎可以反ASIC?因?yàn)橛脕碛?jì)算哈希函數(shù)的邏輯運(yùn)算只占了CPU里的一小部分,意思是在比特幣的解謎計(jì)算里,ASIC不需要執(zhí)行一些不必要的功能,而只需要執(zhí)行計(jì)算哈希函數(shù)的相關(guān)功能,所以占了很大優(yōu)勢。另外一個相關(guān)因素是,不同的內(nèi)存性能上的差異(和單位性能的成本)比不同處理器之間運(yùn)算速度上的差異要小很多,所以,如果我們設(shè)計(jì)了一個剛性內(nèi)存類的解謎,計(jì)算時需要相對簡單的算力但需要大量的內(nèi)存,這就意味著,解密成本的上升速率將會像內(nèi)存成本提升速率那樣,在一個相對低一些的水平。
SHA-256已經(jīng)被認(rèn)定為不是剛性內(nèi)存解謎算法。它只需要一個小小的256位模塊,可以很容易地被放進(jìn)CPU的注冊機(jī)里。但設(shè)計(jì)一個剛性內(nèi)存類的工作量證明解謎不是一件太難的事。
2、Scrypt
現(xiàn)在最受歡迎的剛性內(nèi)存解謎叫作Scrypt,被第二大加密數(shù)字貨幣萊特幣以及其他加密數(shù)字貨幣所用。
Scrypt是一個剛性內(nèi)存的哈希函數(shù),最早是為了加密密碼而不容易被暴力破解(比如,反復(fù)試錯破解),所以挖礦解謎與比特幣用的“不完全哈希函數(shù)原像解謎”是一樣的,只不過用Scrypt取代了SHA-256。
Scrypt在比特幣被發(fā)明出來之前就已經(jīng)存在,而且它是用來加密個人密碼,這一點(diǎn)讓我們對它的安全性有一定信心。密碼的哈希函數(shù)化其實(shí)與反ASIC有著相似的目的。出于安全性考慮,我們期待,一個有著定制化設(shè)備的攻擊者不能夠比使用一般電腦或者服務(wù)器的用戶更快地計(jì)算密碼的函數(shù)值【4】。
Scrypt基本上有兩個步驟:第一個步驟是在用隨機(jī)數(shù)據(jù)填充隨機(jī)存取存儲器(Random Acess Memory,簡稱RAM)里面的緩存空間;第二個步驟是從這塊內(nèi)存區(qū)域里虛擬隨機(jī)地讀?。ɑ蛘吒拢?shù)據(jù),同時要求整個緩存都存儲在RAM里面【5】。
在時間和內(nèi)存之間的權(quán)衡。如果沒有一個較大的內(nèi)存緩存,計(jì)算Scrypt會變得很慢,但是用較少的內(nèi)存來增加相對較少的計(jì)算還是有可能的。假設(shè)我們使用一個大小約N/2的緩存(而不是N的大?。F(xiàn)在,我們只在j是偶數(shù)的情況儲存V【j】的值,丟掉那些j是奇數(shù)的值。而在第二次循環(huán)里,一半的情況下j為奇數(shù)的值將會被選到,但這種情況還是很容易被計(jì)算的。我們只需要簡單地計(jì)算SHA-256(V【j-1】),因?yàn)閂【j-1】在我們的緩存里。在一半的時間內(nèi)會產(chǎn)生這種情況,所以它增加了N/2個額外的SHA-256計(jì)算。
因此,對內(nèi)存要求量的減半只會增加1/4的SHA-256計(jì)算量(從2N到5N/2)??傮w來說,我們可儲存緩存區(qū)域V里的每個k排數(shù)據(jù),即使用N/k的內(nèi)存和計(jì)算(k+3)N/2次的SHA-256迭代計(jì)算。在這個限制下,如果我們設(shè)定k=N,我們就回到先前運(yùn)算時間為O(N的平方)的計(jì)算。這些數(shù)字不一定非常準(zhǔn)確地適用于Scrypt算法本身,但是漸進(jìn)預(yù)測的方式確實(shí)是適用的。
除此之外,還有其他的設(shè)計(jì)可以弱化用時間來換取內(nèi)存地能力。舉例來說,如果一個緩存持續(xù)地在第二次循環(huán)中被更新,它可以讓時間與內(nèi)存之間的互換不是那么有效,因?yàn)檫@些更新必須被儲存在內(nèi)存中。
Scrypt的檢驗(yàn)成本
Scrypt的另一個局限性是,它需要用與計(jì)算所用的同樣大小的內(nèi)存來做校驗(yàn)。為了讓內(nèi)存剛性有意義,N需要變得比較大。這意味著一個Scrypt的計(jì)算要比一個SHA-256的迭代計(jì)算(在比特幣里只需要一個SHA-256計(jì)算就可以校驗(yàn))昂貴許多倍。
這會產(chǎn)生負(fù)面的結(jié)果,因?yàn)樵诰W(wǎng)絡(luò)里的每個用戶必須重復(fù)這個計(jì)算來檢查每一個新發(fā)現(xiàn)的區(qū)塊是否有效。這會減緩新區(qū)塊傳播和被認(rèn)可的速度,從而增加了分叉攻擊的風(fēng)險。它還要求每個客戶端(即使是輕量級的SPV客戶端)擁有足夠的內(nèi)存來有效地進(jìn)行函數(shù)計(jì)算。這樣一來,實(shí)際上在加密數(shù)字貨幣中能夠被Scrypt用到的內(nèi)存N是有限的。
一直到最近我們都不明確,是否有可能設(shè)計(jì)一個挖礦解謎程序在計(jì)算上是剛性內(nèi)存類的,又可以很快地(不需要大量內(nèi)存)進(jìn)行校驗(yàn)。這個特性對密碼進(jìn)行哈希運(yùn)算沒有多大作用,在用于加密數(shù)字貨幣之前,這是Scrypt算法的主要用途。
在2014年,一個叫作杜鵑鳥周期的新解謎算法被約翰·特龍普(John Tromp)所提出(起這個名字是因?yàn)檫@個算法的特性與杜鵑鳥的特性類似,杜占雀巢)。杜鵑鳥周期算法,是從杜鵑鳥哈希表所衍生的一張圖中尋找周期的難度而設(shè)定的,杜鵑鳥哈希表這種數(shù)據(jù)結(jié)構(gòu)在2001年才被首次提出。除了建立起一個很大的哈希表之外,沒有其他已知的方法來計(jì)算這個周期,結(jié)果卻可以通過發(fā)現(xiàn)一個周期(相對小的)來簡單地驗(yàn)證。
這個算法可能會讓剛性內(nèi)存或是內(nèi)存限制類的證明工作在比特幣共識里變得更加實(shí)用??上У氖?,這個函數(shù)無法再數(shù)學(xué)上證明,如果它不用內(nèi)存的話就不能被有效地計(jì)算。通常,一個新的密碼學(xué)算法看起來都是安全的,但是社區(qū)會對它持有保留意見,直到它存在了多年而沒有被破解過。因?yàn)檫@個緣故,并且因?yàn)樗彩亲罱疟话l(fā)明的,當(dāng)前杜鵑鳥周期算法還沒有被任何加密數(shù)字貨幣所采用。
實(shí)際應(yīng)用中的Scrypt
Scrypt被許多種加密數(shù)字貨幣所使用,包括萊特幣在內(nèi)的幾種熱門幣,結(jié)果好壞參半【6】。針對萊特幣Scrypt算法參數(shù)的ASIC已經(jīng)存在(然后被其他幾種另類幣所復(fù)制)。令人驚訝的是,相較于大眾電腦,這些ASIC在算力上的提高比起SHA-256相對普通電腦的提高,至少旗鼓相當(dāng)甚至要更大!所以,Scrypt最終還是無法反ASIC,至少在萊特幣上是如此。萊特幣的設(shè)計(jì)者期初宣稱反ASIC是萊特幣的一大優(yōu)勢。但現(xiàn)在他們已經(jīng)收回了這個說法。
這可能是萊特幣所用的數(shù)值N(內(nèi)存使用參數(shù))比較低所造成的,它只要求128KB就可以進(jìn)行計(jì)算(如果使用時間內(nèi)存互換的模式,可能所需要的內(nèi)存更低,這也被普遍用于GPU以獲得更快地緩存)。低數(shù)值N使設(shè)計(jì)一個不需要復(fù)雜的內(nèi)存存儲總線的輕量級挖礦ASIC變得很容易,通常這種復(fù)雜的總線是讀取十億字節(jié)(Gigabytes)級別的隨機(jī)存取存儲起所需要的,而這些通用電腦都具備。萊特幣的開發(fā)者沒有選擇一個比較高的內(nèi)存參數(shù)(這會是ASIC更加難以設(shè)計(jì)),因?yàn)樗麄冋J(rèn)為高內(nèi)存參數(shù)所導(dǎo)致的高成本的校驗(yàn)過程是不太現(xiàn)實(shí)的。
3. 其他抵抗ASIC的方法
請回憶一下,我們的初衷是想讓可以大幅度提升計(jì)算性能的ASIC的開發(fā)變得困難。剛性內(nèi)存解謎只是其中一個方法,還有其他辦法。
另外被提出但還沒有被實(shí)施的一個辦法是使用一個移動的目標(biāo)值來作為挖礦解謎。也就是說,解謎算法本身就會變化,就像比特幣里的難度會周期性地改變一樣。在理想的狀態(tài)下,為上一個解謎算法而被優(yōu)化過的挖礦硬件,對下一個解謎算法不再適用。我們不是很清楚要多久改變一次解謎算法,才能達(dá)到我們需要的安全要求。如果這是由另類幣的開發(fā)者所決定的,這可能就變成了一種不可接受的中心化來源。比如,開發(fā)者可以根據(jù)他們已經(jīng)開發(fā)出來的一種硬件(或者只是優(yōu)化過的FPGA),去設(shè)計(jì)一個相對應(yīng)新的解謎算法,他們自然就有了針對這個新算法的早期優(yōu)勢。
或許這些解密算法的順序能夠被自動生成,但這看上去也很難。一個想法是選擇一大堆哈希函數(shù)(比如24個沒有被攻破的基于SHA-3的算法),然后每個用上6個月到一年,在這么短的周期里很難開發(fā)新的硬件。當(dāng)然如果這個順序安排被事先知道,相應(yīng)的硬件設(shè)計(jì)就可以按照函數(shù)使用的時間表來進(jìn)行。【7】
PC礦機(jī)從CPU挖礦過渡到CPU+GPU挖礦,同時限制GPU并行拓展及反ASIC芯片,在PC忙時和閑時用人工智能動態(tài)調(diào)節(jié)硬件及帶寬資源,將讓應(yīng)用型公鏈的普適性大大提高,進(jìn)入千家萬戶。