關於PoW共識機制中的難度調整的疑問

在《區塊鏈技術指南》這本書中有這樣一段話:

難度值是比特幣系統中的節點在生成區塊時的重要參考指標,它決定了節點大約需要經過多少次哈希運算才能產生一個合法的區塊。比特幣的區塊大約每10分鐘生成一個,如果要在不同的全網算力條件下,新區塊的產生都基本保持這個速率,難度值必須根據全網算力的變化進行調整。簡單地說,難度值被設定在無論節點計算能力如何,新區塊產生速率都保持在每10分鐘一個。

  難度的調整是在每個完整節點中獨立自動發生的。每2016個區塊,所有節點都會按統一的公式自動調整難度,這個公式是由最新2016個區塊的花費時長與期望時長(期望時長爲20160分鐘,即兩週,是按每10分鐘一個區塊的產生速率計算出的總時長)比較得出的,根據實際時長與期望時長的比值,進行相應調整(或變難或變易)。也就是說,如果區塊產生的速率比10分鐘快則增加難度,比10分鐘慢則降低難度。 

  這個公式可以總結爲:新難度值=舊難度值×(過去2016個區塊花費時長/20160分鐘)

  工作量證明需要有一個目標值。比特幣工作量證明的目標值(Target)的計算公式:目標值=最大目標值/難度值

  其中最大目標值爲一個恆定值:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

  目標值的大小與難度值成反比。比特幣工作量證明的達成就是礦工計算出來的區塊哈希值必須小於目標值。

我們把目光着重放在這兩個公式上 :

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

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

不妨做一個假設,在現有網絡上平均出塊時間長於十分鐘,那麼過去2016個區塊花費時長大於20160分鐘,這代表以前挖礦的難度值大了,按道理新的難度值應該減小。但按照上述第一個公式,新難度值會增大??????這是不符合常理的。

我們再注意一下這句話“目標值的大小與難度值成反比。比特幣工作量證明的達成就是礦工計算出來的區塊哈希值必須小於目標值。”

 關於“區塊哈希必須小於目標值”,我們可以這樣理解:區塊頭部哈希值佔32字節(265個比特位),若定義MAX=2^256,則區塊頭部哈希的取值範圍爲0~MAX-1,對區塊頭部做雙重SHA256哈希運算的結果一定位於0~MAX區間。在該區間內取一個閥值TT(Target_Threshold),並規定區塊頭部哈希值必須位於0~TT區間纔算合法。因此挖礦運算就是不斷調整區塊頭部中的3個字段:Nonce、Time、Merkle Root,嘗試計算出位於0~TT區間的哈希值(位於TT~MAX區間則無效),得到合法的區塊頭部。

由於哈希函數的設計特性,其輸出結果在值域區間基本上是均勻分佈的,若TT越大,哈希運算結果落在0~TT區間的概率就越大,挖礦難度就低,反之,若TT越小,挖礦難度就大。這就像是在射箭,目標體積大,就容易命中,目標體積小,就很難命中。調整TT的值,也就調整了挖礦的難度。由於TT需要佔用256位,爲了縮短區塊頭部的總尺寸,對TT進行簡化編碼就得到了區塊頭部的Bits字段。(點擊查看這段話的原文)

其實還有一種理解方法,在PoW機制中,礦工得到的目標hash值往往滿足一個要求:前n位爲0。這個n越大,這個hash就越難找到。同時根據進制比較大小的法則,前幾位0越多,這個數就越小。

知道了這點,我們接着剛剛的假設來說:前2016個區塊挖礦的時間長,代表難度太大。如果死套公式一,新的難度增大,對於公式二:目標值=最大目標值/難度值 來說,目標值減小。

問題出來了,原來的挖礦難度大,調整後的難度的反而更大????????

帶着這個疑問,我查找了很多網上的資料,很多都是照抄這個公式的。本菜雞還是很不甘心,我查找了bitcoin和bitcoinj的源碼,分別如下:

bitcoin-0.1.5:

對於這段代碼的解釋,可以參考:https://blog.csdn.net/android_dtv/article/details/81118007

bitcoinj-master:

對於這段代碼的解釋:可參考: http://gavinzhang.work/blockchain/%E6%AF%94%E7%89%B9%E5%B8%81/Bitcoinj%E4%B8%AD%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87NetworkParameters

在瀏覽這些博客時,發現了一位兄弟的留言闡述了跟我一樣的疑問:

按照這位兄弟的思路,我考慮了一下,新目標值 = 舊目標值 * (過去2016個區塊花費時長/20160分鐘)這個公式是符合假設情況的。挖礦難的情況下過去2016個區塊花費時長增加,那麼新的目標值就會增大,挖礦也就更容易了。

其實,在bitcoinj的源代碼中也能看出一些蛛絲馬跡,在bitcoinj-0.11版本的源碼中,關於難度調整的算法是這樣的:

可以看到,最新版本的bitcoinj-master代碼與0.11版本的一個顯著區別是:將newDifficulty換成了newTarget,從側面印證了我的想法。(由於剛剛開始閱讀源碼,所以這裏只是一個猜測,如果在後續閱讀過程中發現不是,會回過頭來修改博客,大家見諒。)

那麼關於新目標值 = 舊目標值 * (過去2016個區塊花費時長/20160分鐘)這個公式的講解,大家不妨參照一下這篇博客:

https://blog.csdn.net/SHU15121856/article/details/95162230,裏面講的跟我們說的思路很符合。

菜鳥一枚,如果大家發覺我的思路有誤,歡迎指出,無比感激~

參考:

 1、《區塊鏈技術指南》 鄒均 張海寧 唐屹 李磊等

 2、https://www.chainnode.com/tutorial/4759

 3、 http://gavinzhang.work/blockchain/%E6%AF%94%E7%89%B9%E5%B8%81/Bitcoinj%E4%B8%AD%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87NetworkParameters

 4、https://blog.csdn.net/SHU15121856/article/details/95162230

5、https://blog.csdn.net/android_dtv/article/details/81118007

 

           

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