挖礦這一過程,雖然並沒有創造什么實際價值,但挖礦本身維持了比特幣系統的穩定。總體來說,比特幣系統中的挖礦算法較為成功,並未發現大的漏洞。
當然,比特幣系統的挖礦算法也存在一定問題,其中最為突出的就是導致了挖礦設備的專業化,普通計算機用戶難以參與進去,導致了挖礦中心化的局面產生,而這與“去中心化”這一理念相違背。
因此,在比特幣之后包括以太坊在內的許多加密貨幣針對該缺陷進行改進,希圖做到ASIC Resistance(抗拒ASIC專用礦機)。由於ASIC芯片相對普通計算機來說,算力強但訪問內存性能差距不大,因此常用的方法為Memory Hard Mining Puzzle,即增加對內存訪問的需求。
LiteCoin(萊特幣)
萊特幣曾一度成為市值僅次於比特幣的第二大貨幣。其基本設計大體上和比特幣一致,但針對挖礦賽諾菲進行了修改。
萊特幣的puzzle基於Scrypt。Scrypt為一個對內存性能要求較高的哈希函數,之前多用於計算機安全密碼學領域。
萊特幣挖礦算法基本思想
設置一個很大的數組,按照順序填充偽隨機數。
因為哈希函數的輸出我們不能提前預料,所以看上去就像是一大堆隨機的數據,因此稱其為“偽隨機數”。
比如有一個Seed為種子節點,通過Seed進行一些運算獲得第一個數,之后每個數字都是通過前一個位置的值取哈希得到的。這樣填充的特點是:這樣的數組中取值存在前后依賴關系。
在需要求解Puzzle的時候,按照偽隨機順序,從數組中讀取一些數,每次讀取位置與前一個數相關。
例如:第一次,從A位置讀取其中數據,根據A中數據計算獲得下一次讀取位置B;第二次,從B位置讀取其中數據,根據B中數據計算獲得下一次讀取位置C;
如果數組足夠大,對於挖礦礦工來說,就是memory hard,必須保存該數組以便查詢,否則每次不僅計算位置,還要根據Seed計算整個數組數據,才能查詢到對應位置的數據,這對於礦工來說,挖礦計算復雜度大幅度上升。
當然,礦工可以選擇只保存一部分數據,例如:只保存奇數位置數據,偶數位置需要時再根據前一個奇數位置數據計算即可,從而對內存空間大小減少了一半(計算復雜度提高一點,但內存減少一半)。
核心思想:不能僅僅進行運算,增加其對內存的訪問,從而實現對ASIC芯片不友好。
這個IDEA有問題嗎?
看似蠻不錯的,使得ASIC礦機挖礦變得不友好,但該方法對Puzzle驗證並不是很友好,因為使得求解和驗證需要的內存區域是一樣大的。想要驗證該Puzzle,也需要存儲該數組,因此對於輕節點來說,並不友好(系統中絕大多數節點為輕節點)。
因此,萊特幣真正應用來說,數組大小不敢設置太大。例如:對於計算機而言,1G毫無壓力,而對於手機APP來說,1G占據空間就過大了。所以,實際中,萊特幣系統設計的數組大小僅僅128K大小。起初萊特幣發行時,不僅希望能夠抗拒ASIC,還希望能抗拒GPU。但實際中,后來慢慢出現了GPU挖礦,再后來,ASIC芯片挖礦也出現了。實際應用中,萊特幣的設計並未起到預期作用,也就是說,128k對於ASIC Resistance來說過小了。
萊特幣的這一設計是好事還是壞事?
從其並未起到預期作用來看,當然是一件壞事,但換個角度來思考,早期通過宣傳這一設計目標,有效吸引了大批礦工參與,解決了萊特幣“能啟動”問題,因此目前萊特幣仍然是一個較為主流的加密貨幣。
此外,萊特幣和比特幣另一區別為出塊時間,萊特幣為2.5min,為比特幣的1/4。除了這些不同外,這兩種貨幣基本一樣。
以太坊
以太坊的理念與萊特幣相同,都是Memory Hard Mining Puzzle,但具體設計上與萊特幣不同。
以太坊挖礦算法基本思想
以太坊中,設計了兩個數據集,一大一小。小的為16MB的cache,大的數據集為1G的dataset(DAG)。其關系為,1G的數據集是通過16MB數據集生成而來的。
思考:為何要設計一大一小兩個數據集?
為了便於進行驗證,輕節點保存16MB的Cache進行驗證即可,而礦工為了挖礦更快,減少重復計算則需要存儲1GB大小的大數據集。
數據集生成方式
16MB的小Cache數據生成方式與萊特幣中生成方式較為類似
- 通過Seed進行一些運算獲得第一個數,之后每個數字都是通過前一個位置的值取哈希獲得的。
- 與萊特幣的不同:
- 萊特幣:直接從數組中按照偽隨機順序讀取一些數據進行運算
- 以太坊:先生成一個更大的數組(注:以太坊中這兩個數組大小並不固定,因為考慮到計算機內存不斷增大,因此該兩個數組需要定期增大)
大的DAG生成方式:大的數組中每個元素都是從小數組中按照偽隨機順序讀取一些元素,來回迭代讀256次算出一個數,放入大數組中。
如第一次讀取A位置數據,對當前哈希值更新迭代算出下一次讀取位置B,再進行哈希值更新迭代計算出C位置元素。如此來回迭代讀取256次,最終算出一個數作為DAG中第一個元素,如此類推,DAG中每個元素生成方式都依次類推。
驗證
輕節點只保存小的cache,驗證時進行計算即可。
但對於挖礦來說,如果只保存小的cache,則大部分算力都花費在了通過Cache計算DAG上面,因此,其必須保存大的數組DAG以便於更快挖礦。
求解puzzle
求解puzzle的時候用的是DAG,cache是不用的,
根據區塊block header和其中的Nonce值計算一個初始哈希,根據其映射到某個初始位置A,讀取A位置的數及其相鄰的后一個位置A’上的數,根據該兩個數進行運算,算得下一個位置B,讀取B和B’位置上的數,依次類推,迭代讀取64次,共讀取128個數。
最后,計算出一個哈希值與挖礦難度目標閾值比較,若不符合就重新更換Nonce,重復以上操作直到最終計算哈希值符合難度要求或當前區塊已經被挖出。
偽代碼理解以太坊挖礦算法
匯總:
目前以太坊挖礦以GPU為主,可見其設計較為成功,這與以太坊設計的挖礦算法(Ethash)所需要的大內存具有很大關系。
1G的大數組與128k相比,差距8000多倍,即使是16MB與128K相比,也大了一百多倍,可見對內存需求的差距很大(況且兩個數組大小是會不斷增長的)。
當然,以太坊實現ASIC Resistance除了挖礦算法設計之外,還存在另外一個原因,即其預期從工作量證明(POW)轉向權益證明(POS)
權益證明(POS:Proof of State)
權益證明:按照所占權益投票進行共識達成,類似股份制有限共識按照股份多少投票,權益證明不需要挖礦。
而這對於ASIC礦機廠商來說,就好比一把懸在頭上的達摩克利斯之劍。因為ASIC芯片研發周期很長,成本很高,如果以太坊轉入權益證明,這些投入的研發費用將全部白費(ASIC礦機只能用於挖特定的加密貨幣)
但實際上,以太坊目前仍然是POW挖礦共識機制。在設計之初,以太坊開發者就設想要從POW轉向POS,並為了防止有礦工不願意轉埋下了一顆“難度炸彈”。但截至目前,以太坊仍然基於POW共識機制。
預挖礦(Pre-mining)
以太坊中采用的預挖礦的機制。這里“預挖礦”並不挖礦,而是在開發以太坊時,給開發者預留了一部分貨幣給開發者。以太坊的早期開發者,目前就很有錢了。
而比特幣並未采用這一模式,所有比特幣都是通過挖礦產生的。但早期挖礦難度容易,所有中本聰本人本來就有很多幣(但沒花)
和Pre-Mining對應,還有Pre-Sale,Pre-Sale指的是將預留的貨幣出售掉用於后續開發,類似於拉風投或眾籌。目前,各類加密貨幣很多,存在一部分貨幣就在采用Pre-Sale來獲取資金,如果此時買入,后續如果該貨幣取得成功,同樣可以獲得很大收益,但真正成功的貨幣只占少數,這就是其風險性。
以太坊的統計數據
-
以太坊中以太幣供應量(2018年)
有大約1億個以太幣,每個以太幣市值500多億美元餅狀圖中,藍色部分都是Pre-Mining產生的(接近3/4),可見掌握技術有多么重要。黑色部分為出塊獎勵產生的以太幣,綠色為叔父區塊產生的獎勵以太幣
-
最大的25個礦池挖礦算力比重(2018年)
-
以太幣價格變化情況(至2018年)
可見,2017年以太坊才開始大漲 -
以太幣市值變化情況(至2018年)
-
以太幣Hash Rate變化情況(至2018年)
指的是所有礦工加在一起每秒計算的哈希次數。如果不同的加密貨幣采用的mining puzzle不同,他們的Hash Rate就不能比較,以太坊和比特幣不能比較。
本篇中挖礦算法設計一直趨向於讓大眾參與,這一才是公平的。且由於參與人員的分散,算力分散,也進一步使得系統更安全。
但也有人認為讓普通計算機參與挖礦是不安全的,像比特幣那樣,讓中心化礦池參與挖礦才是安全的。為什么呢?
因為要攻擊系統,需要購入大量只能進行特定貨幣挖礦的礦機通過算力進行強行51%攻擊,而攻擊成功后,必然導致該幣種的價值下跌,攻擊者投入的硬件成本將會全部打水漂。而如果讓通用計算機也參與挖礦,發動攻擊成本便大幅度降低,目前的大型互聯網公司,將其服務器聚集起來進行攻擊即可,而攻擊完成后這些服務器仍然可以轉而運行日常業務。因此,也有人認為,在挖礦上面,ASIC礦機“一統天下”才是最安全的方式。