作者:BitMEX Research
摘要:在這篇文章中,我們要討論 “繁難區塊” —— 專門構造得難以驗證的區塊。如果有人對比特幣懷有敵意、製作出 “繁難交易”(專門設計成讓節點需要很長時間來驗證的交易),就會形成這樣的區塊。這個概念最早得到討論是在 2013 年 1 月,當時出現了一筆繁難交易,其體積接近 1MB ,一臺普通的計算機需要大約 3 分鐘來驗證。這種攻擊還有一些變體,可能會讓情況惡化幾個量級,但本文不會詳細討論。BIP-54 軟分叉提議包含了一項修復措施:限制一筆交易的非隔離見證輸入可以使用的 CHECKSIG 和 CHECKMULTISIG 操作碼的總數量。
概述
本文是關於 BIP-54 可修復或可緩解的比特幣潛在漏洞的系列文章的第四篇:
- Bitcoin’s Duplicate Transactions - March 2025(中文譯本)
- The Timewarp Attack - March 2025(中文譯本)
- 64 Byte Transactions - December 2025(中文譯本)
在這最後一篇文章中,我們要了解最嚴重的潛在漏洞之一:出現惡意區塊的可能性;它可能會讓一個節點花費極長的時間來驗證。這個問題也常常被稱為 “最壞情況下的區塊驗證問題”。
問題淵源
在 2013 年 1 月,比特幣安全研究員 Sergio Lerner 在 Bitcointalk 論壇上發了一個帖子,解釋稱可以構造出一筆有效的比特幣交易,讓一個節點要花費至少 3 分鐘來驗證。辦法就是創建一個使用許多輸入的交易(考慮到歷史時間,當然是隔離見證以前的腳本類型)。這些輸入帶有所謂的 “SIGHASH 操作平方膨脹” 問題。
Sergio 解釋說,一筆自身體積貼近 1MB 的比特幣交易,可以產生出超過 19GB 的需要哈希的數據,對於一臺普通的計算機,至少需要 3 分鐘來驗證。限制了這個問題的嚴重性的,是 1MB 的區塊體積上限,如果沒有這個限制,攻擊可以更加嚴重。在 Sergio 提供的例子中,這筆交易是無效的,但這種攻擊依然算是致命的,因為它讓一個節點需要花很長時間才能斷定一筆交易是有效的還是無效的。除此之外,花 3 分鐘才能驗證僅僅一筆交易,顯然是一個嚴重的問題。我們在下表中列出了這可能帶來的一些問題。
繁難交易可能造成的負面後果
| 場景 | 描述 |
|---|---|
| DoS 攻擊 | 對比特幣懷有敵意的人可以製作出這樣的繁難交易。這算是一個致命的 DoS 漏洞,可以同時影響礦工和節點運營者。在繁難區塊驗證期間,商家和交易所可能必須手動關閉驗證。節點運營者可能對問題一無所知,只能不斷重啟節點又不斷被卡住。可能這時候節點運營者就放棄了,直接下線。 |
| 打擊礦工 | 3 分鐘已經是目標出塊時間的 30% 。一個惡意的礦工可以製作出這樣很難驗證的區塊,當其他礦工正忙著驗證它的時候,自己就立即開挖下一個區塊。一個敵意礦工甚至可以製作出一長串的繁難區塊、阻礙其他礦工,然後壟斷區塊生產。 |
| 增加初始化區塊同步(IBD)時間 | 一旦被區塊確認,難以驗證的交易會永遠留在區塊鏈上,增加節點完成初始化區塊同步的時間。多次出現這種繁難交易可以顯著拖慢 IBD 速度、增加節點運營成本。 |
區塊體積戰爭
繁難區塊問題也出現在了 “區塊體積大戰(Blocksize War)” 中(從 2015 年持續到 2017 年),作為不要提高區塊體積限制的理由;至少,不能不添加新的限制來約束這個問題的影響。
2015 年 12 月, 比特幣安全研究員 Jonas Nick 在香港的 “Scaling II” 大會上作了一次演講,正是關於這個主題。他解釋了為什麼不應該提高區塊體積限制,除非對比特幣區塊添加一種新的資源使用量限制來緩解這種攻擊的影響。

- 圖片來源:https://youtu.be/vfIs\_trEhao?si=oRu2x6CfWhFbxG2R&t=3692 -
2016 年 1 月,Bitcoin Core 項目網站上出現了一篇博客,解釋了 “隔離見證(SegWit)” 的優點。隔離見證的一個關鍵優點是,修復了 SIGHASH 操作非線性膨脹的 bug 。這就是何以隔離見證看起來是比特幣擴容問題的一個強有力解決方案:它為舊形式的(可能有問題的)交易保持了 1MB 的體積限制,同時,為沒有這個致命漏洞的交易形式提高了區塊體積。

本質上,倍增一筆交易的體積,可以既讓簽名操作的數量倍增,又讓為了驗證每一個簽名而需要哈希的數據的數量倍增。這已經可以在非實驗環境中觀察到:普通的單個區塊只需 25 秒就能驗證,而惡意製作的交易需要超過 3 分鐘來驗證。
2021 年 3 月,我們出版了一本關於區塊體積戰爭的書,其中也討論了最壞情況區塊驗證問題。我們提到,這樣的區塊可能要花 “幾個小時” 來驗證 —— 這跟 2013 年到 2016 年期間流行的說法 “3 分鐘” 差異很大。這是因為,一些比特幣安全研究者向我們提出,他們已經找出了最大限度利用這種攻擊的辦法,因此可以讓情況又惡化許多,因此需要幾個小時來驗證。不過另一方面,也許我們的 “幾個小時” 的說法也有一點不現實,除非你在使用相當低配置的設備(比如樹莓派)。
SIGHASH 操作的非線性膨脹意味著,隨著一筆交易所用的輸入個數增加,驗證這筆交易所需的哈希操作數量會呈平方級增加,而非線性增加。這個膨脹問題是提高區塊體積限制的障礙,因為(解除體積限制之後)攻擊者可以製作出需要花很長時間來驗證的交易、長到讓整個網絡陷入停滯。甚至攻擊者可以構造出一個包含許多這樣的大型交易的區塊,讓普通計算機需要花好幾個小時來驗證。因此,對於許多小區塊主義者而言,修復這個問題是上調區塊體積限制的前提條件。他們嘲諷大區塊主義者因為沒注意到這個弱點而揚揚自得,而且缺乏對抗性思維。
—— 《區塊體積大戰》
惡意區塊的算術
在這一節中,我們準備更細緻地解釋這種攻擊。在攻擊者準備繁難區塊時,他們需要考慮三種比特幣共識限制:
| 規則 | 限制 | 規則激活時間 |
|---|---|---|
| 區塊體積限制(非見證數據) | 1MB | 2010 年 9 月 |
| 腳本體積限制 | 10KB | 2010 年 8 月 |
| 單腳本的操作碼數量限制 | 201 | 2010 年 8 月 |
出於演算的目的,我們解釋的是這種攻擊的最基礎形式,甚至比 Sergio 在 2013 年列舉的還要簡單,當然也是過度簡化的。思路是,攻擊者首先要構造出一些啟動交易,可以假設是放在另一個區塊中,以避免佔用真正觸發攻擊的區塊的 1MB 空間。在這些啟動交易中,攻擊者創建許多輸出,每個輸出都包含 200 個 OP_CHECKSIG 操作碼。有了這些輸出之後,攻擊者就準備好製作真正的攻擊交易了。這筆攻擊交易將所有這些輸出用作輸入,(在我們的場景中)還可以留一個輸出給自己。每個輸入都包含一個有意義的 CHECKSIG 和 200 個無意義的 CHECKSIG(填滿 10KB 的單腳本可用空間)。這就用盡了所有可用的空間,因此最大程度上釋放了這種攻擊的威力。
給定這樣的攻擊交易,我們使用下面的非常基礎的近似公式,來計算驗證攻擊交易時我們需要哈希的數據總量。請注意,在下面的公式中我們包含了一個輸入數量的平方項,以反映 SIGHASH 操作平方膨脹 bug :輸入越多,需要哈希的數據就越多,並且是平方關係。
總共需要哈希的數據(KB) = 201 * N * (10KB + N)其中 N 為交易輸入的數量使用上述公式,我們畫出了下圖,它反映了需要哈希的數據的數量如何取決於攻擊交易中的輸入的數量。可以從這條曲線的形狀看出一個平方函數。上述公式是不精確的,並不能精確地統計需要哈希的數量,它的用意只是演示:非常粗糙地表明這個膨脹問題以及其中的數學關係。
需要哈希的數據數量 vs. 交易輸入的數量

這個表的橫軸停在了略多於 8000 個輸入的地方,這是因為,此時交易的體積已經接近 1MB 了,這是隔離見證以前的交易可以使用的最大空間。為了驗證這筆交易,節點需要哈希超過 30GB 的數據。這就是一筆攻擊交易,在我們這個非常基礎的案例(可能也是不準確的案例)中,可以造成的最壞情況。我們的理解是,需要哈希的數據的數量(而非 ECDSA 簽名的驗證次數)才是衡量這種繁難交易的危險性的關鍵指標,因此我們只關注這個指標。
哈希每 1 KB 需要 0.005 ms(毫秒)時間 —— 這是 Jonas Nick 在 2015 年的演講中提到的數據,他的筆記本電腦是 2014 年生產的(使用雙核 3GHz 的 i7 CPU)。下圖展示了這些攻擊交易可能需要多長時間來驗證。在最壞情況下,需要超過 150 秒來驗證一筆交易,也就是超過兩分半鐘。這顯然是一個致命的漏洞。在我們最近出版的一份報告中(中文譯本),關於節點的性能,我們的節點通常 1 秒能驗證 15 個區塊。因此,(相比常規區塊)這種繁難區塊會大大拖慢驗證速度,大約 2300 倍。
驗證攻擊交易所花的時間 vs. 攻擊交易的輸入的數量

不過,現在的設備比 2015 年的快得多了,而且輸入可以並行驗證。因此,上面這個驗證時間圖,對於今天的設備來說可能有一些保守了。
(譯者注:比特幣網絡上的節點並不全都使用最新的設備,也許一部分節點的計算能力就相當於 2015 年的 i7 雙核 CPU。)
BIP-54 修復措施
BIP-54 所提出的修復措施是比較簡單的:對單筆交易增加新的共識限制來約束下列因素的數量:
- 所有非隔離見證輸入中的 CHECKSIG 和 CHECKMULTISIG 操作碼
- 前序輸出的腳本公鑰
如果一筆交易的上述兩項之和超過 2500,就會被當成無效交易。
有了這些修復措施之後,在我們上文描述的場景中,一筆攻擊交易將只能包含 12 個輸入,一個區塊只能造成 24MB 需要哈希的數據,只需要 0.1 秒就能驗證。問題看起來是很好地解決了,至少在我們這個非常基礎的案例中是這樣。
結論
再次強調,我們的計算和案例都是非常基礎的,絕對簡化過頭了。還有一些聰明的技巧,可以讓攻擊更加嚴峻(準確來說是大上幾一個量級)。比如說,可以添加使用長腳本的輸出,使進一步增加需要哈希的數據數量。在這些極端情形中,繁難區塊可能演變成比特幣網絡的危機,因為光這一個區塊就要超過 1 個小時來驗證,很大一部分節點可能暫時離線甚至不再回來。
不過,幸運的是,這種攻擊實施起來是非常複雜的。首先,攻擊需要發送一些非標準的交易,很可能只有礦工才能發起攻擊。即使使用直接向礦工提交交易的服務(例如 Matathon 的 Slipstream),礦工可能也會有一些內置的安全邏輯、不會幹坐在那裡花費幾個小時來驗證這筆提交過來的交易。其次,這些最壞情形涉及多筆複雜的啟動交易,在繁難區塊生產出來之前,就要佔據許多區塊的空間。如果攻擊者不是那麼謹慎的話,很可能觀察比特幣網絡的人就能監測到這些啟動交易,然後提醒用戶需要緊急軟分叉,也許這可以防止攻擊(當然,也許不能)。因此,這個漏洞,從這個角度看,與 “時間扭曲攻擊” 有相似之處。
不過,雖然攻擊有其複雜性,在我們看來,這是比特幣的一個非常嚴重的問題,需要修復。它可能是 BIP-54 意圖修復的四個問題中最嚴重的一個。根據嚴重性從高到低,我們將這四個問題排名如下:
- 繁難區塊
- 時間扭曲攻擊
- 64 交易交易
- 重合交易
(完)

