逃生艙不是功能按鈕,而是資產安全邊界
ZK-Rollup 的使用者體驗通常依賴排序器(Sequencer):使用者把交易提交給排序器,排序器打包批次,證明者生成有效性證明,L1 合約更新狀態根。正常情況下,這條路徑比 L1 便宜得多。但一旦排序器拒絕處理提現、長時間離線、選擇性審查某個地址,使用者就會遇到 Rollup 最關鍵的安全問題:資產在 L2 狀態裡是自己的,但自己無法讓系統把它釋放回 L1。
逃生艙(Escape Hatch)和強制提現(Forced Withdrawal)的目標,就是讓使用者在排序器不合作時仍能單方面退出。它不是“更快提現”的產品功能,而是對審查風險和運營故障的最後約束。對 [AllSwap 跨鏈交換](/exchange-swap) 這類無託管路由入口,逃生艙決定了異常路徑是否可退款、是否可歸因,以及使用者資產是否會因為目標 Rollup 停機或排序器拒絕打包而卡在中間狀態。
本文討論 ZK-Rollup 場景,不把 optimistic challenge game、中心化託管交易所內部賬本或普通跨鏈橋多籤混在一起。核心問題只有一個:當 L2 不能或不願執行使用者提現請求時,L1 合約需要哪些狀態、證明和時鐘規則,才能讓使用者在不信任排序器的情況下取回資產?
系統模型:L1 只儲存狀態根,使用者儲存證明材料
一個典型 ZK-Rollup 至少包含五類物件:
- L2 狀態樹 `S_t`:記錄賬戶餘額、nonce、訂單、倉位或 UTXO; - L1 Rollup 合約 `R`:儲存最新已驗證狀態根 `root_t`; - 排序器 `Seq`:收集交易並生成批次; - 證明者 `P`:為批次生成 ZK proof; - 使用者 `U`:持有賬戶金鑰、本地狀態證明和提現意圖。
正常提現路徑是:使用者向 L2 提交 withdrawal,排序器納入批次,證明者證明狀態轉移,L1 合約接受新 root,使用者在 L1 finalize withdrawal。強制提現路徑則要繞開排序器:
1. 使用者在 L1 提交強制提現請求; 2. Rollup 協議把該請求強制注入 L2 佇列或凍結視窗; 3. 若排序器在期限內處理,走正常批次; 4. 若排序器不處理,使用者用最新可用狀態根和 inclusion proof 觸發逃生; 5. L1 合約驗證資產屬於使用者且未被消費,釋放或標記可提取。
最小安全命題可以寫成:
`Withdraw(u, a, root_t, proof, nullifier) is valid`
當且僅當 `proof` 證明使用者 `u` 在 `root_t` 下擁有金額 `a`,`root_t` 是 L1 已接受的狀態根,且 `nullifier` 未被使用。這個命題看似簡單,但每個變數都很容易出錯:root 可能過時,proof 可能對應舊餘額,nullifier 可能沒有覆蓋全部重放路徑,資產可能已經在後續 L2 狀態中被消費。
強制入隊和逃生艙是兩層機制
很多討論把 forced transaction、forced withdrawal、escape hatch 混成一個概念。工程上它們應拆開。
強制入隊是活性機制。使用者在 L1 提交一個請求,要求排序器必須在某個視窗內把它納入 L2 批次。Arbitrum delayed inbox 和 OP Stack forced transactions 都屬於這類設計:L1 提供一個繞過排序器普通 mempool 的入口,防止 sequencer 永久審查使用者交易。對 ZK-Rollup,強制入隊可用於要求 L2 處理提現或退出操作。
逃生艙是失敗終局機制。當排序器不處理強制入隊,或系統進入凍結/撤退模式,使用者不再等待 L2 繼續出塊,而是在 L1 用狀態證明直接退出。StarkEx 文件中的 forced withdrawal 和 freeze request 體現了這種思路:使用者先請求服務方處理,若未在視窗內處理,可觸發凍結,凍結後使用者透過鏈上機制撤回資產。
兩者的差別是:強制入隊仍假設 Rollup 會繼續執行;逃生艙假設 Rollup 已經不能提供正常服務。AllSwap 路由在判斷目標鏈風險時,也應區分這兩層:一條鏈有 force inclusion,不代表它有完整 escape mode;有逃生艙,也不代表日常提現不會慢。
還有第三層經常被忽略:證明材料獲取。強制入隊和逃生艙都寫在合約裡,並不代表使用者一定拿得到帳戶 leaf、Merkle path、歷史批次資料或 UTXO opening。一個嚴肅的 Rollup 退出設計,需要讓使用者、錢包、索引器或第三方資料服務在正常時期持續儲存可退出 witness。否則真正停機時,使用者才發現自己只有餘額截圖,沒有可提交給 L1 的證明。
L1 合約需要驗證什麼
逃生艙的核心不是“使用者上傳一條 Merkle proof 就能提現”。L1 合約至少要驗證四件事。
第一,狀態根有效。使用者證明必須基於 L1 已接受的 `root_t`。若允許使用者引用未驗證 root,逃生艙就退化成信任使用者或排序器。
第二,資產所有權。證明路徑必須繫結賬戶、資產 ID、金額、nonce 或 UTXO commitment。賬戶模型裡通常證明 `(owner, token, balance, nonce)`;UTXO/record 模型裡通常證明 note 或 commitment 的 inclusion。
第三,未消費性。若使用者能用舊 root 證明自己曾經擁有資產,但資產已在後續狀態中轉出,就會出現重放提現。解決方式通常是 nullifier、exit nonce、forced withdrawal request id 或“只能基於凍結前最後狀態”的全域性撤退規則。
第四,退出金額上界。合約不能只看 proof 裡的金額,還要檢查該資產在 L1 escrow 中可釋放、該使用者沒有重複退出、以及手續費或部分提現規則沒有製造負餘額。
虛擬碼可以壓縮為:
`require(acceptedRoot[root_t])`
`require(verifyInclusion(root_t, accountLeaf, proof))`
`require(accountLeaf.owner == msg.sender)`
`require(!spent[nullifier])`
`spent[nullifier] = true`
`release(token, msg.sender, amount)`
順序也重要。`spent[nullifier]` 應在外部轉賬前寫入,避免重入或重複提交。proof 的 public inputs 應繫結鏈 ID、Rollup ID、資產合約、使用者地址和退出模式,否則跨例項重放會成為現實風險。
更完整的逃生合約通常需要四個狀態:`normal`、`forceRequested`、`frozen`、`withdrawOnly`。`normal` 下接受普通批次;`forceRequested` 下開始計時,等待排序器處理指定請求;`frozen` 下停止接受新批次,防止狀態繼續變化;`withdrawOnly` 下只允許使用者提交退出證明和領取資產。狀態切換必須單調,不能讓管理員在使用者開始逃生後隨意恢復到普通模式,否則使用者可能基於一個凍結 root 準備 proof,卻在提交前被新的狀態根覆蓋。
管理員許可權也是風險點。逃生艙如果依賴單一管理員手動開啟,就不能對抗管理員本身作惡。更合理的設計是把“未處理強制請求超過視窗”作為可公開觸發的條件;任何人都能提交證據讓合約進入 frozen 或 withdrawOnly。管理員可以有暫停惡意攻擊的權力,但不應擁有阻止合法退出的最終權力。
舊證明重放是最難看的失敗路徑
逃生艙最危險的 bug 不是證明驗證失敗,而是證明驗證“正確但語義過期”。假設使用者在 `root_100` 下有 100 USDC,之後在 L2 花掉 80 USDC,到 `root_110` 只剩 20 USDC。如果系統允許使用者在凍結後拿 `root_100` 的 inclusion proof 直接退出 100 USDC,而沒有 nullifier 或最後有效 root 規則,就會破壞 L1 escrow 的守恆。
因此逃生艙必須回答:使用者可以基於哪個 root 退出?常見設計有兩種。
一種是凍結模式:系統在某個 frozen root 停止推進,所有退出都基於這個 root。好處是邏輯清晰;壞處是凍結前沒有及時同步本地 proof 的使用者可能需要依賴資料可用性恢復狀態路徑。
另一種是強制請求模式:使用者先在 L1 登記退出請求,後續證明必須繫結該 request id 和登記時間。若排序器沒有處理,使用者才能走 L1 逃生。好處是減少舊 root 濫用;壞處是使用者必須先發起強制請求,不能在完全離線後才發現自己沒有登記。
無論哪種方式,都需要資料可用性。使用者必須能拿到狀態樹路徑、賬戶葉子或 UTXO witness。若 Rollup 把資料放在鏈下 DAC 或中心化服務裡,逃生艙在 DAC 合謀 withholding 時可能失效。這就是 Validium 與 Rollup 在逃生能力上的本質差別之一。
舊證明重放還會出現在跨資產場景。假設同一使用者在 L2 同時持有 USDC、USDT 和某個 LP token,退出 proof 若只繫結 owner 和餘額,而沒有繫結 token address、chain id、rollup id 和資產 registry,就可能被錯誤解釋為另一種資產的退出。L1 逃生合約必須把 proof 的 public inputs 設計成完整語義,而不是隻驗證一條路徑存在。
強制提現的時鐘設計
強制提現必須有明確時鐘,否則不是安全機制,而是客服流程。時鐘至少包含三個視窗。
第一,排序器響應視窗。使用者在 L1 提交 forced request 後,排序器有多少時間把它納入 L2 批次?視窗太短會誤傷正常擁堵,視窗太長會讓審查持續太久。
第二,證明提交視窗。即使排序器納入交易,ZK proof 也可能延遲。系統要區分“已執行但 proof 未上鍊”和“未執行”。這影響使用者何時可以升級到逃生模式。
第三,撤退視窗。進入凍結或 escape mode 後,使用者多久內可以提交 proof?如果沒有截止,合約長期保留大量狀態;如果截止過短,離線使用者可能錯過退出。
這些視窗應進入路由風險模型。對 AllSwap 來說,目標鏈是否支援 forced withdrawal,不應只是布林值。更有用的引數是 `forceRequestDelay`、`proofLag`、`escapeModeAvailable`、`dataAvailabilityMode` 和 `maxExitWindow`。大額跨鏈交換應該避開強制退出視窗過長、資料可用性弱或逃生模式不清晰的路徑。
時鐘還要考慮 L1 擁堵。真正需要逃生艙的時候,往往不是市場平靜期,而是排序器事故、價格劇烈波動或系統性清算壓力。此時 L1 gas 可能上升,所有使用者同時提交 forced withdrawal 或 exit proof。若逃生艙只在理論 gas 成本下可用,實際危機中就會變成“有門但擠不出去”。批次退出、證明聚合、分階段 claim 和 gas 補貼機制,都是逃生艙可用性的一部分。
批次退出可以降低 L1 壓力,但會引入新的協調風險。若多個使用者的 exit proof 被聚合成一個批次,聚合者必須不能篡改收款地址,也不能扣留某個使用者的 claim。一個穩健模式是:聚合 proof 只證明一組 withdrawal claim 有效,實際領取仍由每個使用者按自己的 claim id 執行。這樣聚合者幫助節省 gas,但不能成為新的託管方。
排序器審查、停機和部分失敗
逃生艙要覆蓋至少三種失敗。
第一,選擇性審查。排序器繼續為其他使用者出塊,但拒絕某個地址或某類提現。強制入隊可以把請求放到 L1 可見佇列,迫使排序器處理或留下可證明審查證據。
第二,全域性停機。排序器或證明者長期離線,Rollup 不再更新 root。這時強制入隊沒有意義,系統必須進入凍結或 escape mode。使用者是否能退出,取決於最後可用狀態根和資料可用性。
第三,部分執行失敗。使用者的跨鏈交換在源鏈已扣款,目標 Rollup 因排序器問題沒有到帳。此時 AllSwap 需要明確失敗發生在源鏈鎖定、目標鏈執行、proof 提交還是 L1 finalize。逃生艙能解決的是“目標 Rollup 內部資產如何退出”,不能自動補償源鏈和目標鏈之間的所有經濟差額。
第四,證明者延遲。ZK-Rollup 的排序器可能處理了提現,但證明者沒有及時提交有效性證明。使用者在 UI 中看到“已執行”,但 L1 合約還沒有接受對應 root。這種狀態不應被展示為最終到帳。路由系統應區分 `executedOnL2`、`provedOnL1` 和 `claimableOnL1`,否則使用者會誤判資金是否真正可退出。
第五,逃生佇列擁堵。凍結模式下,所有使用者都可能同時退出。若 L1 合約逐筆驗證昂貴 proof,佇列會被大戶、機器人或套利者優先佔據。協議需要考慮公平排序、每賬戶限速、批次 proof 或分資產視窗,避免逃生艙在危機中被少數參與者耗盡區塊空間。
對 AllSwap 路由的影響
AllSwap 路由可以把 Rollup 出口安全分成四級:
- `normal-withdrawal`:只依賴排序器正常處理; - `force-inclusion`:使用者可在 L1 強制請求排序器納入交易; - `escape-mode`:排序器失敗後可基於狀態證明單邊退出; - `full-recovery`:退出 proof、資料可用性、退款地址和補償狀態都有可驗證路徑。
路由評分可以寫成:
`routeScore = priceScore + speedScore - exitRiskPenalty - daPenalty - refundUncertainty`
其中 `exitRiskPenalty` 來自強制提現能力,`daPenalty` 來自資料可用性模式,`refundUncertainty` 來自失敗後能否證明和釋放資金。最低手續費路徑如果沒有逃生艙,不一定適合大額交易;稍慢但有 force inclusion 和 escape mode 的路徑,在風險調整後可能更優。
對使用者介面,表達可以保持克制:不用展示所有證明細節,但應在高風險路徑上提示“目標 Rollup 退出依賴排序器正常服務”或“支援 L1 強制退出但預計視窗較長”。在 [/fees](/fees)、[/swap/usdt-erc20](/swap/usdt-erc20)、[/assets/usdc](/assets/usdc) 這類路徑中,費用不只是 gas,也包括失敗恢復的時間和證明成本。
後臺狀態也要足夠細。每筆跨鏈交易至少應能落到這些狀態之一:`submitted`、`sequenced`、`proved`、`claimable`、`forceRequested`、`escapeAvailable`、`refunded`、`failedFinal`。如果所有異常都顯示成“處理中”,使用者無法判斷自己應該等待、補交 proof、發起強制請求,還是聯絡路由器處理源鏈退款。對無託管產品來說,狀態透明本身就是安全功能。
對於 Solver 路徑,逃生能力還影響保證金設計。若 Solver 在目標 Rollup 預墊資產,但 Rollup 後續進入凍結模式,Solver 的再平衡資金可能被鎖。路由器需要知道這條路徑的逃生視窗和資料可用性,否則 Solver 會把風險溢價轉嫁給使用者,或在高波動時直接撤出流動性。
這也是為什麼“是否支援逃生艙”不能只存在於內部風險文件。路由器至少應把它折算成價格、限額或提示:無 escape 的鏈降低單筆上限;資料可用性弱的鏈提高風險溢價;force request 視窗過長的鏈不適合即時到帳承諾。這樣產品不用向每個使用者解釋 Merkle proof,卻仍然把底層安全差異反映在路由結果裡,避免把風險藏到後臺和客服流程中,這一點非常關鍵且必要安全。
仍未解決的問題
第一,賬戶模型和 UTXO 模型的逃生證明差異很大。賬戶模型需要處理 nonce、餘額更新和舊 proof 重放;UTXO 模型需要處理 nullifier、note 隱私和批次退出。統一 UI 很難表達這些差異。
第二,資料可用性仍是逃生艙的硬前提。若使用者拿不到 witness,L1 合約即使支援 escape,也無法憑空恢復狀態路徑。Validium、Volition、Rollup 的逃生語義不能混用。
第三,凍結模式會傷害正常使用者。系統一旦 frozen,所有使用者都進入低效撤退路徑。何時凍結、誰能凍結、惡意凍結如何懲罰,是治理和經濟學問題。
第四,跨鏈交換的退款可能跨越多個系統。目標 Rollup 能逃生,不代表源鏈資產能自動解鎖,也不代表 Solver 已補償。路由層需要把 Rollup escape proof 和跨鏈 swap refund proof 接起來。
第五,強制提現的 UX 仍然很差。使用者可能需要儲存證明、支付 L1 gas、等待視窗、理解 nullifier。真正可用的逃生艙需要錢包、索引器和路由器共同把複雜性隱藏在可驗證流程後面。
第六,跨域逃生還缺少標準介面。今天每個 Rollup、Validium、Volition 或應用鏈的強制退出方式都不同。對聚合器來說,最需要的不是統一 UI 文案,而是機器可讀的 `exitCapabilities`:是否可強制入隊、是否可凍結、證明型別、DA 模式、最長等待視窗、是否支援批次退出、是否支援第三方代提交 proof。沒有這類介面,路由器只能把所有 L2 風險粗暴歸為同一類。
References
[1] StarkEx Forced Transactions and Freeze Request, StarkWare Docs, 2026, https://docs.starkware.co/starkex/perpetual/performing-forced-transactions.html
[2] StarkEx Data Availability, StarkWare Docs, 2026, https://docs.starkware.co/starkex/con_data_availability.html
[3] ZKsync Era Priority Queue, ZKsync Docs, 2026, https://docs.zksync.io/zksync-protocol/contracts/l1-contracts
[4] ZKsync Era Protocol Overview, ZKsync Docs, 2026, https://docs.zksync.io/zksync-protocol
[5] Arbitrum Delayed Inbox and Censorship Resistance, Arbitrum Docs, 2026, https://docs.arbitrum.io/how-arbitrum-works/sequencer
[6] OP Stack Forced Transactions and Sequencer Censorship Resistance, Optimism Docs, 2026, https://docs.optimism.io/stack/transactions/forced-transaction
[7] L2BEAT Stages and Rollup Risk Framework, L2BEAT, 2026, https://l2beat.com/scaling/summary
[8] Validium, Ethereum.org, StarkWare, 2020, https://ethereum.org/en/developers/docs/scaling/validium/
[9] Rollups, Validiums, and Disconnected Exits, Vitalik Buterin, 2021, https://vitalik.eth.limo/general/2021/01/05/rollup.html
[10] Plasma and Mass Exit Background, Ethereum.org, Kelvin Fichter, 2019, https://ethereum.org/en/developers/docs/scaling/plasma/
常見問題
ZK-Rollup 逃生艙和普通提現有什麼差異?
普通提現依賴排序器把請求納入批次並等待證明上鏈;逃生艙用於排序器審查、停機或系統凍結時,讓使用者基於 L1 已接受狀態根和狀態證明單邊退出。
強制提現一定能保證使用者拿回資產嗎?
不一定。強制提現還依賴資料可用性、可提交的狀態證明、未被使用的 nullifier、L1 gas 可承受,以及逃生合約沒有管理員阻止合法退出。
為什麼舊證明重放是逃生艙的關鍵風險?
使用者可能用舊狀態根證明自己曾經擁有資產,但資產後來已在 L2 花掉。逃生合約必須用 nullifier、凍結 root 或 request id 防止舊 proof 重複提現。
AllSwap 路由為什麼要關注 Rollup 逃生能力?
目標 Rollup 若缺少強制入隊或逃生艙,跨鏈交換失敗時可能只能等待排序器恢復。路由評分應把退出視窗、DA 模式和退款證明納入風險成本。
Validium 的逃生能力和 Rollup 一樣嗎?
不一樣。Validium 通常把資料放在鏈下委員會或服務中,若資料不可用,使用者可能拿不到退出所需 witness。Rollup 把資料發布到鏈上,逃生證明更容易恢復。


