比特幣軟體出現嚴重漏洞時,網路怎麼修?

比特幣軟體出現嚴重漏洞時,網路怎麼修?的文章封面插畫

2010 年 8 月,仍很年輕的比特幣網路曾接收一個含異常交易的區塊。程式在加總輸出金額時發生整數溢位:數字超出可表示範圍後,計算結果繞回較小值,因而沒有攔下遠超供給規則的金額。修正版隨後發布;採用修正的礦工與全節點改用新的判斷,網路最後延續未包含那筆異常交易的歷史。

這段經歷常被濃縮成「漏洞很快就修好了」。不過,漏洞不會自行消失,也沒有中央伺服器能讓所有參與者同時更新。有人必須找出問題、提出修補、測試新版並說明風險,實際運行軟體的人還得決定是否安裝。只要部分機器仍照舊判斷,同一份資料就可能得到不同答案。

因此,理解比特幣如何面對嚴重漏洞,第一步是分清錯誤影響哪一層。某些問題只讓一款應用程式顯示錯誤;某些問題會使大量機器當機或無法傳播資料;最棘手的問題則碰到共同驗證規則,可能讓網路對有效帳本產生分歧。三者都值得修,復原方式與波及範圍卻很不一樣。

同樣叫漏洞,影響可能差很多

若某款錢包把餘額顯示錯誤,鏈上的紀錄未必跟著改變。若它產生私鑰的方式有缺陷,使用者可能失去控制權,但其他參與者仍可依原有規則驗證交易。這類事故可能非常嚴重,修補應用程式卻通常不必改動全網共識。

網路通訊或資料處理的漏洞又是另一層。例如,特製訊息可能讓某個版本耗盡資源或崩潰。受影響的機器會離線,服務能力也可能下降;只要其餘參與者仍能對有效資料得出相同結論,問題主要落在可用性,而非共同歷史已經改寫。

共識層漏洞的風險最高。假如兩套實作對同一筆交易或區塊得到相反判斷,一部分節點可能沿著某段歷史前進,另一部分則拒絕它。錯誤若牽涉發行上限、重複花費或腳本驗證,還可能直接動搖大家原本以為由程式保證的邊界。2010 年的溢位事件就屬於這一類。

發布修正版,只完成了修復的一半

漏洞通常先要被穩定重現,維護者才能確認哪些版本受影響、攻擊者需要什麼條件,以及修補會不會另造問題。高風險細節有時會先限縮披露範圍,讓修正版有時間發布;等到使用者有合理機會升級,再公開較完整的技術資訊。這種延後能降低立即利用的機會,也會讓外界暫時難以獨立核對全部判斷。

開發者可以修改原始碼、加入測試並發布版本,卻無法從遠端替所有節點按下更新鍵。全節點操作者、礦工、交易平台及其他服務各自決定何時升級。若漏洞可能被立即利用,部分服務也可能暫停收付,等修正版擴散或風險邊界更清楚後再恢復。

這正是修復速度與分散控制之間的張力。集中式服務能由單一營運者迅速部署,但使用者必須接受它的決定;比特幣參與者可以檢查、拒絕或延後新版,代價是緊急協調較慢,也可能在過渡期間留下不一致。

發生分歧時,歷史怎麼重新靠攏

假設漏洞已讓兩群節點接受不同歷史,修正版必須明確界定哪些資料應被拒絕。升級後的節點會在自己認定有效的候選鏈中,比較累積工作量;它不會只因另一條鏈算力較多,就接受新版規則已判定無效的區塊。礦工若希望自己產生的區塊被這些節點接受,也要在相容的歷史上繼續工作。

當足夠多的礦工、節點與收付款服務採用相同修正,一條共同接受的鏈可能累積較多工作量,參與者因而重新收斂。先前看似已收入歷史的交易也可能因重組而失去交易確認。這就是緊急修復為何不能只看新版下載數量;還要看實際驗證、產生區塊與經濟活動是否回到相容狀態。

這個過程帶有人的判斷。哪些行為算漏洞、修正版是否忠於既有意圖、要不要拒絕已出現的資料,都需要公開說明與廣泛採用。程式最終會執行具體條件,但把哪套程式放進機器裡,仍由人與組織選擇。網路能重新收斂,不代表某位開發者單方面改寫了所有人的紀錄。

修得了程式,不一定救得回所有損失

若問題只造成顯示錯誤,升級後或許能重新從鏈上資料算出正確狀態。若弱點已讓私鑰外洩、資產被有效簽署轉走,修好錢包不會自動取回控制權。若服務曾因錯誤的確認狀態交付商品,後續歷史重組也可能留下現實損失。

軟體多樣性同樣有兩面。不同實作能降低所有人依賴同一套程式的程度,也能讓研究者彼此比對結果;可是,只要它們在共識細節上出現微小差異,就可能造成分裂。大量使用同一實作有助於行為一致,卻也會讓其中一個缺陷同時影響更多節點。這項取捨沒有靠一句「開源」就消失。

所謂不可竄改,也有清楚的適用範圍。當參與者遵循相容規則並對有效歷史形成共識後,任意改寫舊紀錄需要付出極高成本;這不表示軟體永遠不會出錯,更不表示人們遇到漏洞時只能袖手旁觀。嚴重事故發生時,重新檢查規則、發布修補並協調採用,本來就是系統復原的一部分。

較準確的結論是:比特幣能修漏洞,因為軟體可以被檢查與替換;它又無法保證瞬間修好,因為沒有任何一方能強迫全網同步升級。真正的韌性來自問題能否被發現、修補能否被驗證,以及足夠多彼此獨立的參與者能否重新採用相容規則。去中心化沒有消除人的角色,它改變的是任何人介入修復時,必須如何取得其他參與者的接受。