比特幣中的工作量證明(挖礦)

比特幣網絡中任何一個節點,如果想生成一個新的區塊並寫入區塊鏈,必須解出比特幣網絡出的工作量證明的迷題。
這道題關鍵的三個要素是工作量證明函數、區塊及難度值。工作量證明函數是這道題的計算方法,區塊決定了這道題的輸入數據,難度值決定了這道題的所需要的計算量。
1.工作量證明函數
和我們上節例子中用到的哈希函數一樣,比特幣系統中使用的工作量證明函正是SHA256。
SHA是安全散列算法(Secure Hash Algorithm)的縮寫,是一個密碼散列函數家族。這一組函數是由美國國家安全局(NSA)設計,美國國家標準與技術研究院(NIST) 發佈的,主要適用於數字簽名標準。SHA256就是這個函數家族中的一個,是輸出值爲256位的哈希算法。到目前爲止,還沒有出現對SHA256算法的有效攻擊。
2.區塊
比特幣的區塊由區塊頭及該區塊所包含的交易列表組成。區塊頭的大小爲80字節,由4字節的版本號、32字節的上一個區塊的散列值、32字節的Merkle Root Hash、4字節的時間綴(當前時間)、4字節的當前難度值、4字節的隨機數組成。區塊包含的交易列表則附加在區塊頭後面,其中的第一筆交易是coinbase交易,這是一筆爲了讓礦工獲得獎勵及手續費的特殊交易。
擁有80字節固定長度的區塊頭,就是用於比特幣工作量證明的輸入字符串。因此,爲了使區塊頭能體現區塊所包含的所有交易,在區塊的構造過程中,需要將該區塊要包含的交易列表,通過Merkle Tree算法生成Merkle Root Hash,並以此作爲交易列表的摘要存到區塊頭中。
3.難度值
難度值(difficulty)是礦工們在挖礦時候的重要參考指標,它決定了礦工大約需要經過多少次哈希運算才能產生一個合法的區塊。比特幣的區塊大約每10分鐘生成一個,如果要在不同的全網算力條件下,新區塊的產生保持都基本這個速率,難度值必須根據全網算力的變化進行調整。簡單地說,難度值被設定在無論挖礦能力如何,新區塊產生速率都保持在10分鐘一個。
難度的調整是在每個完整節點中獨立自動發生的。每2016個區塊,所有節點都會按統一的公式自動調整難度,這個公式是由最新2016個區塊的花費時長與期望時長(期望時長爲20160分鐘即兩週,是按每10分鐘一個區塊的產生速率計算出的總時長)比較得出的,根據實際時長與期望時長的比值,進行相應調整(或變難或變易)。也就是說,如果區塊產生的速率比10分鐘快則增加難度,比10分鐘慢則降低難度。
這個公式可以總結爲如下形式:
新難度值 = 舊難度值 * ( 過去2016個區塊花費時長 / 20160 分鐘 )
工作量證明需要有一個目標值。比特幣工作量證明的目標值(Target)的計算公式如下:
目標值 = 最大目標值 / 難度值
其中最大目標值爲一個恆定值:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
目標值的大小與難度值成反比。比特幣工作量證明的達成就是礦工計算出來的區塊哈希值必須小於目標值。
 與第3節所舉的例子相類比,我們也可以簡單理解成,比特幣工作量證明的過程,就是通過不停的變換區塊頭(即嘗試不同的nouce值)作爲輸入進行SHA256哈希運算,找出一個特定格式哈希值的過程(即要求有一定數量的前導0)。而要求的前導0的個數越多,代表難度越大。

4.工作量證明的過程

我們可以把比特幣礦工解這道工作量證明迷題的步驟大致歸納如下:
生成Coinbase交易,並與其他所有準備打包進區塊的交易組成交易列表,通過Merkle Tree算法生成Merkle Root Hash
把Merkle Root Hash及其他相關字段組裝成區塊頭,將區塊頭的80字節數據(Block Header)作爲工作量證明的輸入
不停的變更區塊頭中的隨機數即nonce的數值,並對每次變更後的的區塊頭做雙重SHA256運算(即SHA256(SHA256(Block_Header))),將結果值與當前網絡的目標值做對比,如果小於目標值,則解題成功,工作量證明完成。
5結語
比特幣的工作量證明,就是我們俗稱“挖礦”所做的主要工作。理解工作量證明機制,將爲我們進一步理解比特幣區塊鏈的共識機制奠定基礎。
比特幣在Block的生成過程中使用了POW機制,一個符合要求的Block Hash由N個前導零構成,零的個數取決於網絡的難度值。
要得到合理的Block Hash需要經過大量嘗試計算,計算時間取決於機器的哈希運算速度。
當某個節點提供出一個合理的Block Hash值,說明該節點確實經過了大量的嘗試計算,當然,並不能得出計算次數的絕對值,因爲尋找合理hash是一個概率事件。
當節點擁有佔全網n%的算力時,該節點即有n/100的概率找到Block Hash。

什麼是比特幣挖礦

① 區塊和區塊鏈
一段時間內的交易打成的一個包稱爲區塊,比特幣全網平均每10分鐘產生一個區塊,每一個區塊都鏈接到上一個區塊,依次相連形成區塊鏈。
② 以區塊爲單位同步交易數據
區塊從1開始編號,因此節點A連接節點B後,只要檢查雙方的區塊編號高度,就能方便地同步交易數據。例如節點A自己的區塊高度是100,發現節點B的區塊高度是110,則只要向B請求同步101~110這10個區塊即可。
③ 打包區塊的獎勵
爲保證有節點打包比特幣交易,比特幣規則規定:打包交易的節點將獲得比特幣作爲酬勞。
A、打包獎勵的一部分來自交易創建者支付的交易手續費(每KB交易大小100~1000聰手續費)。
B、另一部分來自初始2100萬個比特幣的分發,最開始獎勵是每個區塊50比特幣,之後每經過21萬個區塊(約4年時間)獎勵將減半一次,直到2140年左右區塊獎勵不足1聰爲止,此時區塊獎勵總和爲2100萬比特幣,這就是比特幣2100萬總量的來源(準確地說是 20999999.97690000個)。
2140年後打包獎勵將只來自於交易創建者支付的交易手續費。
④ 對區塊打包權的競爭
節點打包交易只需要消耗很低成本的網絡和計算資源,打包獎勵的存在(目前每個區塊的打包獎勵25比特幣約爲4萬元),使得有大量節點想打包交易。爲保證區塊鏈的唯一性,比特幣規則規定:節點使用類似“扔硬幣”的方法爭奪交易打包權。節點不斷地扔硬幣,誰首先扔出符合規則的結果,誰就能獲得這個區塊的交易打包權,以及這個區塊的打包獎勵。
⑤ 競爭交易打包權的方式
“扔硬幣”在實現上是計算機做一次哈希(SHA-256)運算,並檢查運算結果從第一位開始是否有足夠多連續的0(可以簡單理解爲一次扔256個硬幣,然後看從第一個硬幣開始是否有足夠多的連續硬幣正面)。“扔硬幣”獲勝的唯一訣竅是提高每秒扔硬幣的次數,一個每秒能扔100億次硬幣(做100億次哈希計算)的節點,搶到打包權的概率是每秒扔1億次硬幣節點的100倍。
⑥ 獲勝節點打包交易並廣播
一旦有某個節點扔出符合系統規則的硬幣結果(例如區塊379543的哈希值 000000000000000008bdeb575056584429ea4be876ea7ca4ce70262d3edb8c8b),他就會立即將這段時間蒐集到的交易打包成一個區塊,附上“扔硬幣”的結果、區塊序號379543、上一區塊關係等附加信息廣播出去,其它節點一旦收到區塊379543並驗證無誤,就會停止“扔硬幣”搶這一區塊,轉而在這一區塊的基礎上開始“扔硬幣”搶下一區塊379544。
⑦ “挖礦”和“礦工”的由來
節點大量進行哈希計算需要計算機設備,並消耗大量電力,這個過程在本質上和金礦挖礦很相似(通過挖礦設備,消耗能源換取黃金)。比特幣總量恆定,產量越來越少的產生方式也和黃金很相似。
因此人們形象地將比特幣搶打包權的過程稱爲挖礦(mine),將搶打包權的比特幣節點稱爲礦工(miner)。
發佈了21 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章