以太坊之六挖礦演算法

2021-10-02 16:50:45 字數 4568 閱讀 4542

6.1 scrypt演算法

pow本身是為了能讓記賬權能夠隨機分給各個節點而產生的,但是現在有人用了專用的asic晶元,而且迭代速度非常快,把挖礦當做一種職業已經普及開了,這已經違背了pow的初衷。中本聰用位元幣是當作一種去中心化的加密貨幣,可以理解為電子**的投資或者保值類產品。所以需要使用一種asic resistance的演算法,即抵抗asic。如果降低了對計算速度的要求,就要提公升對記憶體的要求,即memory hard mining puzzle。萊特幣使用的是scrypt演算法。

有乙個陣列x,先用乙個偽隨機數seed求完雜湊後放入x[0]中,再求x[i+1]=hash(x[i]),直至把整個陣列填滿了,這個陣列是個待查的表。實際使用的時候先找到a,通過對a求雜湊能夠找到b,再通過b的雜湊找到c,直至最後找到結果。如果不用這個表,b那個數值是多少就要從陣列頭開始求,c的時候再通過陣列頭找,效率就會很低,這樣就由時間的問題轉換到了空間問題。

有的礦工只儲存奇數字置的值,偶數字置的用奇數的算一步就行了。

scrypt演算法的缺點也是空間,輕節點在驗證的時候也需要維護這個陣列。如果是電腦維護1g的陣列還是挺簡單的,但是如果是手機開銷可就大了。不過萊特幣本身是沒有輕全節點的區分。

6.2 以太坊挖礦演算法ethash原理

以太坊中有兩個陣列,乙個是cache乙個是dataset(也叫dag),初始時cache有16m,dataset有1g。輕節點僅維護cache,全節點兩個都維護。兩個陣列每3萬個區塊增大一次,增大原來的1/128,也就是變為原來的一又一百二十八分之一,因為記憶體技術也是在逐漸增大中。

使用的時候先用乙個偽隨機的種子seed按照順序生成這個陣列,第0個數時seed的雜湊值,第1個數是第0個數的雜湊值,依此類推。生成cache的過程較為繁瑣,遍歷每個dataset的位置,用一種方法找到cache中對應的下標(這個方法是用dataset的下標對cache的元素個數取餘再進行異或,我也不知道為什麼異或,下面有寫),當然也就找到了對應的雜湊值,假設是a。接著用a找到b,再找到c,連續執行256次,就得到了dataset中的這個元素。

這個dataset怎麼用呢?用一種特別的方法遍歷這個dataset(這個方法我就不寫了,**有),遍歷的同時生成雜湊,最終遍歷完整個dataset後得到的雜湊就是結果,是要挖礦的時候驗證target啊,還是其它節點驗證結果啊,就都可以了。

6.3 以太坊挖礦演算法ethash原始碼

下面這個函式用於根據seed生成cache的偽**。每隔3萬個區塊會重新生成新的seed(新seed是對原來的seed求雜湊值),並根據新的seed生成新的cache。cache的初始大小為16m,每隔3萬個區塊重新生成時增大初始大小的1/128,即128k。每個節點的雜湊值是前乙個節點雜湊的結果,cache_size就是cache陣列的大小,seed就是偽隨機數種子。

def

mkcache

(cache_size, seed)

: o =

[hash

(seed)

]for i in

range(1

, cache_size)

:hash

(o[-1]

))return o

下面這個函式用於根據cache遍歷full_size生成dataset。full_size自然是dataset的陣列大小,cache就是cache陣列。這個dataset叫做dag,初始大小是1g,也是每隔3萬個塊更新,同時增大初始大小的1/128,即8m。

def

calc_dataset

(full_size, cache)

:return

[calc_dataset_item(cache,i)

for i in

range

(full_size)

]

下面這個函式用於遍歷dataset的每一位來生成dataset,cache就是整個cache陣列。(這句話是我抄的)先通過cache中的第i%cache_size個元素生成初始的mix,因為兩個不同的dataset元素可能對應同乙個cache中的元素,為了保證每個初始的mix都不同,注意到i也參與到了雜湊計算中。get_int_from_item()函式的作用是當前的雜湊值求出下乙個要讀取的位置。make_item()用剛剛的cache索引和雜湊值求出下乙個雜湊值。cache中的資料做256次雜湊,返回結果,這個結果可以存到dataset裡。

def

calc_dataset_item

(cache, i)

: cache_size = cache.size

mix =

hash

(cache[i % cache_size]

^ i)

for j in rage(

256)

: cache_index = get_int_from_item(mix)

mix = make_item(mix, cache[cache_index % cache_size]

)return

hash

(mix)

下面第乙個是全節點,第二個是輕節點的,返回雜湊值。全節點和輕節點的區別就是輕節點是不儲存dataset的,每個數值是現求的。輕節點是用來驗證nonce是否有效,全節點是用來挨個嘗試nonce。header是當前要生成的區塊的塊頭,nonce是嘗試的數字,full_size是dataset的大小,這個值3萬個區塊改一次,增加1g的1/128即8m。以太坊和位元幣一樣挖礦只用塊頭的資訊,因為這樣能夠實現輕節點僅用塊頭就可以驗證。我在看**的時候有點問題,for迴圈中mix的值被不停的修改,return的只能是最後乙個結果,那執行兩次make_item()還有什麼意義?第5行的mix也是第6行的引數,總之就是用一種既定的方式遍歷dataset,直至求出最終雜湊的結果。

def

hashimoto_full

(header, nonce, full_size, dataset)

mix =

hash

(header, nonce)

for i in

range(64

):dataset_index = get_int_from_item(mix)

% full_size

mix = make_item(mix, dataset[dataset_index]

) mix = make_item(mix, dataset[dataset_index +1]

)return

hash

(mix)

defhashimoto_light

(header, nonce, full_size, cache)

mix =

hash

(header, nonce)

for i in

range(64

):dataset_index = get_int_from_item(mix)

% full_size

mix = make_item(mix, calc_dataset_item(cache,dataset[dataset_index]))

mix = make_item(mix, calc_dataset_item(cache,dataset[dataset_index +1]

))return

hash

(mix)

下面的函式用於挖礦,尋找滿足target的節點。具體內容不用說了。

def

mine

(full_size, dataset, header, target)

: nonce = random.randint(0,

2**64)

while hashimoto_full(header, nonce, full_size, dataset)

> target

nonce =

(nonce +1)

%2**64

return nonce

6.4 asic resistance

以太坊為了實現asic resistance,打算把pow轉換為pos,即工作量轉換為權益證明,不過它們一直沒實現,實現的時間點一直在後推。因為asic晶元的研發週期大約1年,以太坊就不停的嚇唬礦機生產商:我們要做權益證明了哈,搞的礦機生產商不敢大幅度生產。事實證明很有效,以太坊中asic晶元確實不多,沒有位元幣那麼氾濫,可能也跟ethash有關。

到底要不要設計抵抗asic晶元的演算法呢?抵抗後,就越能讓通用裝置參加挖礦。以太坊和萊特幣是這麼做的。持正方態度的是因為參加挖礦的裝置越普通,參加挖礦的人越多,挖礦的結果越民主,區塊鏈越安全。反方覺得asic晶元使挖礦的成本大幅度提高,首先asic晶元的研發週期大約1年,能讓該晶元占有統治地位的時間也很短,而且專為某一種幣挖礦而設計的asic晶元還不能用於另一種幣。如果有人需要發動攻擊需要購買大量的asic礦機,攻擊後很可能會導致幣的**大幅**,這就是完全費力不討好的事。如果讓很多通用裝置能夠參與挖礦,像亞馬遜和阿里雲那種雲計算超級強的公司,它們在全球伺服器的數量可能已經夠攻擊幣了。雖然這些錢可能對那些公司來說不算什麼,但是如果他們覺得以太坊的某些記錄或者什麼資料威脅到了他們,他們完全可以集中算力乾掉以太坊,伺服器再繼續出租,大大降低了51%的成本。

19 以太坊中的挖礦演算法

對於基於區塊鏈證明的區塊鏈系統來說,挖礦是保障區塊鏈安全的重要手段,block chain is secured by mining。bug bounty 在美國電影裡面有賞金獵人 bounty hunter 這個是說懸賞去找挖礦bug。在位元幣的挖礦演算法是是安全的,但是在位元幣系統中存在必須使用...

以太坊2 0怎麼挖礦 看好以太坊2 0挖礦的潛力

我們先看看關於以太坊的幾個資料。1 截至6月6日,根據intotheblock資料顯示,目前持有以太幣的位址總數已經達到3996萬個,而位元幣的持有位址數為3010萬個,以太坊的持有位址總數已經超過位元幣。而且在持有以太坊的位址中,值得注意的是,持有超過32個以太幣的位址數一直在增長。這很有可能是因...

位元幣挖礦和以太坊挖礦對比

位元幣挖礦採用的是 工作量證明 機制 pow,proof of work 這種機制在加密貨幣領域被廣泛應用。礦工們 不停的工作 通過乙個名為雜湊 hash 的特殊數學方程式進行打包交易,將一筆筆交易以密碼學方式打包到區塊上來,獲得相應的挖礦獎勵。抽絲剝繭來看,其實就是要求每台礦機把乙個隨機的資料新增...