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