跨鏈橋並不搬運任何東西。它是在一條鏈上做出一個聲明,再讓另一條鏈據此行動;而每一次橋被打穿,都是第二條鏈採信了一個本該拒絕的聲明。所以給跨鏈橋的風險分類,靠譜的做法是按信任假設,而不是按產品名字:目的鏈究竟在相信什麼,以及要讓它相信一件假事需要付出什麼。本文按這條線索走五個結構性來源,從外部驗證者集合一直講到升級權限。
先問一句:到底誰在驗證
以太坊官方開發者文件把跨鏈橋的安全性壓成了一個問題:誰來驗證這套系統?手續費、速度、能連多少條鏈,全都在這個問題的下游。
機制本身很少變花樣。源鏈上發生了某件事。某個角色出具證明說它發生了。目的鏈上的合約拿這份證明去對一條規則,通過就放幣或鑄幣。攻擊者想要的一切,都在這條規則的另一頭。
該文件把設計分成兩族。受信任型的橋由外部驗證:一個帶多簽的聯盟、一套多方計算系統,或者一個預言機網絡。無需信任型的橋依託它所連接的兩條鏈和這兩條鏈自己的驗證者,不新增信任假設。前一族買到的是連通性與速度,代價記在安全性上——由外部驗證者保障的橋,通常弱於由鏈本身原生保障的橋。
押在上面的錢讓這筆交換不留情面。截至 2022 年 8 月,Chainalysis 統計到 13 起獨立的跨鏈橋被盜事件,合計約 20 億美元,約佔當年到那時為止全部被盜金額的 69%。橋之所以吸引攻擊,是因為它把抵押品堆在了那條規則被檢查的同一個點上。
所以下面幾節按假設排列,而不是按事件排列。兩座名字不同、驗證模型相同的橋,會以相同的方式失敗;而記住名字,並不能告訴你手上這一座是什麼。
外部驗證者集合是一套你沒審計過的系統
最常見的受信任設計,是在兩條鏈之間放一組 N 個角色。他們盯著源鏈,為發生過的事件簽名出證;目的鏈的合約只要驗到其中至少 M 個簽名,就予以接受。除此之外,這份合約對現實沒有任何別的看法。
結論很直白:誰控制了 M 把密鑰,誰就能鑄幣。設一組 9 人、門檻為 5。攻擊者拿到 5 把密鑰,不需要合約漏洞,不需要任何一條鏈出問題,也不需要再過別的檢查。他把橋掏空的整個過程,橋都在嚴格按設計行事。
留意你真正買到的是什麼安全性。驗證者集合是它自己的一套系統,有自己的營運方、機器與激勵,從它連接的兩條鏈那裡什麼都繼承不到。由外部集合驗證的橋,強度就等於這組集合的強度,不會更高——兩側的網絡再大也一樣。
所以值得問的是成員問題。這 N 個是誰,有沒有公開過?他們是彼此獨立的機構,還是一家機構開著九台機器?M 是多少?成員手裡有沒有押著一旦簽了假訊息就會被沒收的東西?以及,誰能改這份名單——因為一把密鑰就能改寫的集合,本質上是一座披著委員會外衣的單簽橋。
門檻有沒有用,取決於密鑰會不會一起失效
M-of-N 是一句關於獨立性的話,不是一道算術題。九選五比一選一更難,前提是這九把密鑰能以九種互不相關的方式失效。
而它們常常做不到。同一家公司裡的密鑰,共用一套入職流程、一份筆記型電腦裝機映像、一條 VPN、一個雲端密鑰服務和一個簽名介面。如果同一封釣魚郵件能同時夠到九個持有人,或者其中五把就放在同一個雲端帳戶裡,那麼 N 只是儀表板上的一個數字,真實的 N 更接近 1。
把門檻往上調修不好這件事,而且要付代價。M 定得高,丟掉幾把密鑰就會讓橋根本簽不出字:錢沒被偷,但也沒人動得了,資產卡在錯誤一側的人只能等。每一個門檻,都是在「太容易被偷」和「太容易被凍住」之間選一個位置。
簽名環節值得和託管一樣多的注意。簽名者批准的是他們基本讀不懂的載荷;如果介面顯示的是一句友善的摘要,而底下的位元組說的是另一回事,那麼誠實的簽名者也會產出一個有效的惡意簽名。盲簽會把 M-of-N 的委員會變成 M-of-N 的橡皮圖章,而門檻對此毫無防護。
輕客戶端與樂觀驗證賭的不是同一件事
最小化信任的那幾種設計去掉了外部集合,但它們沒有去掉信任,只是把信任挪了個地方。挑大樑的是兩族。
輕客戶端驗證,是把源鏈的一個客戶端放進目的鏈裡。目的鏈保存源鏈的共識狀態,再檢查被聲稱的事件能否對著它給出證明。在 IBC 裡,連接的每一側都用對方鏈的輕客戶端來驗證進來的訊息,於是假設收縮成兩條:源鏈的共識,加上客戶端代碼本身寫得對。IBC 的新版本把話說得更明白——所謂客戶端只是一種驗證模型,它同樣可以是輕客戶端、多簽,或者一個證明驗證器。名字不等於假設,客戶端類型才是。
樂觀驗證走的是反方向:先臨時接受這條訊息,再給任何人一個時間窗去證明它是假的。它的假設是,至少有一個監督者在跑、有錢,並且能在窗口關閉前把挑戰交易送上鏈。一個在窗口期間掉線、沒手續費或被審查的監督者,和沒有監督者是一回事。
兩族都不免費,而且代價是結構性的,不是偶然的。輕客戶端對每一對鏈都要花 gas 和工程量,客戶端裡的一個 bug 就是規則本身的 bug。樂觀設計接起來便宜,但會讓每一個誠實用戶白等一段由設計者定下的延遲。以太坊文件把兩邊的代價都寫明了:輕客戶端型的橋受限於連通性,樂觀型的橋受限於速度。
重放:同一條有效訊息被算了兩次
一條跨鏈訊息就是一份授權。重放這種攻擊,是把一份確實簽發過的授權再拿出來用一次:可能是在同一個地方來第二次,也可能是拿到一個它壓根沒打算適用的地方去用第一次。沒有任何東西被偽造,只是同一串有效位元組被重複使用。
以太坊自己的歷史裡就有那個標準答案。EIP-155 把 chain ID 摺進了參與雜湊與簽名的數據,於是為一條鏈做出的簽名,在另一條鏈上驗不過。留意它是怎麼落地的:舊的六元素格式仍然有效——也就是說,這層保護是簽名方選擇加入的,而不是格式本身給的保證。
而對於跨鏈橋真正在傳的那類結構化訊息,EIP-712 定義了一個域分隔符。它可以攜帶名稱、版本、chain ID 和驗證合約的地址,外加一個作為最後手段的 salt;標準裡還寫明,當 chain ID 與用戶當前所在的鏈對不上時,錢包應當拒絕簽名。換一條鏈、換一個合約、換一個版本,就是另一條訊息。這就是「域分隔」在實踐中的意思:把目的地放進被簽的內容裡。
域分隔仍然攔不住同一條訊息被送到同一個目的地兩次。EIP-712 自己就這麼說:這份標準只管簽名,不含重放保護,所以應用必須自己拒絕重複的那一條,或者把被授權的動作做成冪等的。這份活歸 nonce、序列號,或者一份已消費訊息的記錄來幹。
IBC 展示的是拼完整之後的樣子。恰好一次投遞是協議明寫的性質:每個數據包帶一個序列號,接收鏈在這個序列號下寫一條回執,回執已經存在的數據包會被拒收。規範裡點明,這就是簽名訊息那套序列號問題,只不過簽名者的位置換成了輕客戶端。只驗證、不去重,那只是半座橋。
升級權限凌駕於其餘所有假設之上
上面說的全都是一座橋今天在執行的那條規則。升級權限決定的是:明天誰能把這條規則換掉。
多數跨鏈橋合約是代理合約,而 ERC-1967 把代理的接線位置標準化了:一個儲存槽放它委託過去的實現地址,另一個儲存槽放被允許更換這個實現的 admin 地址。admin 發一筆交易,代理就指向新代碼,而新代碼想怎麼定義「有效」都行。
這讓升級權限成了本文其餘所有風險的超集。九把密鑰的驗證者集合、輕客戶端、挑戰窗口——控制著 admin 槽的那一方都能把它們換掉。一座橋的安全上限,老實說等於驗證模型和升級路徑裡更弱的那一個。
讓人安心的是,這一條是可以自己查的。標準告訴了你去哪裡看,並要求這些槽位發生變化時發出事件:實現變了發 Upgraded,admin 變了發 AdminChanged。去讀那個 admin 槽。看看它放的是一個外部帳戶、一個多簽,還是一個時間鎖;如果是時間鎖,再看延遲多長、誰有權取消。
暫停權與參數調整權值得同樣讀一遍。叫停一座橋、或者調高一檔轉帳上限,比重寫規則的權力小,但它同樣是握在某個人手裡的一把鑰匙;而一座能被暫停的橋,也能在你的轉帳走到一半時被暫停。
結語
一旦問出「誰在驗證」,跨鏈橋的風險就分得很乾淨。外部驗證者集合是一套獨立的系統,它的門檻就是它的安全預算;而這個門檻能不能立住,取決於背後的密鑰會不會一起失效。輕客戶端把假設挪到源鏈的共識和客戶端代碼的正確性上;樂觀設計把假設挪到至少有一個監督者在整個窗口期裡活著且沒被攔住。重放保護是與驗證並列的另一項要求:目的地必須是被簽內容的一部分,每條訊息都需要一個序列號或一條回執。而凌駕在這一切之上的是升級權限,它一筆交易就能把其餘部分全部替換。你過橋時真正信任的,是這五個答案,而不是介面上的那個品牌。
風險披露:本文為 Bitbase(幣貝)學院的科普內容,僅供教育與資訊參考,不構成任何投資、交易、稅務或財務建議。加密資產波動劇烈,請自行評估風險。本文撰寫於 2026 年 8 月,請以官方最新資訊為準。
參考資料
[1] Ethereum.org, developer documentation, Bridges ethereum.org
[2] Chainalysis, Vulnerabilities in Cross-chain Bridge Protocols Emerge as Top Security Risk chainalysis.com
[3] EIP-155: Simple replay attack protection eips.ethereum.org
[4] EIP-712: Typed structured data hashing and signing eips.ethereum.org
[5] ERC-1967: Proxy Storage Slots eips.ethereum.org
[6] IBC-Go documentation, protocol overview docs.cosmos.network
[7] Inter-Blockchain Communication Protocol, ICS-004: Channel and Packet Semantics github.com






