比特幣的重複交易:一個風險極小的有趣Bug
在比特幣區塊鏈中存在兩組完全相同的交易,一組交易「夾住」了另一組交易,它們都發生在 2010 年 11 月中旬。 重複交易可能會導致混亂,比特幣開發者多年來一直通過各種方式與之作鬥爭。 這個問題仍未 100% 解決,下一個潛在的重複交易可能會在 2046 年出現。 儘管與重複交易相關的風險現在已經很小,但這是一個值得思考的有趣怪異 bug。

概述
一個正常的比特幣交易通過引用前一筆交易的交易 ID(TXID) 來使用至少一個前一筆交易的輸出。 這些未花費的輸出只能被花費一次,如果它們可以被花費兩次,你就可以對比特幣進行雙重支付,使比特幣變得毫無價值。 然而,在比特幣中實際上恰好存在兩組完全相同的交易。 這種情況之所以可能發生,是因為 coinbase 交易沒有任何交易輸入,而是有新生成的幣。 因此,兩個不同的 coinbase 交易有可能發送相同數量到相同地址,並以完全相同的方式構建,使它們完全相同。 由於這些交易是相同的,TXID 也相匹配,因為 TXID 是交易數據的哈希摘要。 TXID 被複製的唯一其他方式,是哈希碰撞,對於加密安全的哈希函數來說,這被認為是不太可能且不可實現的。 像 SHA256 這樣的哈希碰撞在比特幣或其他任何地方都從未發生過。
這兩組重複交易都發生在相近的時間內,在 2010 年 11 月 14 日 08:37 UTC 至 2010 年 11 月 15 日 00:38 UTC 之間,跨度約 16 小時。 第一組重複交易被夾在第二組之間。 我們將 d5d2….8599 歸類為第一個重複交易,因為它首先成為複製品,儘管奇怪的是,它在區塊鏈上首次出現是在另一個重複交易 e3bf….b468 之後。
重複交易詳情
在下面的圖片中,可以看到來自 mempool.space 區塊瀏覽器的兩個截圖,顯示了第一個重複交易在兩個不同區塊中重複出現的情況。


有趣的是,當在網絡瀏覽器中輸入相關網址時,mempool.space 區塊瀏覽器在 d5d2….8599 的情況下默認顯示較早的區塊,而在 e3bf….b468 的情況下默認顯示較晚的區塊。 Blockstream.info 和 Btcscan.org 與 mempool.space 有相同的行為。 另一方面,根據我們的基本測試,Blockchain.com 和 Blockchair.com 的行為方式不同,當在瀏覽器中輸入 URL 時,總是顯示重複交易的最新版本。
在相關的四個區塊中,只有一個區塊(區塊 91,812)包含了其他交易。 這筆交易將 1 BTC 和 19 BTC 的輸出合併成了一個 20 BTC 的輸出。
這些輸出可以被花費嗎?
由於存在兩組相同的 TXID,這為後續交易創造了引用問題。 每個重複交易的價值為 50 BTC。 因此,這些重複交易總共涉及 4 x 50 BTC = 200 BTC,或者根據不同的理解方式,可能涉及 2 x 50 BTC = a100 BTC。 在某種程度上,有 100 BTC 實際上並不存在。
截至今天,所有 200 BTC 都未被花費。 據我們所知(我們可能在這裡是錯誤的),如果有人擁有與這些輸出相關聯的私鑰,他們可以花費這些比特幣。 然而,一旦被花費,UTXO 將從數據庫中刪除,重複的 50 BTC 因此將無法花費並丟失,因此只有 100 BTC 可能被找回。 至於如果這些幣被花費,它們將來自哪個區塊,是較早的還是最近的,這可能是未定義的或無法確定的。
這個人本可以在創建重複交易之前花費所有比特幣,然後創建重複輸出,在未花費輸出的數據庫中創建新條目。 這將意味著不僅有重複交易,還有可能有重複的已花費輸出的重複交易。 如果發生這種情況,當這些輸出被花費時,將可能創建更多的重複交易,形成一種重複鏈。 人們必須小心事件的順序,總是在創建重複之前花費,否則比特幣可能永遠丟失。 這些新的重複交易將不是 coinbase 交易,而是「正常」交易。 幸運的是,這種情況從未發生過。
重複交易的問題
重複交易顯然是不好的。 它們會給錢包和區塊探索者帶來混亂,也會讓人不清楚比特幣的來源。 它還會帶來許多攻擊和漏洞。 例如,你可以用兩筆重複的交易支付某人兩次。 然後,當交易方決定嘗試使用這筆資金時,他們可能會發現只有一半的資金可以收回。 例如,這可以是對交易平台的攻擊,試圖使其破產,而攻擊者卻沒有任何損失,因為他們可以在存款後立即提取資金。
禁止使用重複 TXID 的交易
為了緩解重複交易問題,2012 年 2 月,比特幣開發者 Pieter Wuille 提出了 BIP30 軟叉方案,禁止使用重複 TXID 進行交易,除非前一個 TXID 已被花費。 該軟叉適用於 2012 年 3 月 15 日之後的所有區塊。
2012 年 9 月,比特幣開發者 Greg Maxwell 修改了這一規則,使 BIP30 檢查適用於所有區塊,而不僅僅是 2012 年 3 月 15 日之後的區塊。 本文前面提到的兩個重複交易除外。 這修復了一些 DOS 漏洞。 從技術上講,這又是一次軟叉,儘管規則變更只適用於過去 6 個月以上的區塊,因此它不存在與正常協議規則變更相關的任何風險。
這種 BIP30 檢查的計算成本很高。 節點需要檢查新區塊中的所有交易輸出,並檢查這些輸出端點是否已存在於 UTXO 中。 這可能就是 Wuille 只對未使用的輸出進行檢查的原因,如果對所有輸出都進行檢查,計算成本會更高,而且無法進行剪枝。
BIP34
2012 年 7 月,比特幣開發者加文-安德森(Gavin Andresen)提出了 BIP34 軟分叉方案,並於 2013 年 3 月激活。 這一協議變更要求 coinbase 交易包含區塊高度,這也使得區塊版本管理成為可能。 區塊高度被添加為幣基交易腳本 Sig 的第一項。 coinbase scriptSig 中的第一個字節是區塊高度數字所使用的字節數,接下來的字節就是區塊高度數字本身。 對於第一個 c160 年(223 /(每天 144 個區塊 * 每年 365 天)),第一個字節應為 0x03。 這就是為什麼如今的 coinbase ScriptSig(HEX)總是以 03 開頭。 這次軟分叉似乎徹底解決了重複交易問題,現在所有交易都應該是唯一的。
由於已經採用了 BIP34,2015 年 11 月,比特幣開發者亞歷克斯-莫科斯(Alex Morcos)向比特幣核心軟件倉庫添加了一個拉取請求,這一更改意味著節點將停止進行 BIP30 檢查。 畢竟,既然 BIP34 修正了這個問題,那麼這種昂貴的檢查就不再有必要了。 雖然當時還不知道,但從技術上講,這是為未來一些非常罕見的區塊進行的硬分叉。 現在看來,潛在的硬分叉並不重要,因為幾乎沒有人在運行 2015 年 11 月之前的節點軟件。 在 forkmonitor.info,我們運行的是 2015 年 10 月發布的 Bitcoin Core 0.10.3。 因此,這是一個硬分叉前的規則,客戶端仍在進行昂貴的 BIP30 檢查。
區塊,983,702 問題
事實證明,在 BIP34 激活之前的區塊中有一些 coinbase 交易,當時使用的 scriptSigs 的第一個字節恰好與未來有效的區塊高度相匹配。 因此,雖然 BIP34 確實在幾乎所有情況下都修復了這個問題,但它並不是一個完全的 100% 修復。 2018 年,比特幣開發者約翰-紐貝里(John Newbery)打印出了這些潛在重複的完整列表,如下表所示。


*注:這些區塊已在 2012 年和 2017 年產生 Coinbase 交易並非重複。 209 921 個區塊(距離第一次減半僅差 79 個區塊)不可能是重複的,因為 BIP30 在此期間得到了執行。
來源:https://gist.github.com/jnewbery/df0a98f3d2fea52e487001bf2b9ef1fd
按年份分列的潛在重複 Coinbase 交易數量

來源:https://gist.github.com/jnewbery/df0a98f3d2fea52e487001bf2b9ef1fd
因此,下一個可能出現重複交易的區塊是 1,983,702,將於 2046 年 1 月左右產生。 2012 年 1 月產生的 164,384 區塊中的 Coinbase 交易向七個不同的輸出地址發送了 170 BTC。 因此,如果 2046 年的礦工想要進行這次攻擊,他們不僅需要足夠幸運地找到這個區塊,還需要燒掉不到 170 BTC 的費用,總成本略高於 170 BTC,其中包括 0.09765625 BTC 區塊補貼的機會成本。
按照目前 88500 美元的比特幣價格計算,這將花費超過 1500 萬美元。 至於 2012 年幣庫交易的七個地址歸誰所有,目前還不得而知,密鑰很有可能已經丟失。 目前,該 Coinbase 交易的所有七個輸出地址都已被使用,其中三個在同一筆交易中使用。 我們認為這些資金可能與 Pirate40 龐氏騙局有關,但這只是我們的推測。 因此,這次攻擊看起來不僅代價高昂,而且對攻擊者來說幾乎毫無用處。 要在硬分叉中將 31 年前的 2015 年 11 月節點從網絡中刪除,這將是一筆不小的開支。
下一個可能被複製的脆弱區塊是 2012 年 3 月的 169985。 這個 Coinbase 只花費了剛剛超過 50 BTC,遠遠低於 170 BTC。 當然,50 BTC 是當時的補貼,而當這一 Coinbase 交易在 2078 年變得容易被重複時,補貼就會低得多。 因此,要利用這一點,礦工將需要燒掉大約 50 BTC 的費用,而這些費用他們是拿不回來的,因為這些費用必鬚髮送到 2012 年的舊產出中。 誰也不知道 2078 年比特幣的價格會是多少,但這種攻擊的成本也可能高得嚇人。 因此,這個問題可能不是比特幣的主要風險,但仍然令人擔憂。
自 2017 年 SegWit 升級以來,Coinbase 交易也可以包含對一個區塊中所有交易的承諾。 這些 BIP34 之前的區塊並不包含見證承諾。 因此,要產生一個重複的 Coinbase 交易,礦工需要從區塊中排除任何 SegWit 輸出贖回交易,這進一步增加了攻擊的機會成本,因為區塊可能無法包含許多其他支付費用的交易。
結論
考慮到復制交易的難度和成本,以及利用它的機會非常罕見,這個複制交易漏洞並不像是比特幣的一個主要安全問題。 不過,考慮到所涉及的時間尺度和重複交易的新穎性,想想還是挺有意思的。 儘管如此,多年來開發人員還是在這個問題上花費了大量時間,2046 年這個日期在一些開發人員心中可能是修復這個問題的最後期限。 修復這個錯誤的方法有很多,可能需要軟叉。 一種可能的修復方法是強制執行 SegWit 承諾。
原文鏈接
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方賬號:https://twitter.com/BlockBeatsAsia