作者:晏文春 / 來源:白話區塊鏈
在《為什么有的區塊沒有打包交易,是礦工忘記了嗎?》一文中,有讀者留言提問:
這個問題梳理成如下表述:
假設最新的區塊高度為1萬,在10:00整被挖出,礦工快速構建區塊高度為1萬零1的區塊,然后在10:05,大白發布了一個交易,在10:06最新的區塊被挖出,而且打包了大白發布這筆交易,這是為什么呢?按理說,這個新交易發布的時候,礦工早就構建好了候選區塊,這個交易肯定不在他當初構建的候選區塊里。
今天我們就來試著解答這個問題。
01
挖礦就是不斷嘗試隨機數
在《一個經典的故事,讓你3分鐘搞懂比特幣挖礦》一文中,白話區塊鏈介紹過,挖礦的過程就是不斷嘗試隨機數,試圖找到符合要求的解的過程。礦工在構建好區塊后,不斷嘗試隨機數,直到有人找到符合要求的隨機數(區塊頭的哈希值≤目標值),新區塊被挖出,該礦工獲得出塊獎勵。
02
有限的隨機數
比特幣系統中的可以嘗試的隨機數是有限的,只有2^32種可能的取值。礦工構建區塊后,遍歷所有的隨機數,很可能仍沒得到符合要求的解。這種情況,礦工該怎么辦呢?哈希函數特點是,輸入值改變哪怕一點:可以是改變順序、增加內容、減少內容等,輸出值的結果都會有天差地別般的變化。所以這種情況下礦工可以重新構建區塊,比如其他內容不變,將一筆剛剛發布交易打包進區塊,然后再嘗試隨機數,這種情況下,如果剛好找到了符合要求的解,新的區塊就被挖出來了,這筆新發布交易也就被確認了。這也就回答了我們開頭的那個問題。
03
礦工的其他調整方法
在遍歷所有隨機數后仍沒有找到符合要求的解的情況下,礦工除了調整區塊里打包的交易,還有哪些其他調整方案呢?
我們知道挖出新區塊的條件是:區塊頭的哈希值≤難度目標。
而區塊頭內容包含:
除去隨機數字段,塊頭里的版本字段、父區塊頭哈希值、難度目標都是確定的,無法調整,而時間戳字段可調的范圍非常有限。這樣下來,方便調整的部分還就剩默克爾樹根字段。區塊頭內并沒有包含該區塊的交易數據,而是對這些交易信息取哈希值,然后再對交易的哈希值兩兩合并再取哈希值,直到形成最后形成一個字段,這個字段就是默克爾樹根字段,它將被存儲進區塊頭里。
▲圖片來自網絡:默克爾樹
所以當出現遍歷所有隨機數都沒有找到合適解的情況下,礦工可以調整區塊里的交易:包括交易的順序、增加打包的交易、減少打包的交易等,這些調整最終都將造成區塊頭里默克爾樹根哈希值的變化,從而影響整個區塊頭的哈希值。但這樣的處理都是輔助的方式,礦工更普遍的方式修改一個特殊交易的額外的隨機數(Extra Nonce),這種調整方法相對來說更加高效。
這個特殊的交易就是比特幣出塊獎勵的創幣交易。這筆交易是由系統"憑空創造"的,所以這筆交易是沒有輸入的,也就是說它的輸入域(input 字段)默認是空的。礦工可以對這個字段進行修改,以期找到符合要求的解。創幣交易輸入域為額外的隨機數提供了8個字節空間,換句話說,這使得隨機數由原來的2^32種可能性擴大為2^96種可能性,礦工遍歷2^96種可能性,一般都能找到符合要求的解。
另外值得一說的是,這個特殊交易的輸入域還是很多人信息上鏈的"窗口",比如神魚的"執子之手,與子偕老。神魚 to 冬冬"就寫在創幣交易的輸入域里。
如果你是礦工,想在創幣交易輸入域"秀恩愛",你應該在區塊挖出之前上寫“秀恩愛“的信息,還是等區塊挖出之后再寫呢?為什么呢?歡迎在留言區寫下你的看法。