跨鏈輕客戶端真正貴的不是 Merkle Proof
跨鏈狀態驗證最容易被低估的成本,不是驗證一條 Merkle inclusion proof,而是驗證“這條狀態根到底是不是源鏈共識認可的狀態根”。如果目標鏈是 EVM,源鏈是 Tendermint、Solana、NEAR 或其他使用 Ed25519、不同哈希函數、不同狀態樹佈局的系統,目標鏈合約要麼直接重放源鏈輕客戶端邏輯,要麼相信一組外部驗證者,要麼把源鏈共識檢查壓縮成零知識證明(ZK proof)。ZK-Light Client 的價值就在第三條路徑:把昂貴的異構簽名、驗證者權重、區塊頭更新和狀態根檢查放到鏈下證明,在目標鏈只驗證一個簡潔證明。
但這個方案不是“用 ZK 就免費”。真正的瓶頸是非原生字段算術(non-native field arithmetic)。Ed25519 的有限域、Solana 的哈希時間序列、Tendermint 的驗證者投票權重、Ethereum 的 BLS12-381 和 BN254/小字段 STARK 體系之間並不天然同構。證明系統的底層字段不匹配時,一個源鏈簽名驗證會被拆成大量 limb、range check、carry 約束和模約減。對 [AllSwap 跨鏈交換](/exchange-swap) 這類路由入口而言,這決定了“信任最小化跨鏈證明”能否用於真實報價、退款和到帳確認,而不是隻停留在研究演示。
系統模型:目標鏈只接受壓縮後的共識事實
本文討論的是跨異構鏈狀態驗證,不討論中心化託管、價格預言機或純多籤橋。系統包含四個狀態層:
- 源鏈 `S`:產生區塊頭、驗證者簽名、狀態根和最終性證明; - 證明者 `P`:離線同步源鏈頭部,構造證明電路並生成 ZK proof; - 目標鏈驗證合約 `V`:驗證 proof,並更新已接受的源鏈共識狀態; - 應用合約 `A`:基於 `V` 中的可信狀態根驗證跨鏈消息、資產釋放或退款條件。
安全目標不是讓目標鏈“理解源鏈的一切”,而是讓目標鏈只接受一個可驗證命題:
`VerifyZK(proof, publicInputs) = true`
其中 `publicInputs` 至少包含 `oldRoot, newRoot, sourceHeight, validatorSetHash, appStateRoot, messageCommitment`。如果 proof 正確,目標鏈知道:從已信任的舊共識狀態出發,源鏈在某個高度產生了新狀態根,並且該狀態根包含目標應用需要的消息承諾。目標鏈不需要重新驗證幾十個 Ed25519 簽名,也不需要下載所有中間區塊。
這套模型仍然繼承源鏈的安全假設。若源鏈驗證者超過拜占庭閾值,ZK proof 只能忠實證明“源鏈已經接受了錯誤狀態”;若證明者停止服務,目標鏈不會自動前進;若 public input 綁定錯誤,proof 可能證明了一個正確但對應用無意義的狀態。ZK-Light Client 降低的是鏈上驗證成本,不是消除最終性、數據可用性和同步活性問題。
非原生字段為什麼會放大約束
證明系統通常在一個固定有限域 `F_p` 上工作。若要在電路里驗證另一個有限域 `F_q` 的運算,且 `p != q`,就必須把 `q` 域元素表示為多個 `p` 域 limb。例如把一個 255-bit Ed25519 標量拆成若干 64-bit 或 51-bit limb,再用約束證明乘法、加法、進位和模 `q` 約減都正確。
一個普通乘法 `z = x * y mod q` 在原生域裡可能只是一條乘法約束;在非原生域裡會變成:
`x = sum(x_i * 2^{w*i})`
`y = sum(y_i * 2^{w*i})`
`x*y = z + k*q`
其中 `x_i, y_i, z_i, k_i` 都要做範圍約束和 carry 約束。若 limb 數為 `m`,樸素乘法會出現 `O(m^2)` 個部分積,後續還要處理進位傳播和模約減。Ed25519 簽名驗證不是一次乘法,而是橢圓曲線點加、點倍乘、哈希挑戰、標量乘法和等式檢查的組合。約束數量自然會膨脹。
這也是為什麼 ethresear.ch 上關於 IBC 到 Ethereum 的討論會把 Ed25519 鏈上驗證視為災難性成本:直接在 EVM 裡驗證大量 Tendermint 驗證者簽名,gas 會隨驗證者數量線性放大。zkBridge 論文的方向是把這類工作移出鏈上,用 succinct proof 把鏈上驗證壓到一個可接受的常數級驗證過程。Electron Labs、Succinct SP1 Tendermint 示例和 ZK-IBC 的共同思路,也都是把輕客戶端的簽名和頭部更新邏輯放入可證明程序。
一個更工程化的判斷是:非原生字段成本通常不由“簽名數量”單獨決定,而由 `簽名數量 * 每個簽名的橢圓曲線操作 * 每個操作的 limb 約束` 決定。如果驗證者集合有 150 個節點,但只需累計超過 2/3 權重的簽名,電路仍要處理簽名選擇、權重累加和位圖約束。若為了隱藏參與簽名者集合而引入額外承諾,約束還會繼續增加。因此,ZK-Light Client 的性能瓶頸經常出現在看似低級的地方:limb 寬度選錯、range check 沒有用 lookup、哈希函數不證明友好,都會讓 proof generation 從可接受變成不可運維。
Tendermint/IBC 是最典型的壓力測試
Tendermint 輕客戶端的核心不是“看見一個區塊頭”,而是檢查新頭部是否被足夠驗證者權重簽名,並且驗證者集變更沒有越過信任期(trusting period)和拜占庭閾值。IBC ICS-07 規範把 Tendermint light client 建模成一個可更新的 client state 和 consensus state;CometBFT light client 規範則強調,輕客戶端不能信任 full node 返回的數據,必須用提交簽名和驗證者集關係做校驗。
這套邏輯放在原生環境裡已經不簡單,放進 EVM 更麻煩。原因有三層:
第一,簽名算法不匹配。Cosmos/Tendermint 生態常見 Ed25519 或 secp256k1 組合,而 Ethereum 執行層歷史上沒有 Ed25519 預編譯。用 Solidity 或 EVM bytecode 直接重放 Ed25519,成本不適合大規模 validator set。
第二,驗證者集合是動態的。輕客戶端要證明 `validatorSet_t` 到 `validatorSet_{t+1}` 的變更合法,不能只驗證一個靜態多籤閾值。ZK 電路需要把驗證者權重、地址、投票、哈希和集合更新綁定到 public input,否則目標鏈可能接受一個過時或偽造的集合。
第三,狀態證明有兩段。先證明頭部被共識接受,再證明應用消息存在於 `appHash` 或某個承諾根下。很多橋攻擊不是發生在 Merkle proof 本身,而是發生在“這個 root 是否可信”的上游。ZK-Light Client 正是把這兩段串起來:共識狀態更新給 root 賦予信任,應用 proof 再證明消息存在。
這也是 Tendermint/IBC 成為跨鏈 ZK 輕客戶端壓力測試的原因。它不是一個靜態簽名驗證問題,而是一個隨高度滾動的狀態機問題。電路要知道當前信任錨、目標高度、跳躍驗證策略、驗證者集合 hash、下一集合承諾和應用根之間的關係。如果只證明某個 commit 簽名有效,卻沒有證明這個 commit 能從目標鏈已保存的 trusted state 合法推進,目標鏈得到的只是一個孤立事實,而不是可更新輕客戶端。
ZK-Light Client 的狀態機
一個可執行級流程可以寫成:
1. `sync_header(h)`:證明者從源鏈獲取高度 `h` 的區塊頭、commit、驗證者集合和應用狀態根。 2. `check_trusting_period()`:確認舊信任狀態仍在可更新窗口內。 3. `verify_commit()`:在證明電路內檢查簽名集合權重超過閾值。 4. `verify_validator_update()`:證明新驗證者集合 hash 與頭部承諾一致。 5. `verify_message_membership()`:證明目標跨鏈消息存在於應用狀態根。 6. `prove_transition()`:輸出 proof 和 public inputs。 7. `update_client()`:目標鏈驗證 proof,寫入新高度和可信 root。
目標鏈合約可以只保留極少狀態:
`trustedHeight`
`trustedHeaderHash`
`trustedValidatorSetHash`
`trustedAppRoot`
`consumedMessageRoot`
這比傳統鏈上輕客戶端輕得多,但它把複雜性轉移給了證明生成和電路審計。電路必須正確實現簽名驗證、hash、權重累加、集合更新和 membership proof;任何欠約束都可能讓證明者構造“合法 proof + 錯誤 root”。因此,ZK-Light Client 的審計重點不是 Solidity 驗證器合約本身,而是整個可證明程序的約束完備性。
目標鏈還需要存儲回滾保護。若新 proof 的 `sourceHeight` 不高於當前 `trustedHeight`,或 `trustedHeaderHash` 與當前狀態不銜接,合約應拒絕更新。若允許多條源鏈分叉並存,應用層必須明確選擇哪個 fork 的 root 可以釋放資產。對跨鏈交換而言,最簡單的安全策略通常是單調高度更新加消息一次性消費:先更新可信 root,再驗證消息 membership,再把 message id 標記為 consumed,最後執行資產釋放或退款。
小字段 STARK、Plonky3 與遞歸壓縮的取捨
Plonky3、BabyBear、Goldilocks 這類小字段證明系統對 CPU 友好,適合高吞吐 STARK 或遞歸證明。但它們驗證 Ed25519、BLS12-381 或 Keccak/Merkle Patricia Tree 時,仍會面對非原生字段和非友好哈希的成本。小字段讓 prover 的內存訪問和多項式運算更快,卻不會自動讓源鏈密碼學變成本地運算。
工程上常見三種路線。
第一,直接在電路中實現源鏈簽名和 hash。這最通用,但約束數量最大,證明生成延遲最高。
第二,使用遞歸或聚合:把多個簽名、多個頭部更新、多個消息 inclusion proof 先在鏈下聚合,再生成一個最終 proof。zkBridge 的論文就強調用 proof system 組合和分佈式 proving 降低實際成本。代價是系統複雜,失敗時要定位是哪一級遞歸或聚合出錯。
第三,等待目標鏈原生預編譯降低驗證成本。Ethereum Pectra 已把 EIP-2537 納入升級,增加 BLS12-381 曲線操作預編譯,這對 BLS 系證明和簽名驗證是重要改善。但它不能直接解決 Ed25519、Solana PoH、Tendermint 集合更新或非 EVM 狀態樹在電路中的成本。預編譯降低的是某些目標鏈驗證和應用密碼學成本,不是把所有異構鏈都變成同構鏈。
遞歸壓縮也不是免費午餐。若第一層證明系統適合快速證明 Ed25519,第二層證明系統適合在目標鏈便宜驗證,兩層之間還要證明 proof verifier 的正確執行。這個“證明另一個證明系統的驗證器”本身會引入新的電路、約束和 trusted setup 或 FRI 參數。工程上通常要在三件事之間取捨:單次證明延遲、鏈上驗證成本、系統可審計性。過度複雜的遞歸棧可能把鏈上 gas 降下來,卻讓故障定位和安全審計變得更難。
失敗模式:proof 正確也可能不安全
第一類失敗是 public input 綁定錯誤。證明電路可能確實驗證了一個有效 header,但目標鏈合約沒有把 `sourceChainId`、`height`、`appRoot`、`messagePath` 和 `recipient` 全部綁定到同一個 public input 域。結果是 proof 正確,應用語義錯誤。跨鏈路由裡這會變成錯誤資產釋放或錯誤退款。
第二類失敗是過時 proof。輕客戶端有 trusting period 和最終性窗口。如果 relayer 或 prover 延遲提交,目標鏈可能接受一個理論上可驗證、但已經落後於源鏈安全窗口的狀態。CometBFT 和 IBC 規範都把信任期作為核心安全參數;ZK 版本不能把它藏到鏈下。
第三類失敗是證明服務中心化。ZK-Light Client 降低了驗證成本,卻可能讓證明生成集中到少數高性能 prover。若所有跨鏈消息依賴同一個 prover 隊列,系統活性會退化為“prover 是否在線”。這不是安全性破壞,但會影響到帳、退款和報價 SLA。
第四類失敗是電路欠約束。簽名解析、range check、carry、hash domain separation、validator weight overflow,只要有一處約束缺失,就可能出現非法狀態轉移被證明為合法。ZK 橋的安全邊界通常不在鏈上驗證合約,而在電路和 witness 生成程序。
第五類失敗是源鏈最終性誤讀。Solana、Tendermint、Ethereum、L2 的最終性語義不同。把所有鏈都抽象成“等待 N 個區塊”會讓路由錯誤估計風險。ZK proof 只能證明某個共識規則下的狀態,不會替產品決定應該等待多久。
第六類失敗是證明參數退化。STARK 的查詢次數、FRI 輪數、遞歸層數、SNARK 的曲線安全等級和 trusted setup 選擇,都會影響最終安全邊界。如果產品層只展示“ZK verified”,卻不區分證明系統參數、驗證器版本和升級權限,用戶會得到過度簡化的安全信號。對跨鏈證明,版本管理和可追溯性必須像資產合約地址一樣被索引。
AllSwap 為什麼要關心 ZK-Light Client
對用戶而言,跨鏈交換結果是“資產是否到帳”;對路由系統而言,真正的問題是“到帳依據是什麼”。若路徑依賴多籤或外部中繼,系統要為外部信任假設定價;若路徑依賴 ZK-Light Client,系統要為證明延遲、源鏈最終性、驗證合約 gas、prover 可用性和退款狀態定價。
AllSwap 不需要把所有路徑都改造成 ZK 輕客戶端。更現實的做法是把證明類型納入路由評分:
- 多籤/委員會證明:低延遲,但外部信任更強; - 原生輕客戶端:信任最小化,但鏈上驗證和維護成本高; - ZK-Light Client:鏈上驗證便宜,但 prover、電路和同步窗口成為新風險; - optimistic 證明:成本低,但需要挑戰窗口和失敗恢復。
這會影響用戶能看到的報價質量。大額交易、低流動性路徑、重要退款路徑更適合使用更強證明;小額、低風險交易可以接受更快但信任假設更強的路徑。AllSwap 的 [費用說明](/fees)、[/swap/usdt-erc20](/swap/usdt-erc20) 這類資產入口,以及 [/assets/usdc](/assets/usdc) 這樣的資產頁,最終都應該讓用戶知道:手續費之外,還有證明延遲、最終性窗口和異常退款成本。
可執行的路由狀態可以抽象為:
`proofType = committee | nativeLightClient | zkLightClient | optimistic`
`routeScore = priceScore - latencyPenalty - trustPenalty - refundPenalty`
其中 `trustPenalty` 不應該是主觀標籤,而應來自可觀測變量:驗證器合約版本、proof verifier 是否可升級、最近 proof 延遲、prover 隊列長度、源鏈最終性窗口、歷史失敗率和退款是否有鏈上證據。這樣做不會把普通用戶推入複雜參數,但能讓產品在大額交易和高風險路徑上自動偏向更強證明。
對無託管交換尤其重要的是退款歸因。若目標鏈釋放失敗,系統必須回答失敗發生在源鏈 burn/lock、證明生成、目標鏈 proof verification、消息 membership,還是資產合約執行。ZK-Light Client 能讓其中一部分路徑變得可證明:如果 proof 對應的源鏈消息確實存在,那麼退款邏輯可以圍繞目標鏈執行失敗展開;如果 proof 根本沒有生成或過期,用戶應看到的是同步延遲,而不是資產狀態不明。
監控層也要跟上。最小指標包括 `latestProvedHeight`、`sourceFinalizedHeight`、`proofLag`、`proofFailureRate`、`verifierVersion` 和 `pendingRefundNotional`。這些指標不必全部展示給用戶,但應進入路由風控;否則系統可能繼續把訂單送入一個已經落後數小時的證明通道。證明緩存也要按源鏈高度和應用根隔離,不能把舊 proof 當成新消息的通用通行證,這是基本安全底線之一。
仍未解決的問題
第一,非原生字段算術的通用優化還沒有統一收斂。不同證明系統在 limb 寬度、lookup、range check、carry 約束、遞歸壓縮上選擇不同,很難給出跨系統可比的成本模型。
第二,異構鏈狀態樹的統一抽象仍然困難。Tendermint 的 AppHash、Ethereum 的 MPT/Verkle 遷移、Solana 的賬戶模型、Move Object 模型都不是同一個證明接口。ZK-Light Client 不能只證明 header,還要把應用狀態路徑規範化。
第三,prover 市場的活性還沒有成熟。若證明生成需要 GPU 集群或專用優化,誰來保證證明按時生成、誰承擔延遲導致的退款損失、誰審計 witness 程序,都是開放問題。
第四,升級和 emergency halt 很難處理。源鏈升級驗證者格式、hash 函數或狀態根結構時,ZK 電路也要升級。若目標鏈 verifier 升級慢於源鏈,跨鏈狀態可能停在舊高度。
第五,用戶介面還沒有表達證明強度的標準。用戶不需要讀懂 non-native field arithmetic,但需要知道某條路徑是委員會證明、原生輕客戶端、ZK-Light Client 還是 optimistic proof,以及失敗時退款依據在哪裡。
References
[1] zkBridge: Trustless Cross-chain Bridges Made Practical, Xie et al., ACM CCS 2022, https://arxiv.org/abs/2210.00264
[2] IBC ICS-07 Tendermint Client Specification, Cosmos IBC, https://github.com/cosmos/ibc/blob/main/spec/client/ics-007-tendermint-client/README.md
[3] CometBFT Light Client Verification Specification, CometBFT, https://github.com/cometbft/cometbft-rs/blob/main/docs/spec/lightclient/verification/verification.md
[4] A Tendermint Light Client, Braithwaite et al., 2020, https://arxiv.org/abs/2010.07031
[5] Bringing IBC to Ethereum using ZK-SNARKs, Electron Labs / ethresear.ch, 2022, https://ethresear.ch/t/bringing-ibc-to-ethereum-using-zk-snarks/13634
[6] Electron Labs NEAR Prover Contracts, Electron Labs, https://github.com/Electron-Labs/near-prover-contracts
[7] SP1 Tendermint Example, Succinct Labs, https://github.com/succinctlabs/sp1-tendermint-example
[8] Prague-Electra Pectra Upgrade, ethereum.org, https://ethereum.org/roadmap/pectra/
[9] EIP-2537: Precompile for BLS12-381 curve operations, Ethereum Improvement Proposals, https://eips.ethereum.org/EIPS/eip-2537
[10] Polygon Plonky3, Polygon Labs, https://polygon.technology/blog/polygon-plonky3-the-next-generation-of-zk-proving-systems-is-production-ready
常見問題
ZK 輕客戶端能完全替代跨鏈橋驗證者嗎?
它能減少對外部委員會的依賴,把源鏈共識驗證壓縮成鏈上 proof verification。但它仍然依賴源鏈最終性、證明者活性、電路正確性和目標鏈驗證合約安全,不是無條件替代所有橋風險。
非原生字段算術為什麼會讓 ZK 輕客戶端變貴?
當證明系統字段與源鏈簽名或哈希字段不一致時,電路必須用 limb、range check、carry 和模約減模擬外部字段。Ed25519 簽名驗證會因此膨脹成大量約束。
EIP-2537 是否解決了跨鏈 ZK 輕客戶端的主要瓶頸?
EIP-2537 改善了 Ethereum 上 BLS12-381 曲線操作,對 BLS 簽名和部分證明驗證有幫助。但它不能直接消除 Ed25519、Tendermint 驗證者更新或非 EVM 狀態樹在 ZK 電路中的成本。
AllSwap 路由為什麼要關注 proof type?
不同證明類型對應不同信任假設、延遲、退款邊界和失敗模式。大額或高風險跨鏈交換應優先考慮更強證明;小額低風險路徑可以在成本和速度上做不同取捨。
ZK 輕客戶端最常見的失敗模式是什麼?
常見問題包括 public input 綁定錯誤、過時 proof、證明服務中心化、電路欠約束、源鏈最終性誤讀和證明參數退化。這些問題都需要在路由和監控層顯式建模。
參考資料
- zkBridge: Trustless Cross-chain Bridges Made Practical
- IBC ICS-07 Tendermint Client Specification
- CometBFT Light Client Verification Specification
- A Tendermint Light Client
- Bringing IBC to Ethereum using ZK-SNARKs
- Electron Labs NEAR Prover Contracts
- SP1 Tendermint Example
- Ethereum Pectra Upgrade
- EIP-2537: Precompile for BLS12-381 curve operations
- Polygon Plonky3


