T26 · Cross-chain
別のチェーンへ渡った資産は、同じ資産なのか?
- 練習する能力
- BuilderProtocol Literacy
- 実践
- クロスチェーン送金の両端の取引を追い、途中の信頼前提を誰が担うか明記する。
- AI Lab
- AI に 3 種類のクロスチェーン構成の信頼モデルを比較させ、実際のブリッジ攻撃でその分類を検証する。
現実の問題
Aチェーンの1,000 USDCを、Bチェーンのプロトコルで使うため橋を渡します。
二分後、財布にはUSDC 1000と表示されます。アイコン、名前、decimalsも正しく、担保にして借り入れます。
三週間後の深夜、A側の橋のロック契約が空になります。
B側のアドレス、残高、名前は変わりません。変わったのは、その1,000枚を裏付けるものがなくなったことだけです。
価格は数分で数セントへ落ち、担保は債務を下回ります。清算人も価値のない証書を受け取りたくなく、預金者が不良債務を分担します。
利用者は大手の橋を使い、馴染みの名前を確認しました。財布も価格サービスもUSDCと表示していました。
その1,000枚は、実際には何だったのでしょう?
思考実験
直接通信のない二つの国を考えます。
A国の倉庫へ貨物を預け、受取証をB国へ持っていき売ります。
Bの買い手はなぜ信じるのか? Aの倉庫を直接確認できません。
方法は三つです。
第一、Bでも認められる公証人に頼みます。 Aを見た人の証言は安く速い反面、公証人次第です。買収、強要、偽造をBでは発見できません。
第二、B自身がAへ観測者を常駐させます。 入出庫を記録し、他人でなく自分の検証規則に頼ります。
代償は費用です。無関係な99%を含めすべて追跡し、複雑な規則には対応できないこともあります。
第三、受取証を渡しません。 Bに同じ貨物を持つ人と交換します。その人がAの在庫リスクを引き受け、料金を取ります。
ここが重要です。
三つとも貨物は一歩も動いていません。変わるのは、Aの所有権というメッセージをBがどう信じるかです。
受取証は貨物ではなくメッセージです。人がそれを資産として解釈するから価値を持ちます。
メッセージが偽物なら、解釈された資産は最初から存在しません。
冒頭のUSDCは解釈結果です。ロックが空になった時点で根拠もなくなりました。
あなたが決める
アプリに橋を選ぶ前に、検証方法を選びます。
結果を観察する
四つを比較します。
| 信頼対象 | 失敗例 | 遅延 | 費用 | 新チェーン | |
|---|---|---|---|---|---|
| 外部検証者 | NからM人の不正がない | 鍵盗難、検証bug | 小 | 小 | 容易 |
| light client | 元チェーン合意 | 実装bug、更新不整合 | 中 | 大 | 難しい |
| challenge | 誠実で送信可能な一人 | 検閲、妨害 | 大 | 中 | 中 |
| 流動性network | makerと深さ | 枯渇、default | 小 | 中 | 中 |
二列目から次が分かります。
無信頼のクロスチェーンはなく、信頼先の選択があります。
trustlessという宣伝は、誰が不正なら自分の資金が失われるかへ翻訳します。できなければ理解不足です。
橋に事故が多い理由もあります。
利用が増えるとロックは増えますが、安全予算は増えません。1,000万から10億になっても検証者は同じN人で、侵害費はほぼ同じです。
すると次へ近づきます。
侵害費が、侵害利益より小さくなります。
次章の経済攻撃の式です。橋は資金が集中し、一プールでなく全ロックが失われるため特に露骨です。
章の結論です。
渡るのはメッセージで、資産はその解釈の一つです。
1,000枚はAからの情報に基づきBでmintされた証書で、価値は情報の真実性への信頼に依存します。
モデルを作る
伝送・検証・解釈の三層
信頼仮定を決めるのは中間層です。
- 元チェーンのイベント
- 伝送:誰が運ぶか
- 検証:誰が真実を証明するか
- 解釈:宛先で何をするか
| 層 | 役割 | 変更の影響 |
|---|---|---|
| 伝送 | relay、oracle、利用者が証拠を運ぶ | 活性。止まるが偽造はできない |
| 検証 | 元チェーン由来か確認 | 安全全体 |
| 解釈 | mint、unlock、関数実行 | 被害範囲 |
三層を分けると宣伝の多くを見抜けます。「独立relayが20ある」ことは伝送層で到着を保証するだけで、情報の真実性は保証しません。何人いても、保証するのは到着だけで、真実性ではありません。 問うべきは検証層の担当者です。
資産を表す三方式
同じ送金でも受け取るものは違います。
| 方式 | 元側 | 宛先 | 受取物 |
|---|---|---|---|
| Lock-Mint | ロック | wrappedをmint | 証書。ロック安全に依存 |
| Burn-Mint | burn | 同じ発行者がnativeをmint | native。発行者を信頼 |
| 流動性交換 | poolへ入金 | 別poolから出金 | native。流動性を信頼 |
第一方式には見落としがあります。
同じ資産に複数の非互換版ができます。 五つの橋のUSDCは五アドレスで、互換ではありません。別の橋で償還できません。
流動性が分裂し、利用者は版を見分けにくくなります。
allowlistはsymbolでなくアドレスです。 名前で識別するコードはいずれ不適切な資産を受け入れます。
発行者自身のBurn-Mintは、すでに発行者を信頼しているなら橋という追加仮定を減らせます。
メッセージの冪等性と再送
T17 のoutboxと同じ二性質が必要です。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract MessageReceiver {
// 実行済みメッセージ。全体で一意な座標をキーにする
mapping(bytes32 => bool) public executed;
event Executed(bytes32 indexed id);
function execute(
uint256 srcChainId,
uint256 nonce,
address sender,
bytes calldata payload,
bytes calldata proof
) external {
// 1. 宛先チェーンを含め、多チェーンでの重複実行を防ぐ
bytes32 id = keccak256(
abi.encode(srcChainId, block.chainid, nonce, sender, payload)
);
// 2. 実行済みなら拒否
require(!executed[id], "already executed");
// 3. この検証が橋全体の安全を決める
require(verify(id, proof), "invalid proof");
// 4. 記録してから実行。逆順はreentrancy
executed[id] = true;
_apply(sender, payload);
emit Executed(id);
}
function verify(bytes32, bytes calldata) internal view virtual returns (bool) {
return false; // 具体的な検証層で実装
}
function _apply(address, bytes calldata) internal virtual {}
}四つの注釈は実際の事故に対応します。
IDには宛先チェーンが必要です。 なければ一つの証拠で複数チェーンにmintできます。
冪等性はチェーン上の永続状態で実装します。 relayや利用者の再試行、再編で繰り返し届きます。T16 と同じく、根拠は記憶でなくメッセージ座標です。
検証の一行が橋全体の安全です。 実例で確認します。
記録が先、実行が後です。 逆順はreentrancyになります。
最終性の境界
T17 と同じ問題ですが、被害は大きくなります。
元側:ロック → inclusion → 複数確認 → 十分深い
宛先: ↑
どの時点でmintする?直後にmintして元側が再編されると、mint済みなのに担保が存在しません。
無担保増発で、回収できません。
T17 の取り消せない動作は十分深くなってからという原則です。通知なら謝れますが、発行済み資産は取り消せません。
待機深度には二つの注意があります。
第一、待機深度はチェーンごとの設定で、全体共通の定数ではありません。 最終性は、明確に確定するchainと確率的保証だけのchainで大きく異なります。別chainの値をそのままコピーする誤りは、攻撃に利用されます。
待機と体験は衝突します。 三秒到着は深度を下げるか、立替人へリスクを移すか。後者は明示的、前者は全利用者へ隠れて移します。
攻撃面
橋は集中資金、複雑な検証、二つの安全モデルを持ちます。
実際の攻撃面です。
| 面 | 形 |
|---|---|
| 検証bug | signer集合、chain照合を省く、空proofを認める |
| 鍵盗難 | 機械、cloud、CI侵入、shard集中管理 |
| mint権限 | 呼出制限漏れ、更新後の権限漏れ |
| upgrade | EOAに権限、timelockなし |
| replay | chain/nonce欠落、実行前記録なし |
| 最終性 | 浅い深度で元側再編 |
| 広すぎる解釈 | 偽メッセージで任意関数実行 |
通用メッセージはmint以外の任意呼出も運べます。
偽造一回で橋の権限すべてを使えるため、特定送信元と形式だけを受け入れ、任意呼出を認めません。
一度計算する
次章の方法を先に使います。
侵害費 = M本の鍵取得費 + Gas + 時間
侵害利益 = 全ロック資産
安全条件:費用 > 利益ロックは公開情報です。 費用は難しくても検証者の人数、運営者、共通チーム、鍵管理、timelockを調べられます。
ロックだけ二桁増えたなら、まだ順番が来ていない危険状態へ入っています。
何と呼ぶか
一方の状態変化を他方で効果にするシステムです。
資産を動かすのではなく、情報を運び、宛先が信じる仕組みです。
AのイベントでBのロジックを実行します。
資産移動は一用途です。通用性が高いほど偽造の被害も増えます。
元をロックして宛先にwrappedを発行し、帰路ではburnしてunlockします。
資産そのものではなく証書で、橋別の非互換版が流動性を分裂させます。
宛先で元チェーンの合意、ヘッダー、Merkle proofを検証します。
信頼は最小ですが、実装、Gas、合意更新が課題です。ZKによる費用削減が一つの方向です。
誰の不正・失敗で資金を失うかという文です。
すべての橋にあり、明記されているかが違います。 書けなければ検証層を理解していません。
他チェーンの資産を表す宛先のtokenです。
アドレス識別、償還経路、ロック障害時の受取物を確認します。答えられなければ債務を生むプロトコルへ入れません。
一意IDと宛先の実行記録で一回だけ実行します。
元chain、宛先chain、nonceが必要です。次元を一つ省くと再実行経路が増えます。
実践
全てtestnetです。 取引構造を学ぶ実験で、資金を移す練習ではありません。
一頁の最後に、「____が不正または失敗すると、資金を失う」 と書きます。
対応する二つのtestnetと橋を選びます。 少額を送ります。
開始時刻を記録し、ここから計時します。
元側を読みます。
四問に答えます。
- 宛先はロックcontractかEOAか?
- eventに宛先chain、recipient、nonceがあるか?
- 実際のロック残高はいくらか?
- proxyか?upgrade権限とtimelockは?到着までの実時間から待機深度を概算します。
時間差を元チェーンのブロック時間で割ります。
最終性と比較します。 小さすぎれば主要リスクを発見しました。
宛先を読みます。
- 誰が送ったか?relay、validator、本人?
- 関数とproofは?
- mint権限は誰にあるか?
- tokenアドレスは公式の同名tokenと同じか?最後でwrappedを初めて認識する人もいます。
検証層を探します。
宛先chainの取引のcall列をたどり、messageの真実性を判定する段階を見つけます。通常は署名検証、Merkle proof検証、またはregistryへのqueryです。
何を検証し、誰が保証するのか?
見つからなければ文書とsourceを読みます。見つからないこと自体が信頼先不明という結論です。
具体的な主語で一文を書きます。
不十分:「橋が攻撃されると失う」
十分:「8人のうち5人の鍵が漏れると、Bのwrappedは無担保証書になる」8人は誰か、同じチームかも調べます。
帰路も実験します。
検証、時間、費用が違うことがあります。両方向が別機構の橋は多くあります。
二つの仮定を並べて成果にします。
AI Lab
三段階で、第三が本題です。
第一:外部validator、light client、challengeを比較してください。
「___の不正・失敗で資金を失う」と具体的な役割・人数で書き、
遅延、費用、新chain追加難度を添えてください。
第二:伝送、検証、解釈の各障害について、資金損失か停止かを説明してください。
第三:実際のbridge事故を一つ選び、
1. 攻撃取引と操作
2. 失敗した層
3. 別方式でも成立するか
4. 事前の公開情報から見える兆候
を答えてください。第一は教科書的に答えやすい問題ですが、主語のない「橋が壊れた」は分析ではありません。
第二段階がこのLabの骨格です。モデルはrelay数やnode分布など伝送層の指標を、安全性の根拠と取り違えやすいです。これは宣伝がよく使う伝送と検証の混同で、この枠組みなら見抜けます。
第三段階はモデルと自分の両方を試します。事故報告は公開され詳細なので素材は多いですが、鍵の盗難と検証ロジックのbugを混同しがちです。前者は鍵管理、後者はコードの修正が必要で、分類を誤ると後の結論も全て誤ります。
事前に何が見えたかが最も有用です。ロック、人数、upgrade、timelockは公開されています。
自分で未言及の面を加えます。 七項目のうちreplayと最終性は漏れやすく、自分の統合でも踏みやすいものです。
AI の回答後、自分で必ず検証すること
- relay数を安全根拠にしていないか
- 具体的な役割と人数で信頼仮定を書けるか
- 最終性と深度を含むか
- 事件の時刻、金額、方法を原報告や取引で確認したか
- 検証bug、鍵管理、mint、upgradeを正しく区別したか
- 完全trustlessと断言していないか
- 未言及の攻撃面と、それに耐える方式を自分で追加する
実例
署名の数学的正しさだけを確認し、集合所属を確認しませんでした。
攻撃者の鍵で偽proofを署名し、mintできました。
構文、コンパイル、正常テストは通ります。 異常入力でしか発見できません。
多くの欠陥は構文でなく権限境界にあります。
侵入でthreshold以上の鍵を得て、合法の手順で出金しました。
署名も処理も設計どおりで、チェーン上は正常です。
二つの教訓があります。bridgeの安全上限は鍵管理で、良いコードでも補えません。 全段階が正常なので、通常のchain監視はほぼ効きません。
借入protocolがwrappedへnativeと近い担保率を設定しました。
bridge事故で値を失い、清算されず預金者が負担します。
資産リスクと橋リスクを加えて評価します。 担保率、oracle、上限へ反映します。T21 に加え、償還経路もsingle pointです。
EOAや低threshold multisigに権限があり、timelockがありません。
コードとvalidatorが正しくても、一鍵で全ロジックを変えられます。
攻撃技術なしで確認でき、結果も公開された、あらゆるbridge評価の第一pageに書くべき情報です。 第24章 の通り、timelockなしのupgrade権限は、その鍵へ全資金を預けることと同じです。
変数を一つ変える
攻略利益は100倍、費用はほぼ不変なので、割に合わないbridgeから有利な攻撃対象へ変わります。コード変更は一行もなく、この過程でalertも起動しません。
安全予算が資金規模に追従しない問題です。
人数、threshold、出金rate、単発上限、大口timelockで抑えますが、高速体験を犠牲にします。
深度の経験則が明確になり、再編由来の無担保mintは減ります。
検証bugや鍵、mint権限は解決しません。
最終性は発生の確定、検証はなぜ信じられるかです。
wrappedと断片化がなくなり、各chainでnativeを得ます。
信頼仮定はbridgeのvalidatorから一発行者へ縮みます。すでにその発行資産を持つなら、新たな信頼でなく既存信頼の再利用です。 これは実質的な改善です。
中央発行者に限り、凍結や拒否のsingle pointが強まります。改善と形を変えたリスクが併存します。
クロスチェーンガバナンス、清算、直接呼出が可能です。
偽造一回が橋としての任意操作になります。
統合時は解釈層の制約を自ら加え、特定source chainとaddressだけ受け、固定の関数集合と引数範囲を検証します。T32 のValidatorとPolicyと同じく、上流が信頼できない場合、自分の側へ防御を置きます。
持ち帰る問い
クロスチェーンは、Aの状態変更がBで効果を生む問題を解決します。資産自体を運ぶことではありません。 通貨が途中にあるという状態はなく、元chainのlock契約内にあるか、既にburnされています。
流動性型はmakerが可否とslippageを決めます。Lock-Mintでは宛先wrapped市場の深さを誰が提供するかが逃げ道を決めます。
リスクの主語は橋ではなくvalidator、発行者、maker、元合意です。具体化できれば理解したことになります。
章末チェック
方式次第です。
Lock-Mintは証書です。ロック喪失でもアドレス、symbol、残高は変わりません。
Burn-Mintと流動性交換はnativeで、発行者またはmakerへリスクが移ります。
元にどう戻すかを聞き、その橋にしか戻せなければ証書です。
伝送の問題は停止であり、偽造ではありません。
100relayでも三validatorなら、信頼はその三人です。
三層に分け、中央の検証を見ます。
再送、再試行、再編で繰り返し届くからです。
元chain、宛先chain、nonce、sender、payloadを含めます。
宛先を省くと各chainで同じproofを実行できます。
永続記録は実行前に書きます。
元の十分な最終性まで待ちます。浅いと再編で担保のないmintになります。
chain別に設定します。
T17 の不可逆操作は十分深くなってからという原則です。
即時体験は立替リスクか深度削減によるものです。
確認項目:
- 不正・失敗の主語と人数を書いたか?
- 検証層を実際に見たか?
- ロックと人数の比率は半年でどう変わったか?
- upgradeとtimelockは?
- address識別かsymbol識別か?
- 事故時の不良債務を計算したか?
- nativeと別上限を設けたか?
第三はリスクの移動、七は損失規模を測ります。
要点
クロスチェーンで伝わるのはメッセージであり、資産はその解釈の一つにすぎない。