18-ETH-挖礦算法

聲明:本文是要點筆記,介紹和系列筆記均收錄在專題:區塊鏈技術與應用

在之前的BTC篇中,介紹了比特幣系統中使用的挖礦算法。挖礦這一過程,雖然並沒有創造什麼實際價值,但挖礦本身維持了比特幣系統的穩定。總體來說,比特幣系統中的挖礦算法較爲成功,並未發現大的漏洞。

當然,比特幣系統的挖礦算法也存在一定問題,其中最爲突出的就是導致了挖礦設備的專業化,普通計算機用戶難以參與進去,導致了挖礦中心化的局面產生,而這與“去中心化”這一理念相違背。

因此,在比特幣之後包括以太坊在內的許多加密貨幣針對該缺陷進行改進,希圖做到 ASIC Resistance(抗拒ASIC 專用礦機)。由於 ASIC 芯片相對普通計算機來說,算力強但訪問內存性能差距不大,因此常用的方法爲Memory Hard Mining Puzzle,即增加對內存訪問的需求。

LiteCoin(萊特幣)

萊特幣曾一度成爲市值僅次於比特幣的第二大貨幣。其基本設計大體上和比特幣一致,但針對挖礦算法進行了修改。

萊特幣的 puzzle 基於 Scrypt。Scrypt 是一個對內存性能要求較高的哈希函數,之前多用於計算機安全密碼學領域。

萊特幣挖礦算法基本思想
1、設置一個很大的數組,按照順序填充僞隨機數(因爲哈希函數的輸出我們並不能提前預料,所以看上去就像是一大堆隨機的數據,因此稱其爲“僞隨機數”)。

Seed爲種子節點,通過Seed進行一些運算獲得第一個數,之後每個數字都是通過前一個位置的值取哈希得到的。可以看到,這樣的數組中取值存在前後依賴關係,如下圖所示。

2、在需要求解 Puzzle 的時候,按照僞隨機順序,如下圖所示,從數組中讀取一些數,每次讀取位置與前一個數相關。例如:第一次,從 A 位置讀取其中數據,根據 A 中數據計算獲得下一次讀取位置 B;第二次,從B 位置讀取其中數據,根據 B 中數據計算獲得下一次讀取位置 C;

分析
如果數組足夠大,對於挖礦礦工來說,必須保存該數組以便查詢,否則每次不僅計算位置,還要根據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數據生成方式與萊特幣中生成方式較爲類似:
1、通過Seed進行一些運算獲得第一個數,之後每個數字都是通過前一個位置的值取哈希獲得的。
2、不同之處:

  • 萊特幣:直接從數組中按照僞隨機順序讀取一些數據進行運算
  • 以太坊:先生成一個更大的數組(注:以太坊中這兩個數組大小並不固定,因爲考慮到計算機內存不斷增大,因此該兩個數組需要定期增大)。

3、大的DAG生成方式:大的數組中每個元素都是從小數組中按照僞隨機順序讀取一些元素,方法同萊特幣中相同。如第一次讀取 A 位置數據,對當前哈希值更新迭代算出下一次讀取位置 B,再進行哈希值更新迭代計算出 C 位置元素。如此來回迭代讀取 256 次,最終算出一個數作爲 DAG 中第一個元素,如此類推,DAG 中每個元素生成方式都依次類推,如下圖所示。

分析
輕節點只保存小的 cache,驗證時進行計算即可。但對於挖礦來說,如果這樣則大部分算力都花費在了通過 Cache 計算 DAG 上面,因此,其必須保存大的數組 DAG 以便於更快挖礦。

以太坊挖礦過程:
根據區塊 block header 和其中的 Nonce 值計算一個初始哈希,根據其映射到某個初始位置 A,讀取 A 位置的數及其相鄰的後一個位置 A' 上的數,根據該兩個數進行運算,算得下一個位置 B,讀取 B 和 B' 位置上的數,依次類推,迭代讀取 64 次,共讀取 128 個數,如下圖所示。

最後,計算出一個哈希值與挖礦難度目標閾值比較,若不符合就重新更換Nonce,重複以上操作直到最終計算哈希值符合難度要求或當前區塊已經被挖出。

僞代碼理解以太坊挖礦算法

通過 seed 計算 cache 僞代碼:

通過 cache 來生成 dataset 中第 i 個元素僞代碼:

通過不斷調用上圖的函數 calc_dataset_item 來依次生成 dataset 中全部 full_size 個元素:

下面是礦工挖礦函數和輕節點用於驗證的函數:

下面是礦工挖礦主循環函數:

下面是整體挖礦算法彙總:

目前以太坊挖礦以 GPU 爲主,可見其設計較爲成功,這與以太坊設計的挖礦算法(Ethash)所需要的大內存具有很大關係。

1G的大數組與128k相比,差距8000多倍,即使是16MB與128K相比,也大了一百多倍,可見對內存需求的差距很大(況且兩個數組大小是會不斷增長的)。

當然,以太坊實現 ASIC Resistance 除了挖礦算法設計之外,還存在另外一個原因,即其預期從工作量證明(POW)轉向權益證明(POS)

權益證明(POS: Proof of State)(現在以太坊已轉 POS)

權益證明:按照所佔權益投票進行共識達成,類似於股份制有限共識按照股份多少投票,權益證明不需要挖礦。

而這對於 ASIC 礦機廠商來說,就好比一把懸在頭上的達摩克利斯之劍。因爲 ASIC 芯片研發週期很長,成本很高,如果以太坊轉入權益證明,這些投入的研發費用將全部白費(ASIC礦機只能用於挖特定的加密貨幣)。

但實際上,以太坊目前仍然是 POW 挖礦共識機制。在設計之初,以太坊開發者就設想要從 POW 轉向 POS,併爲了防止有礦工不願意轉埋下了一顆“難度炸彈”。但截至目前,以太坊仍然基於 POW 共識機制。

其實很多時候,面對一些問題轉換思路就能得到很好的解決方案。如這裏,如果按照原本思想,通過不斷改進挖礦算法來達成 ASIC Resistance,無疑是比較難的。而這裏通過不停宣傳要轉向 POS 來不斷嚇阻礦工,使得礦工不敢擅自轉入 ASIC 挖礦,從而實現了ASIC Resistance。

預挖礦(Pre-Mining)

以太坊中採用的預挖礦的機制。這裏“預挖礦”並不挖礦,而是在開發以太坊時,給開發者預留了一部分貨幣。以太坊的早期開發者,目前就很有錢了。

而比特幣並未採用這一模式,所有比特幣都是通過挖礦產生的。但早期挖礦難度容易,所有中本聰本人本來就有很多幣(但沒花....)。

和 Pre-Mining 對應,還有 Pre-Sale,Pre-Sale指的是將預留的貨幣出售掉用於後續開發,類似於拉風投或衆籌。目前,各類加密貨幣很多,存在一部分貨幣就在採用Pre-Sale來獲取資金,如果此時買入,後續如果該貨幣取得成功,同樣可以獲得很大收益,但真正成功的貨幣只佔少數,這就是其風險性。

其他觀點

本篇中挖礦算法設計一直趨向於讓大衆參與,這一纔是公平的。且由於參與人員的分散,算力分散,也進一步使得系統更安全。

但同樣一件事物,從不同觀點看就有不同的看法。也有人認爲讓普通計算機參與挖礦是不安全的,像比特幣那樣,讓中心化礦池參與挖礦纔是安全的。爲什麼呢?

因爲要攻擊系統,需要購入大量只能進行特定貨幣挖礦的礦機通過算力進行強行51%攻擊,而攻擊成功後,必然導致該幣種的價值跳水,攻擊者投入的硬件成本將會全部打水漂。而如果讓通用計算機也參與挖礦,發動攻擊成本便大幅度降低,目前的大型互聯網公司,將其服務器聚集起來進行攻擊即可,而攻擊完成後這些服務器仍然可以轉而運行日常業務。因此,也有人認爲,在挖礦上面,ASIC礦機“一統天下”纔是最安全的方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章