給年輕人的第一個區塊鏈添加POW工作量證明

對POW不太熟悉的同學可以參考這篇文章:https://xiaozhuanlan.com/topic/0492176583

準備工作:

  1. 單向加密:單向加密以人類可讀的文本(明文)作為輸入,比如“666”這個字符串,再通過一個數學函數產生出難以辨認的輸出(密文)。

  2. 挖礦:比特幣的產出是通過給予“獲勝礦工”獎勵來實現,為了獲取比特幣獎勵礦工之間會進行競爭。這個過程之所以被稱為“挖礦”。

為什麼要挖礦?

相信同學們上篇文章已經按照步驟實現了基礎的區塊鏈功能,但是有沒有發現,很容易就生成一個區塊,如果是這樣的話,稀缺性就非常低,沒有什麼價值,所以我們需要添加生成區塊的難度,而且要隨著時間的推移,難度係數越來越高。這樣保證了一定的付出後才能獲取區塊,這個付出在這裡就是對一個數學問題求解,完成這個問題後才能獲取這個區塊。

挖礦挖的是什麼?

是求一個數學問題的解,需要先理解SHA-256算法也叫哈希算法,這個算法是把給定的文本經過函數計算後得出一個256位的文本,例如:“老鐵666” 經過計算後得出哈希值:

7bde6d3ea9a23cf15b0e01fd223649a9f9db10ea7b18150b04ce5dc18c191fcb

同學們可以試試,找個在線SHA-256加密的網站,同樣的文本,結果是一樣的。

看到這裡,有的同學就會思考:“一個哈希值是不是可以像身份證號,代表唯一的一個人?”沒錯,這就是它的特性之一,唯一性,還有一個特性是幾乎不可能逆向求解,誰能看出“7bde6d3ea9a23cf15b0e01fd223649a9f9db10ea7b18150b04ce5dc18c191fcb”這樣一個字符串是代表“老鐵666”

小總結一下:

  1. 哈希值具有唯一性

  2. 在給定明文和哈希值的前提下,可以很容易的驗證哈希值是否正確,只需按照同樣的SHA-256算法對明文重新求一下哈希值,然後比較兩個哈希值是否一致即可。

  3. 單獨給出一個哈希值,幾乎不可能推斷出它的明文,具有私密性

那我們要挖的其實就是這個哈希值,加上一定的條件,這個條件就是哈希值的前2位都是0,這時有同學會問了:“剛才不是說是唯一的嗎?‘老鐵666’怎麼讓它前2位是0啊”,是這樣 同學,在代碼中我們會添加一個隨機數和區塊的其它信息,再加上你的明文,一起去算一個哈希值,如果前兩位不是0,那就換個隨機數,其它信息不變,再算,直到算出來為止,這些你做的計算就是你的工作量證明,如下圖:

給年輕人的第一個區塊鏈添加POW工作量證明

然後我們刷新瀏覽器看到如下結果:

給年輕人的第一個區塊鏈添加POW工作量證明

這樣就生成一個有工作量證明的區塊。

代碼實現:

看到這裡,該碼代碼了,但是我們先思考一下,在上篇的基礎之上,我們需要添加哪些新功能:

  1. 一個變量,來控制哈希值前面幾位是0,也叫難度系統

  2. 一個函數:判斷是否是符合要求的哈希值

  3. 在原來的生成區塊函數中添加一個循環來計算

判斷是否是符合要求的哈希值

func isHashValid(hash string, difficulty int) bool {

prefix := strings.Repeat("0", difficulty)

return strings.HasPrefix(hash, prefix)

}

go語言中strings的Repeat方法非常方便

生成區塊函數改造:

func generateBlock(oldBlock Block, Content string) Block {

var newBlock Block

t := time.Now()

newBlock.Index = oldBlock.Index + 1

newBlock.Timestamp = t.String()

newBlock.Content = Content

newBlock.PrevHash = oldBlock.Hash

newBlock.Difficulty = difficulty

for i := 0; ; i++ {

hex := fmt.Sprintf("%x", i)

newBlock.Nonce = hex

if !isHashValid(calculateHash(newBlock), newBlock.Difficulty) {

fmt.Println(calculateHash(newBlock), " 繼續算!")

continue

} else {

fmt.Println(calculateHash(newBlock), " 中!")

newBlock.Hash = calculateHash(newBlock)

break

}

}

return newBlock

}

總結:

介紹了工作證明的原理,SHA256的特性唯一性,私密性,為我們的區塊鏈添加了工作量證明機制,下一篇會介紹如何生成多個節點的區塊鏈。

代碼在:https://github.com/sunqichao/blockchainPOW

參考:https://medium.com/@mycoralhealth/code-your-own-blockchain-in-less-than-200-lines-of-go-e296282bcffc


分享到:


相關文章: