1. 程式人生 > 其它 >BTC-挖礦難度的調整(區塊鏈技術與應用)

BTC-挖礦難度的調整(區塊鏈技術與應用)

挖礦難度

挖礦就是不斷嘗試區塊塊頭中的nonce和extra nonce的值,使得:
$$
H(block header)≤target
$$
顯然目標閾值target越小,則挖礦的難度就越大。所以調整挖礦難度就是在調整target,以調整目標空間在整個輸出空間中所佔的比例

比特幣中使用的雜湊函式是SHA-256,產生的雜湊值是256位的,所以整個輸出空間是2256 ,調整目標空間所佔的比例,在這個問題裡直觀的來看就是最後得到的雜湊值前面有多少位0(這只是通俗直觀來看的,也許第一個非0位是要小於4也說不定),這個0越多顯然值就越小,也就是挖礦難度越大了。

挖礦難度和目標閾值的大小成反比:
$$
difficulty=\frac{difficulty_1_target}{target}
$$
上式中常量difficulty_1_target

是指挖礦難度difficulty定義為1時所對應的目標閾值target的值。挖礦難度最小就是1,所以這個常量也就是target允許的最大值

為什麼要調整挖礦難度?

系統中的總算力越來越強,如果挖礦難度保持不變,那麼平均出塊時間會越來越短,這會造成一些問題。

假設平均出塊時間減小到了1秒鐘,也就是每隔1秒左右就有一個新的區塊攜帶一些列交易被髮布到比特幣網路上,而在比特幣網路上這個區塊傳播給大多數結點可能就要幾十秒。如果有兩個結點幾乎同時釋出了區塊,那麼就會出現分叉:

這是一個二分叉的情況,如果出塊時間很短,就會導致這種分叉成為常態。而且不僅僅是二分叉,可能會出現很多分叉

分叉過多對比特幣系統達成共識沒有好處,並且會危害比特幣系統的安全性。

eg:分叉攻擊:正常情況下,因為大部分結點是誠實的,有惡意的結點想要在6個確認後拿這段時間集中算力算出的新鏈去覆蓋掉最長合法鏈是很難的,因為誠實結點也都在集中算力擴充套件最長合法鏈。
如果出塊時間很短,就會導致分叉過多(因為相比於出塊時間,可以認為網路上傳輸的時間變長了),這樣誠實結點的算力就被分散了,這時惡意結點要進行51% attack很可能就不需要50%以上的算力了,可能百分之十幾就足夠了,這樣大大降低了比特幣系統的安全性。

以太坊的出塊時間就降低到了15秒,大幅降低了出塊時間,所以以太坊就要設計一個新的共識協議GHOST。在這個協議中,分叉產生的orphan block不能簡單丟棄掉,而是也要給予一些獎勵(uncle reward

)。

總之,在不同的區塊鏈賬本系統中,不論出塊時間設計成多長,都要設法讓其保持穩定,而不能允許它隨著系統中總算力的提高而無限減小下去。

怎麼調整挖礦難度?

比特幣協議中規定,每隔2016個區塊(大約每2個星期)要重新調整一下目標閾值target,具體的迭代更新公式是:
$$
target=target*\frac{actual\ time}{expected\ time}
$$
這裡expected time就是預期的兩次調整的間隔時間,即2016乘以10分鐘;而actual time是系統中產生最近的2016個區塊實際花費的時間。

為了避免系統中出現某些意外情況,導致系統出現非常大的波動,每次對目標閾值target的調整最大不能超過4倍,最小不能小於$\frac{1}{4}$ ,也即上式中的$\frac{actual\ time}{expected\ time}$ 即便超過4了也按4使用,即便小於$\frac{1}{4}$ 也只按$\frac{1}{4}$ 使用。

如果惡意的結點不調整target怎麼辦

target是寫在比特幣系統的程式碼裡的,程式碼也都是開源的,如果有結點到了該調整的時候不調整target怎麼辦?

這也是一個大部分結點誠實的問題,如果不調整target,那麼釋出的區塊塊頭裡的4位元組nBits域(32位元組的target壓縮編碼後的版本)就不是正確的,誠實的結點不會接收這樣的區塊