【區塊鏈技術基本原理1】比特幣挖礦--工作量證明機制的底層原理

說點閑話

算了下,我大概有10天沒有在幣乎更文了,那這些天,我干什么去了?我覺得有必要跟大家聊聊。暫時離開幣乎,不是因為我偷懶,不想寫文章了,而是我想冷靜下來,把自己學習區塊鏈這2,3個月以來腦子里混亂的東西給理清楚。我想知道自己為什么要寫文章?我學習區塊鏈的目的是什么?我能夠堅持多久?事實上,我不是一個喜歡隨大流的人,所以我不會見到別人日更就去日更,我更不想為了寫作而寫作。好了,現在這幾個問題,我都找到了我自己的答案,所以我回來繼續寫作了。關于那幾個問題的答案,就暫時不細說了,我想說說我這些天干了什么。我去深入了解了幾個我看好的項目,包括eos,gxs,qtum,btm;我還去體驗了幾個平臺,包括,candy.one、pressone、iVeryOne、ONT。我還去把曾經學習過的區塊鏈的書翻過來重新看看,去學習了GO語言的編程(很多區塊鏈項目開發會使用)。

你所知道的工作量證明機制

說的稍微有點多了,現在正式進入到今天的話題比特幣挖礦--工作量證明機制的底層原理到底是什么樣的?說到挖礦POW工作量證明機制,我相信有不少朋友都會知道一些,比如,比特幣每10分鐘會產生一個區塊;礦工是根據解答一道系統給出的難題來獲得記賬的權利的,算力越高,獲得記賬權利的機會就越大。而我今天主要是想跟大家詳細分析一下礦工們是如何競爭記賬的,也就是說如何競爭解決這道難題的,以及這個經常被我們提及的區塊(block)到底是什么樣的?

我們都知道比特幣的區塊的產生是通過POW(Proof Of Work)工作量證明機制來完成的,整個網絡平均10分鐘就會產生一個區塊,而且伴隨著區塊的產生,系統會獎勵一定數量的比特幣給在這個區塊上記賬的礦工。說道這里,請大家思考2個問題。

  • 問題一:系統獎勵的比特幣的數量是多少?是恒定不變的嗎?
    比特幣的創世區塊是在2008年,由中本聰挖出的,按照比特幣白皮書的規定,每挖出一個區塊,系統就會獎勵50個比特幣,每四年,獎勵減半,到現在的話,獎勵是12.5個比特幣。注意:這里的每四年是一個大概值,實際上是說每挖出21萬個區塊獎勵就減半,大家可以自己算算,挖出21w個區塊的時間是3.99年,所以大致是每4年減半。

  • 問題二:系統如何來判斷誰擁有這個區塊的記賬權呢?
    為了解決這個問題,比特幣系統引入了POW共識機制,也就是工作量證明機制,這也是比特幣系統的靈魂所在。這個算法很簡單,就是系統出一道數學題,誰能夠最先解答出來,誰就會產生一個區塊,并在上面記賬。其實這種機制,我們生活中處處可見,比如我們的各種考試,考證。它的原理是:既然監督你們工作的過程是非常低效的,那好,我不管你是去如何工作的,我根據考試的結果來判斷你是否做了很多的工作。

工作量證明的基本原理

你做了一定難度工作產生了一個結果,系統根據結果來驗證你是否做了相應的工作。大致流程如下:



圖片來源:《區塊鏈:定義未來金融與經濟格局》

舉個例子
給定的一個基本的字符串"Hello, world!",我們給出的工作量要求是,可以在這個字符串后面添加一個叫做nonce的整數值,對變更后(添加nonce)的字符串進行SHA256哈希運算,如果得到的哈希結果(以16進制的形式表示)是以"0000"開頭的,則驗證通過。為了達到這個工作量證明的目標。我們需要不停的遞增nonce值,對得到的新字符串進行SHA256哈希運算。nonce的初始值為0

"Hello, world!0" => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64
...............
"Hello, world!4249" => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6
"Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

結果是需要4251次運算才能解答正確,當然這里只是一個簡單的例子,實際上比特幣系統的機制與這個小例子類似,但是比它更復雜,也就意味著需要更大的算力才能成功解題。

實際的比特幣系統中又是如何出題和解題的呢?
比特幣采用的是SHA-256算法,這是哈希運算的一種。礦工要計算的工作量就是通過解決下面這個哈希函數的未知參數,大概數學公式是這樣的。

Hash(上一個區塊的Hash值,交易記錄集,隨機數X) = 0000a2a5FD6g

由于比特幣網絡中節點去生成一個區塊是,總是基于目前存在的最新的區塊,所以每個礦工在計算之前已經能夠獲取到上一個區塊的所有信息,所以,Hash()函數的前2個參數都是確定的,最后的值也是確定的,礦工要做的就是去做大量的嘗試計算,找到一個隨機數X,使得Hash的結果以若干個0開頭,當然在每道題中0的個數不確定。哪個節點最先算出,就會產生一個新的區塊,并記賬。

下面是我從https://blockchain.info找的一個區塊#516559,你可以看看Hash值,一共18個0,再看看這個Nonce隨機數,可以看出這次解題是經過了數億次運算才成功。

到這里,我們已經知道礦工們為了獲取系統給出的比特幣,就會去耗費自己的算力和電力來解決難題。這道難題的3個關鍵點是:工作量證明函數區塊難度值

工作量證明函數

工作量證明函數是指這道題的計算方法,在比特幣的網絡中是SHA-256。SHA是一種安全散列算法,主要用于數字簽名。SHA-256是這個函數家族中的一員,它的特點是通過哈希算法運算之后,輸出值為256位。到目前為止,還沒有出現對SHA-256算法的有效攻擊。

區塊

區塊的作用是記載比特幣網絡中合法的交易。區塊包含的交易列表則附加在區塊頭后面,其中的第一筆交易是coinbase交易,這是一筆為了讓礦工獲得獎勵及手續費的特殊交易。下面這張圖是我自己畫的一個關于區塊的簡圖,比特幣挖礦都是基于已存在的最新區塊去生成下一個區塊。區塊主要由區塊頭交易列表組成。

區塊頭的詳細數據結構如下:

字段 描述 大小(byte)
Version 版本號 4
PrevBlockHash 上一個區塊的哈希值 32
MerkleRootHash 該區塊中的所有交易通過Merkle Tree生成的Hash 32
Time UNIX時間戳,也就是區塊產生的時間 4
Bits 難度值,完成比特幣工作量證明目標的難度系數 4
Nonce 隨機數,為了找到滿足難度目標所設定的隨機數 4

區塊包含的交易列表則附加在區塊頭后面,其中的第一筆交易是coinbase交易,這是一筆為了讓礦工獲得獎勵及手續費的特殊交易。

所以一個完整的區塊數據結構如下:


圖片來源:《區塊鏈:定義未來金融與經濟格局》

難度值

難度值是礦工挖礦的難度指標,它表示礦工大概需要多少次哈希運算才能產生一個合法區塊。我們已經知道比特幣的區塊大約每10分鐘生成一個,而全網的算力是在不斷變化的,比特幣系統要讓產生新區塊的時間基本維持在10分鐘,就得不斷去調整挖礦的難度值。通過去不斷的調整難度值,才使得新區塊的產生平均保持在10分鐘。

難度值的調整是在每個完整的節點中獨立發生的,而且是每隔2016個區塊(大概2周的時間)才會進行一次自動調整。具體來說就是實際挖礦的時常和期望時常(每個區塊10分鐘)相比較,如果產生區塊的時常大于10分鐘,就降低難度值,反之,則增加難度值。

這個公式可以總結為如下形式:

新難度值 = 舊難度值 * ( 過去2016個區塊花費時長 / 20160 分鐘 )

工作量證明還需要有一個目標值,計算公式如下:

目標值 = 最大目標值/難度值

最大目標值是固定的:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

目標值是指當前區塊生成所達成目標值的hash值,用來表示礦工的工作量證明,只有當礦工計算出來的hash值小于目標值,才表示挖掘區塊成功。

通過以上內容,我們可以大致總結下比特幣挖礦(工作量證明)的過程。通過不停的變換區塊中的nonce隨機數的值,并將它作為SHA-256哈希運算的輸入,直到找到一個值,可以讓運算之后的哈希值有指定個數的0為前導。0的個數越多,挖礦難度越大。

以下總結來自《區塊鏈:定義未來金融與經濟格局》
比特幣挖礦,也就是解決這道工作量證明難題的步驟大致歸納如下:

1、生成Coinbase交易,并與其他所有準備打包進區塊的交易組成交易列表,通過Merkle Tree算法生成Merkle Root Hash

2、把Merkle Root Hash及其他相關字段組裝成區塊頭,將區塊頭的80字節數據(Block Header)作為工作量證明的輸入

3、不停的變更區塊頭中的隨機數即nonce的數值,并對每次變更后的的區塊頭做雙重SHA256運算(即SHA256(SHA256(Block_Header))),將結果值與當前網絡的目標值做對比,如果小于目標值,則解題成功,工作量證明完成。

該過程可以用下圖表示:

通過以上介紹,我們已經知道,礦工是如何去解題以及怎樣才算是解題成功了。現在我們一起來思考一個問題。

Question

按照上面提到的Hash算法,只要礦工計算出來的區塊的哈希值小于目標值,就算是完成了工作量證明,那么也就有可能差不多在同一時間,有2個以上的礦工都完成了工作量證明,并且把消息廣播出去。那也就意味著同一高度可能存在多個區塊,也就是說主鏈即出現分叉(Fork),但是呢,肯定只能有一個區塊來記賬,那此時比特幣系統又該如何判決呢?

如果遇到分叉時,網絡會根據下列原則選舉出Best Chain:

  • 1、不同高度的分支,總是接受最高(即最長)的那條分支
  • 2、相同高度的,接受難度最大的
  • 3、高度相同且難度一致的,接受時間最早的
  • 4、若所有均相同,則按照從網絡接受的順序
    等待Block Chain高度增一,則重新選擇Best Chain

產生分叉時,區塊鏈大概是這樣的。


從這幅圖我們可以看出2點,第一:在同一高度可能會產生分叉(fork),第二:有一條最長的鏈(黑色的那條就是)。

這里就要稍微簡單介紹一下比特幣系統的最長鏈機制了。我們知道,每個新區塊的產生是要基于一個以前的區塊,而絕大多數礦工會選擇最長鏈的最后一個區塊來計算下一個區塊,因為只有最長鏈上的區塊才能獲得比特幣系統的認可,并得到挖礦的獎勵。而其他的分支則是無效分枝,不能得到任何獎勵,只能白白的浪費自己的算力和電力。這是保證區塊鏈不發生分裂的重要機制。

所以現在會有很多礦工會選擇抱團組成礦池,這樣才能保持長期成為最長分支。

最后一步,驗證機制

在節點(礦工)完成工作量證明(也就是找到滿足指定哈希值的隨機數nonce)之后,會馬上對全網進行廣播,網絡的節點收到廣播打包區塊,會立刻對其進行驗證。如果驗證通過,其他節點(礦工)將不再競爭打包這個區塊,而是選擇接受這個區塊,并將打包后的數據記錄在自己的賬本中,然后繼續進行下一個區塊的競爭答題中。

感謝以下作者
https://www.cnblogs.com/tinyxiong/p/7791538.html
http://8btc.com/article-160-1.html
http://www.infoq.com/cn/articles/bitcoin-and-block-chain-part02

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一、快速術語檢索 比特幣地址:(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一串...
    不如假如閱讀 16,064評論 4 87
  • 1 貨幣的演變——從貝殼到比特幣 當社會分工產生之后,人類就產生了商品交換的需求。在貨幣被發明之前,人類是以以物換...
    longlee閱讀 7,664評論 1 23
  • 本譯文首次以“s先生”的筆名發表于公眾號:補天遺石(ID:butianys)。譯無達詁,歡迎交流指正(微信:dat...
    補天遺石閱讀 5,231評論 0 4
  • 當手臂快伸直的時候,楊一凡手腕一翻,一枚銀針飛出,黑衣人猝不及防,銀針扎在了他的小腿上,楊一凡本來腕力就不錯,加之...
    不可芳物閱讀 303評論 22 3
  • web高并發開發 服務器端 keepalived + nginx/haproxy/lvs(代理)->[nginx(...
    laidian閱讀 430評論 0 1