1. ethash 演算法
1.1 ethash
ethash是以太坊1.0中使用的pow(工作量證明)演算法,它是hashimoto演算法結合dagger之後產生的乙個變種。它的特點是計算的效率基本與cpu無關,卻和記憶體大小和記憶體頻寬正相關。因此通過共享記憶體的方式大規模部署的礦機晶元並不能在挖礦效率上有線性或者超線性的增長。
該演算法的一般流程如下:
1.2 記憶體難解
由於位元幣將hash演算法作為pow工作量證明的重要手段,後續的各種採用pow的數字貨幣也延續了這個設計,以sha256、md5(md5後來被證明不具備強碰撞性數字貨幣一般不用)為代表演算法。在設計之初都是算力敏感型,意味著計算資源是瓶頸,主頻越高的 cpu 進行 hash 的速度也越快。這個設計直接導致後來的礦機出現,採用asic晶元的礦機更是將這種運算能力成倍提公升,更多礦場的出現使得當時的位元幣面臨算力中心化的威脅。為了限制計算能力的依賴,人們開始尋求新的演算法,既然要限制cpu的能力,目光自然投向儲存依賴,也就是記憶體依賴。
hashimoto演算法採用io飽和的策略來對抗asic,使記憶體讀取成為採礦過程中的限制因素。
dagger演算法使用dag(directed acyclic graphs 有向無環圖)來同時實現記憶體難解和記憶體易驗證兩個特點。 主要原理是,計算每個nonce需要dag中的一小部分,採礦過程需要儲存完整的dag,禁止每次計算dag的相應子集,而驗證過程是允許的。
1.3 引數定義
word_bytes
4 word的位元組數
dataset_bytes_init
2**30 1gb
dataset的初始大小 |
dataset_bytes_growth
2**23 8mb
每個紀元dataset的增長量 |
cache_bytes_init
2**24 16mb
cache的初始大小 |
chche_bytes_growth
2**17 128kb
每個紀元cache的增長量 |
cache_multiplier
1024
size of the dag relative to the cache |
epoch_length
30000
每個epoch的塊數 |
mix_bytes
128
mix的寬度 |
hash_bytes
64 hash的長度 |
dataset_parents
256
每個資料集元素的parents數量 |
cache_rounds
3 計算cache時的輪數 |
accesses
64 hashimoto迴圈的次數 |
2 dag
dag是ethash演算法中需要頻繁訪問的資料集,這個為每個epoch生成的。dag要花很長時間生成,如果客戶端至少按照需要生成它,那麼在找到新epoch第乙個區塊之前,每個epoch過渡都要等待很長時間。然而,dag的生成只取決於區塊數量,所以可以預先計算出dag來避免在每個epoch過渡過長的等待時間。
dag的生成流程如下:
2.1 dag_size 和cache_size
每個epoch的dagsize和cachesize都不同,上面已經定義了創世時的初始值,以太坊還提供了乙個表來儲存接下來2048個紀元(大約20年)的各個值。詳見官網或原始碼cpp-ethereum/libethash/data_sizes.h.
獲取datasize 和cachesize的方法如下:
演算法中需要乙個seedhash,由下面程式生成,從程式可見每個epoch的seed是不變的。
使用seedhash計算cache。
最後使用cache計算dag,light引數中儲存的是cache資料.
2.5 dag檔案
dag每次生成都需要很長時間,因此生成時候需要存在檔案中,再使用mmap對映到記憶體中。dag檔案路徑一般如下
mac/linux : $home/.ethash/full-r–
是ethash演算法的版本號,在libethash/ethash.h 中revision定義。
是上面計算出來的seedhash
路徑下可能會有多個dag檔案,這取決於使用者或者客戶端是否刪除過時的dag檔案。
格式:dag檔案以8位元組的幻數開頭,值為0xfee1deadbaddcafe, 以小端格式寫入。接下來是小端格式寫入的dataset資料。
3 ethash實現
圖1 演算法流程圖
引數說明:
header_hash: 是當前塊頭部資料的hash值,在礦機呼叫get_ethwork時從任務引數中獲取。
nonce: 是每次計算ethash使用不同的數,不能重複。可以取時間戳或隨機數作為起始值,然後遞增。
對於礦工來說,如果result的值小於或等於target,那麼就完成了挖礦過程,將當前的nonce和mix_hash作為工作量證明提交工作;如果result的值大於target,那麼就需要改變nonce的值,再次呼叫ethash演算法.
ethash演算法程式如下:
從圖中看,每次ethash從dag隨機取64128=8192bytes, 以gtx1070顯示卡為例,頻寬為256gb/s, 那麼每秒能承受256102410241024/8192=33554432次ethash運算,即33mh/s的算力。可見,該演算法對記憶體頻寬的要求很高。
3.2 快速驗證
當驗證乙個工作提交是否有效時,速度很快。
下面是快速驗證程式:
ETH Pow演算法分析
1.ethash演算法 1.1 ethash ethash是以太坊1.0中使用的pow 工作量證明 演算法,它是hashimoto演算法結合dagger之後產生的乙個變種。它的特點是計算的效率基本與cpu無關,卻和記憶體大小和記憶體頻寬正相關。因此通過共享記憶體的方式大規模部署的礦機晶元並不能在挖礦...
演算法分析 演算法的漸進效率分析
一般用於界定函式集合的上界,漸進表示式o g n 的含義就是,c為正常數,函式集合o中的元素的最大值不會超過c.g n f n o g n 的含義是,函式f n 的屬於集合o g n 因為函式集合o中的最大值為c.g n 所以f n 的最大值為c.g n 由於只是漸進的上界,所以當函式g n 的階數...
演算法和演算法分析
一 演算法的基本概述 演算法是為了解決某類問題而規定的乙個有限長的操作序列。乙個演算法必須滿足以下五個重要特性 1 有窮性2 確定性3 可行性 4 有輸入5 有輸出 二 設計演算法的原則 1.正確性 2.可讀性 3 健壯性 4.高效率與低儲存量需求 三 演算法的時間複雜度簡介 語句頻度 語句重複執行...