比特幣挖礦有可能存在無法滿足難度條件的情況嗎?

比特幣一個區塊的頭只有80位元組,就算加上可以對Merkle的各種組合變動來調節HASH結果,有沒有可能出現難度過大,而造成理論上無法挖到礦的情況呢?

難度調整也要通過出塊調整才能發布出去。有沒有可能沒法出塊呢?從理論上有證明肯定能出塊嗎?

這是不是可以理解為,從一個較大的空間,向一個256位的空間映射的問題。難道只要微調難度,就一定能保證能映射成功,有塊可出嗎?


歷史上曾經出現過算力波動過大,一次難度調整後半天也不出快的情況;

所以理論上是可能長時間不出塊造成網路堵塞的,這個長時間取決於難度調整的幅度大小,如果一下難度調整為離譜的數字,那肯定會發生長時間不出塊的情況了;但是如果難度每次都是微調,都不會超過算力波動太大,就沒問題了。

那麼我們再複習下比特幣的難度調整演算法:

比特幣的區塊平均每10分鐘生成一個。這就是比特幣的心跳,是貨幣發行速率和交易達成速度的基礎。不僅是在短期內,而是在幾十年內它都必須要保持恆 定。在此期間,計算機性能將飛速提升。此外,參與挖礦的人和計算機也會不斷變化。為了能讓新區塊的保持10分鐘一個的產生速率,挖礦的難度必須根據這些變 化進行調整。事實上,難度是一個動態的參數,會定期調整以達到每10分鐘一個新區塊的目標。簡單地說,難度被設定在,無論挖礦能力如何,新區塊產生速率都 保持在10分鐘一個。

那麼,在一個完全去中心化的網路中,這樣的調整是如何做到的呢?難度的調整是在每個完整節點中獨立自動發生的。每2,016個區塊中的所有節點都會 調整難度。難度的調整公式是由最新2,016個區塊的花費時長與20,160分鐘(兩周,即這些區塊以10分鐘一個速率所期望花費的時長)比較得出的。難 度是根據實際時長與期望時長的比值進行相應調整的(或變難或變易)。簡單來說,如果網路發現區塊產生速率比10分鐘要快時會增加難度。如果發現比10分鐘 慢時則降低難度。

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

New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 20160 minutes)

然後看看實際的代碼:

int64_t nActualTimespan = pindexLast-&>GetBlockTime() - pindexFirst-&>GetBlockTime(); LogPrintf(" nActualTimespan = %d before bounds
", nActualTimespan);

if (nActualTimespan &< Params().TargetTimespan()/4)

nActualTimespan = Params().TargetTimespan()/4;

if (nActualTimespan &> Params().TargetTimespan()*4)

nActualTimespan = Params().TargetTimespan()*4;

為了防止難度的變化過快,每個周期的調整幅度必須小於一個因子(值為4)。如果要調整的幅度大於4倍,則按4倍調整。由於在下一個2,016區塊的 周期不平衡的情況會繼續存在,所以進一步的難度調整會在下一周期進行。因此平衡哈希計算能力和難度的巨大差異有可能需要花費幾個2,016區塊周期才會完成。

所以這個設計已經算很保守了。比特幣難度的調整是和上個周期2016個塊的產生時間決定的。同時有個最大最小因子。

但是我們能想到的最極端的情況,比如有一天一個難度周期調整之後,所有礦機同時損毀,短時間內不能再造。大家都回到GPU挖礦時代,這個時候可能會發生題主說的長時間不出塊的情況,同時造成難度周期無法調整,這個理論上的概率是有的。

合理的難度調整是個很有意思的問題,比如現在分叉幣多得很,大家都出來圈錢,但是簡單fork一份代碼就分個叉,難度調整照搬原來,初期肯定就會出不了塊,然後沒有礦工過來挖礦,這個幣就死掉了。

所以現在的分叉幣一出來,第一個改的就是難度調整演算法。


確實有可能無法滿足,因為80位元組能夠提供的隨機性是有限的,不能保證一定能存在滿足難度要求的頭。


雖說不能保證一定出塊吧,但是……

80位元組,其中有40位元組是不斷變化的:

32位元組的Merkle根,至少其中的coinbase裡面包含了不定長還可以隨意修改的擴展Nonce;

4位元組時間戳,每秒都在變;

4位元組Nonce,可以隨意修改。

如果這還挖不到,SHA256散列演算法也太不「散」了。

另一方面,活人不能讓程序憋死,如果真的出現難度太大不出塊的情況。大家可以表決換個演算法,換難度調整演算法,換散列演算法,都行。


看到樓上有人回答,算力波動導致半天不能出塊的問題,和樓主提問的是2個問題。算力波動無法出塊,是因為難度太高了,算力不夠導致的,並不是區塊頭無法提供足夠的隨機性。80位元組區塊頭是否能保證足夠隨機性我不懂,我只知道現在單純改變區塊頭的nonce不行,有時候還需要輔助coinbase 裡面的其他值吧。


挖礦難度都是動態調整的,目前BTC是2016個塊調整一次,BCH是每個塊都會調整,簡單來說就是算力大了,難度就會增加,算力小了,難度就會減小。目的就為了平均每10分鐘出一個塊。


推薦閱讀:

TAG:比特幣Bitcoin | 挖礦 | 區塊鏈Blockchain |