這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
第四期 簡介go語言下挖礦難度的代碼實現(3)
卡酷少
Wechat:13260325501
經過之前所有的鋪墊,這一期我們將對難度的代碼實現作出簡單示範。(以下是在不考慮近期各機構對於區Block Storage資訊改進的情況下。對於區塊資訊的調整,有比如“隔離驗證”等方法。暫時不瞭解沒有關係,本期並不涉及這點。之後隨著學習的深入,我們會一一介紹給大家。)
本期我們將對上期圖二中幾項資訊給出樣本,然後代碼類比難度的實現。
區塊裡的雜湊是如何產生的?
- 如第四期(1)篇裡講到的,每個區塊裡包含了index,current hash,previous hash,timestamp,data,nounce等資訊。current hash,就是將剩下的其他資訊拼接成字串,然後將這個字串進行雜湊的結果。正如上一個區塊的當前雜湊也是由它之前的區塊的這些資訊雜湊產生的。
- 其中,nounce作為電腦窮舉的隨機數,不斷變化,形成字串的變化,產生了不同的雜湊值。這個雜湊值不斷去匹配現階段的雜湊難度。當nounce值取到某數,並使之形成的雜湊值匹配上了當前的有效雜湊難度,雜湊碰撞就成功了。
- 以下為代碼實現
雜湊sha256
/*代碼邏輯: 第一步:匯入crypto/sha256庫 第二步:聲明字串 第三步:sha256.New()建立一個對象 第四步:將字串轉換為位元組數組 第五步:使用對象調用write方法 第六步:first.Sum(nil) 返回hash值*/package mainimport ( //第1步 "crypto/sha256" "fmt" "bytes")func main() { //第2步 const input1 = "199778A - > B 100" //第3步 first := sha256.New() //第4步 //第5步 first.Write([]byte(input1)) //第6步 fmt.Printf("%x\n", first.Sum(nil)) const input2 = "Hello" second := sha256.New() second.Write([]byte(input2)) fmt.Printf("%x\n", second.Sum(nil)) //輸出兩個雜湊是否相等,bytes.Equal() fmt.Println(bytes.Equal(first.Sum(nil), second.Sum(nil)))}
0000e1343c8d9ec8a8996f0c1c8d1f9f1d954a750c3db5525205f401c516222d185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969falseProcess finished with exit code 0
- 其中一些函數大家一定急於瞭解,但這些函數的封裝過於艱深,我們在此不作深究。主要的是大家要記住四個關鍵步驟3,4,5,6,並熟練使用。其中包括以下幾點:
- ==sha256.New()== 有傳回值,需要聲明變數並接收。且它的傳回值一個是雜湊對象,而且是一個指標對象。它可以調用一些方法,其中有write方法。——第3步
- 雜湊對象調用 ==obj.Write()== 方法是需要傳參,且參數類型為位元組數組。所以涉及到要將雜湊的字串先轉化為 ==[ ]byte== 類型——第4步第5步
- 雜湊對象調用 ==first.Sum(nil)== 方法返回雜湊值,方法有參數且參數固定為==nil==;可以聲明變數接收或者直接輸出。——第6步
關於雜湊難度的判斷
- 要寫出挖礦難度的完整代碼,其中有一環節必須要解決。那就是如何判斷雜湊難度是否是有效呢?下面我們先給出代碼
/*代碼邏輯:(我們將代碼) 第一步:聲明一個隨機取的雜湊值,來在之後測驗isValidDifficulty是否有效 第二步:設定當前雜湊難度,difficulty 第三步:寫入一個迴圈來迭代匹配雜湊值對應位置的值,查看是否這個位置是否是雜湊難度要求的值 第四步:列印對這個雜湊值的判斷*/package mainimport "fmt"func main() { h := "0000e1343c8d9ec8a8996f0c1c8d1f9f1d954a750c3db5525205f401c516222d" //h1 := "0033e1343c8d9ec8a8996f0c1c8d1f9f1d954a750c3db5525205f401c516222d" //h2 := "0003e1343c8d9ec8a8996f0c1c8d1f9f1d954a750c3db5525205f401c516222d" difficulty := 4 var i int for i = 0; i < len(h); i++ { if h[i] != '0' { break } } fmt.Print( i >= difficulty)}
trueProcess finished with exit code 0
falseProcess finished with exit code 0
falseProcess finished with exit code 0
- 於是我們將代碼封裝一下,使它看起來更清晰,更便於調用。
package mainimport "fmt"func main() { h := "0000e1343c8d9ec8a8996f0c1c8d1f9f1d954a750c3db5525205f401c516222d" fmt.Println(isValidHashDifficulty(h, 4))}func isValidHashDifficulty(h string, difficulty int) bool { b := len(h) // 64 var i int for i = 0; i < b; i++ { if h[i] != '0' { break } } return i >= difficulty}