挖礦計算

        以前做過礦池開發,也看了很多有關挖礦算法的技術文章,一頭霧水,也花了很長時間去理解。在《白話區塊鏈》中挖礦章節中說的通俗易懂,分享出來,希望對同學們能有所幫助。

        很多朋友在第一次看到“挖礦”這個詞時都很疑惑,包括本人。比特幣不是一個軟件嗎?通過軟件來挖礦是什麼意思?從字面上來看,應當是通過投入某種工作,然後能得到一個“寶貝”,也就是礦。當然了,“挖礦”自然不是我們通常認爲的那個挖礦,它只是一套算法,在介紹算法過程前,我們先來了解下挖礦在比特幣軟件中主要都有哪些用途:
·搶奪區塊打包權
·驗證交易事務
·獎勵發行新幣

·廣播新區塊

        我們知道,比特幣是一個對等網絡,每個節點都可以獨立維護自己的數據副本,那麼問題就來了,怎麼來保證彼此之間的數據一致呢?既然沒有一箇中心服務器,自然也就沒有一個傳統意義上的權威數據來源了。這就得有一個約定的規則,大家共同按照這個規則來進行競爭,誰競爭成功了誰就有數據的打包權,也就是記賬權,打包完成後廣播給別人,別人只要驗證一下有無問題即可,沒有問題就存入到自己的數據文件中。這個思路不錯,等於就是大家來競爭臨時中心服務器的資格,那麼比特幣中實行了一種什麼樣的規則呢?那就是被稱爲工作量證明(Proof of Work,PoW)的一種算法,其實就是類似於擲骰子的一種遊戲。如大家約定擲出一個10位長度的數字,前面6位要都是0,後面的4位數得小於某個值,看誰先擲出符合要求的數字出來,誰就搶得了打包權(記賬權)。我們來看下比特幣中具體是怎麼來擲這個骰子的。
1.難度值
        首先,既然是大家都在競爭擲骰子,那擲出來的數字必然是要符合一個難度的,這個難度就是一個門檻,在比特幣軟件中,規定一個256位的整數:

x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

        作爲難度1的目標值。在比特幣誕生初期,當時的全網算力,大約需要10分鐘左右的運算能得到一個符合這個難度1要求的值,這也是我們常常說比特幣網絡每隔大約10分鐘出一個區塊的來源。我們在查詢創世區塊(也就是0號區塊)的信息時,可以看到當時的難度就是1。那麼,所謂符合這個難度爲1的要求的值是什麼意思呢?就是說通過工作量證明算法,也就是比特幣中的挖礦算法來計算出一個結果,這個結果要小於這個難度目標值,我們來看下0號區塊的難度信息:
"nonce": 2083236893,
"bits": "1d00ffff",

"difficulty": 1,

        這些信息可以通過比特幣支持的JSON-RPC中的getblock命令方法獲得,其中的difficulty就是指難度級別。0號區塊的難度值是1,nonce是一個隨機數,是挖礦計算得到的一個數字,這個等會兒再介紹,bits是用來存儲難度的十六進制目標值的,這個難度目標值是存儲在區塊的頭部的,在源碼中被定義爲一個4字節長度的字段,4字節也就是32位,要用來存儲256位長度的難度目標值,因此這256位長度的值需要經過壓縮處理後才能放到這個字段中。以這個難度1的目標值來說,我們查詢區塊信息後,看到的值是1d00ffff,那麼,這個值是怎麼壓縮而來的呢?規則其實很簡單,我們一共有4個字節來存儲,這4個字節的最高位字節用來存儲難度值的有效字節數。什麼叫有效字節數?就是從第一個不全爲0的字節開始的部分,比如難度1的值有效位是0x00FFFF……。等等,怎麼前面有2個0呢?這是因爲在壓縮規則中,規定了如果難度值有效位的最高位爲1(大於0x80),則需要在前面補上一個0x00,這裏的最高位是F,也就是二進制的1111,因此是符合這個規則的。難度1的目標值中,有4個字節長度的0,減掉這些0的長度共32bit,剩餘256-32=224,也就是28個字節,加上補的0x00,因此,有效位總計29個字節,29的十
六進制是1D,另外3個字節中存儲的是目標值有效位的最高3個字節,此時的目標值有效位前面已經加上了2個0,因此最高3個字節爲0x00FFFF,合起來壓縮後的值就是0x1D00FFFF。對於這樣的一個壓縮後的十六進制4字節難度目標值,前2位通常稱爲冪者指數,後面6位稱爲係數。

那麼,有朋友問了,壓縮是可以,那還原出來呢?我們看個公式:

目標值=係數*2^(8*(指數-3))次方。
        我們就以這個0x1D00FFFF爲例來說明,係數是後面6位也就是00FFFF,指數是前面2位也就是1D,代入進去就是:
0x00FFFF*2^(8*(0x1D-3)),計算後得到的值是:
0x00000000FFFF00000000000000000000000000000000000000000000000
有朋友可能疑惑了,不對吧,這個跟規定的那個難度1的值不一樣了啊,精度少了很多,確實是的,存儲在bits中的值是一個精度截斷的近似值。我們以200000號區塊爲例,查詢一下難度值,得到如下:
"nonce": 4158183488,
"bits": "1a05db8b",

"difficulty": 2864140.507810974,

        我們來看看這個difficulty的值是怎麼來的,0號區塊的難度是1,對應的目標值是0x1D00FFFF,200000號區塊的難度目標值是0x1A05DB8B,將兩者的目標值按照上述公式進行轉換後相除便能得到這個2864140.507810974的難度值,我們發現,200000號區塊的difficulty比0號區塊的大許多,而bits的大小卻比0號區塊的小許多。這其實是表明了一個特點,隨着全網算力越來越強,difficulty難度值就會越來越大,而bits表示的目標值會越來越小,這兩者成反比,目標值越小就越難挖礦。剛纔也提到了,難度值並不是一成不變的,比特幣差不多每兩週會調整一下新的難度值,因爲計算的算力是會變化的,爲了維持差不多10分鐘出一個區塊的節奏,難度要跟隨算力變化而調整,不得不說比特幣的設計還是相當完整的。

        新難度值的計算公式是這樣的:新難度值=當前難度值×(最近的2016個區塊的實際出塊時間/20160分鐘)。2016個區塊的意思是:假設按照理論的10分鐘出一個塊,2周也就是14天的時間,應該出2016個區塊,可以看到實際上就是計算一下實際與理論上的時間差值,彌補上這個差值即可。

2.挖礦計算
        我們瞭解了難度值的概念,現在來看看挖礦計算具體是怎樣一個過程。首先,我們說了挖礦是要搶奪區塊打包權,那就得收集需要打包進區塊的那些交易事務,那這些數據從哪來呢?這裏有個概念需要大家注意,打包就像是記賬,是把發生的交易事務記錄下來存檔,但是無論什麼時候打包、誰打包,在網絡中發生的交易是持續不斷的,就像企業倉庫的進銷存業務,無論記賬員是一個月還是半個月記一次賬,業務是持續進行的。在比特幣系統中,每個人都會將通過錢包進行的轉賬交易數據廣播到網絡中,這些都是屬於等待打包的未確認交易數據。這些數據都會放在一個內存池中,總之就是一個緩衝區,當然,這些數據都會被
接受基本的驗證,用以判斷是否是不合法的或者是不符合格式的交易數據。
    挖礦程序從內存池中獲取用來打包區塊的交易數據,接下來就要幹活啦,我們來看一下挖礦的計算公式:
SHA256(
        SHA256(version + prev_hash + merkle_root + ntime + nbits + nonce )

    ) < TARGET

        SHA256是一種哈希算法,可以通過對一段數據進行計算後輸出一個長度爲256位的摘要信息。SHA256在比特幣中使用很廣泛,不但用於挖礦計算,也用於計算區塊的哈希值和交易事務的哈希值,比特幣對SHA256算法是情有獨鍾啊,我們看到在這個公式中,是對參數進行兩次SHA256計算,如果計算出來的值小於那個TARGET(也就是難度目標值),那就算是挖礦成功了。那麼,這些參數都是由哪些組成的呢?

請看下錶:


        這些數據字段其實也是區塊頭的組成部分,將這些參數連接起來,參與SHA256的挖礦計算。在這些參數中,版本號是固定的值,前一個區塊的哈希值也是固定的值,當前難度也是一個固定的值,那麼要想改變這個公式的計算結果,能改動的參數就只有梅克爾根、區塊時間戳和那個隨機數了。
        1)梅克爾根是通過交易事務計算出來的,挖礦程序從內存池中獲取待打包的交易事務,然後計算出梅克爾根,獲取交易事務本身也是有一些優先級規則的,比如根據手續費大小之類,這些細節就不贅述了。
        2)區塊時間戳是指UNIX時間戳,用於記錄區塊的產生時間,我們知道比特幣系統是分佈式的網絡,沒有固定的時間服務器,因此每個節點獲得的時間戳都可能是不一樣的,由此,比特幣系統中設置了規則:

    ①新產生區塊的時間戳要大於之前11個區塊的平均時間戳;

    ②不超過當前網絡時間2個小時。所以,後一個區塊的時間戳比前一個區塊的時間戳反而小也是可能的。

        3)隨機數是一個可自由取值的數值,取值範圍是0~2的32次方。我們可以看到,要通過這樣的參數來計算出符合條件的值,基本上也就只能靠暴力計算匹配了,這種不斷執行SHA256計算的過程很消耗算力,因此這個過程被形象地稱爲“挖礦”。簡單地說,挖礦就是重複計算區塊頭的哈希值,不斷修改該參數,直到與難度目標值匹配的一個過程。

    一旦匹配成功,就可以廣播一個新的區塊,其他客戶端會驗證接收到的新區塊是否合法,如果驗證通過,就會寫入到自己的區塊鏈賬本數據中。那麼,挖礦的獎勵在哪兒呢,不是說礦工成功出一個區塊就能得到比特幣作爲獎勵的嗎?那麼這裏獎勵在哪呢?這個獎勵其實是作爲一條交易事務包含在區塊的交易事務中的,相當於系統給礦工轉賬了一筆比特幣,這種交易事務由於特殊性,通常稱爲coinbase交易,這個交易一般是位於區塊中的第一條,比特幣系統也正是通過這種挖礦獎勵的方式發行新的比特幣,就像央行發行新鈔一樣。


作者:韓璐
來源:《白話區塊鏈》
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章