概要
スマホ決済、銀行振込、ポイント交換、交通系ICカード、ゲーム内アイテム。
普段はあまり意識しませんが、私たちはいろいろな場所で 「残高」や「価値の記録」 を使っています。
たとえば、A銀行からB銀行へ振り込む場面を考えてみます。
A銀行のアプリで残高が減ったからといって、B銀行の残高が自動で増えるわけではありません。
銀行ごとに管理している台帳があり、その間をつなぐ決済の仕組みがあるからこそ、「A銀行で減った分が、B銀行側に反映される」という流れが成り立ちます。
ポイント交換も似ています。
A社の10,000ポイントをB社のポイントに交換するとき、A社のポイントがそのまま物理的に移動しているわけではありません。
多くの場合、A社側のポイントを減らし、交換レートやルールに従ってB社側のポイントを増やす、という処理が行われます。
| 身近な例 | 何が起きているか | ブリッジ理解へのつながり |
|---|---|---|
| 銀行Aから銀行Bへ振り込む | A銀行側の残高を減らし、B銀行側の残高に反映する | 別々の台帳をどうつなぐか |
| 円をユーロに両替する | 円を減らし、レートに応じてユーロを受け取る | 同じ価値を別の形式で使えるようにする |
| A社ポイントをB社ポイントへ交換する | 片方のポイントを減らし、もう片方のポイントを増やす | 元の価値と交換先の価値の対応を管理する |
| 交通系ICカードの残高を別アプリで使う | サービス間の対応がなければ、そのまま残高を共有できない | 仕組みが違うと、記録をそのまま読めない |
| ゲームAのアイテムをゲームBで使う | ゲームごとにルールやデータベースが違う | 別の世界で同じ資産として扱うには変換が必要 |
ここで大切なのは、別の仕組みに価値を移すには、間をつなぐ仕組みが必要になる という点です。
これはブロックチェーンでも同じです。
Ethereum、Solana、AvalancheのようなL1や、Arbitrum、OptimismのようなL2は、それぞれ別の台帳、別のルール、別の状態を持っています。
Ethereum上にあるトークンを、Solanaのような別L1やL2上でそのまま使えるわけではありません。
たとえば、Ethereum上にあるトークンを別のチェーンで使いたい場合、何らかの仕組みで次のような対応を取る必要があります。
送信元チェーンで起きたこと
例: トークンを預ける、ロックする、バーンする
↓
その出来事を確認・伝達する
例: 証明、署名、メッセージ、リレイヤー
↓
宛先チェーンで対応する処理を行う
例: ラップドトークンを発行する、別チェーン側でミントする
このように、異なるブロックチェーンの間で資産やメッセージを扱えるようにする仕組みが、一般に ブロックチェーンブリッジ と呼ばれます。
Ethereum.orgでは、ブリッジは複数の設計に分かれ、代表的な資産移転の方式として、送信元チェーンで資産をロックして宛先チェーンでミントする Lock and Mint、送信元チェーンでバーンして宛先チェーンでミントする Burn and Mint、別の参加者と資産を交換する Atomic Swap が挙げられています。
ただし、ここで少し注意が必要です。
「ブリッジ」という名前から、コインが橋を渡って別のチェーンへ移動する様子を想像したくなります。
しかし、実際にはトークンが物理的に別チェーンへ移動しているわけではありません。
多くの場合、片方のチェーンで資産をロックしたり、バーンしたりします。
そして、もう片方のチェーンで対応するトークンを発行したり、既存の流動性から支払ったりします。
つまり、ブリッジを理解するときは、単に「資産が移動する」と見るよりも、別々の台帳の間で、対応する状態をどう作るのか と考える方が正確です。
もう少し言うと、ブリッジが扱うものはトークンだけではありません。
最近のクロスチェーン系プロトコルでは、別チェーンへデータや命令を送る クロスチェーンメッセージング も重要です。
Chainlink CCIPの公式ドキュメントでは、CCIPはトークン、メッセージ、またはその両方をチェーン間で転送するアプリケーションを構築できる相互運用プロトコルとして説明されています。
また、Wormholeの公式ドキュメントでも、Wormholeは複数のブロックチェーン間で安全かつ効率的な通信を可能にする generic message-passing protocol と説明されています。
参考: Wormhole Docs: Introduction to Wormhole
そのため、本記事ではブリッジを単なる「トークン移動ツール」としてではなく、次のように広めに捉えます。
| ブリッジで扱うもの | 例 | 本記事での見方 |
|---|---|---|
| トークン | ETH、USDC、ERC-20トークンなど | 別チェーン上でどう表現されるのかを見る |
| メッセージ | 別チェーンのコントラクトへ送る命令 | その命令が本当に正しいかを誰が検証するのかを見る |
| 任意データ | 状態、証明、ペイロードなど | データの正しさや改ざん耐性を見る |
| スマートコントラクト呼び出し | 別チェーン上の処理を実行する指示 | 実行失敗、リプレイ、権限設計に注意して見る |
ここで、ブリッジの便利さも見えてきます。
ブリッジがあると、ユーザーは別のチェーン上のdAppsを使いやすくなります。
開発者は、複数のチェーンの特徴を組み合わせたアプリケーションを作りやすくなります。
Ethereum.orgの開発者向け資料でも、ブリッジの利点として、異なるブロックチェーンの強みを活用できることや、複数エコシステムのユーザー・開発者をつなげられることが説明されています。
一方で、便利さの裏側にはリスクもあります。
ブリッジでは、送信元チェーンで本当に資産がロックされたのか、バーンされたのか、正しいメッセージなのかを、宛先チェーン側が何らかの方法で確認する必要があります。
その確認の仕組みには、スマートコントラクト、署名者、検証者、ガーディアン、リレイヤー、オラクル、発行体など、さまざまな登場人物や部品が関わります。
Ethereum.orgも、ブリッジには trusted bridge と trustless bridge のような分類があり、信頼の置き場所が設計によって異なることを説明しています。
参考: Ethereum.org: Introduction to blockchain bridges
本記事では、ブリッジを「便利だから使えばよい」「攻撃事例があるから危険」といった二択では扱いません。
次の4つの問いを軸に、仕組みとリスクを整理していきます。
| 問い | 見るポイント |
|---|---|
| 何を別チェーンへ渡しているのか | トークン、メッセージ、任意データ、スマートコントラクト呼び出し |
| 資産はどう表現されているのか | ロック、バーン、ミント、アンロック、ラップドトークン、流動性 |
| 誰が出来事を検証しているのか | ライトクライアント、外部バリデータ、ガーディアン、発行体、Watcher |
| 失敗したとき何が起こるのか | 資産の不整合、メッセージ失敗、流動性不足、ユーザー操作ミス、権限悪用 |
この記事を読み終えるころには、ブリッジを単なる「チェーン間の送金機能」としてではなく、別々の台帳をつなぐための仕組みと、その信頼モデル として見られるようになることを目指します。
💡 豆知識
ブリッジは「橋」という名前ですが、実際には道路の橋よりも、銀行間送金やポイント交換に近い部分があります。
片方の記録を減らし、もう片方の記録を増やす。
その間で「本当に減ったのか」「誰が確認したのか」「二重に増えていないか」を見ることが、ブリッジ理解の大きなポイントになります。
ここまでで、ブリッジを身近な残高移動の延長として見てきました。
次の章では、本記事が派生元のブロックチェーン全体像記事の中でどの位置づけになるのかを整理します。
この記事の立ち位置
本記事は、以前作成した 「身近な記録から理解するブロックチェーンの全体像」 の派生記事です。
派生元の記事では、ブロックチェーンを「複数の参加者が同じ記録を共有し、その記録があとからこっそり書き換えられていないかを確認しやすくする仕組み」として整理しました。
そこでは、ブロック、チェーン、台帳、分散、ハッシュ、デジタル署名、コンセンサス、スマートコントラクト、情報セキュリティ上の強みと限界を広く扱いました。
本記事では、その中でも特に ブロックチェーンブリッジ に焦点を当てます。
ブロックチェーンブリッジは、異なるチェーンの間で資産やメッセージを扱えるようにする仕組みです。
Ethereum.orgの開発者向け資料でも、ブリッジはブロックチェーン同士をつなぎ、トークンや任意データ、スマートコントラクト呼び出しなどを別チェーンへ渡す経路を作るものとして説明されています。
ただし、ブリッジを理解するときは、単に「別チェーンへ送れる便利な機能」として見るだけでは不十分です。
ブリッジでは、送信元チェーンで起きた出来事を宛先チェーン側がどのように確認するのか、ロックされた資産と発行された資産の対応関係がどう保たれるのか、検証者・発行体・ガーディアン・流動性提供者などをどこまで信頼するのかが重要になります。
派生元記事との関係を整理すると、次のようになります。
| 派生元記事 | 本記事 |
|---|---|
| ブロックチェーン全体の地図を整理する | ブリッジとクロスチェーン連携に絞って整理する |
| 記録を共有し、改ざんを検知しやすくする仕組みを見る | 別々のチェーン上の記録をどう対応させるかを見る |
| ハッシュ、署名、分散、コンセンサスなどを広く扱う | Lock and Mint、Burn and Mint、メッセージ検証、信頼モデルを扱う |
| 情報セキュリティ上の強みと限界を整理する | ブリッジ特有のリスク、攻撃事例、確認ポイントを整理する |
関連記事: 身近な記録から理解するブロックチェーンの全体像
Qiitaに投稿する際は、上記の ここに派生元記事のURLを挿入 の部分を、実際に投稿済みの派生元記事URLへ置き換えてください。
本記事は、派生元記事の中でも クロスチェーン連携・セキュリティリスク編 に近い位置づけです。
ブリッジを「便利か危険か」の二択で見るのではなく、何を渡し、誰が検証し、どこに信頼仮定があり、失敗したとき何が起こるのかを分けて整理します。
この記事で分かること
この記事で分かることは、次のとおりです。
- ブロックチェーンブリッジがなぜ必要になるのか
- 資産が本当にチェーンを移動しているのか
-
Lock and Mint、Burn and Mint、Lock and Releaseの違い - ラップドトークンとネイティブ資産の違い
- ブリッジ処理がどのような順番で進むのか
- 送信元チェーンの出来事を宛先チェーン側でどう検証するのか
- ライトクライアント型、ガーディアン型、発行体アテステーション型などの信頼モデル
- L2カノニカルブリッジ、Wormhole、Circle CCTP、Cosmos IBC、Chainlink CCIP、LayerZeroなどの考え方
- ブリッジに関するセキュリティリスク
- 代表的なインシデントから学べること
- 利用者・開発者が確認すべきポイント
- ブリッジについてよくある誤解
特にこの記事では、次の4つを混同しないことを重視します。
| 混同しやすいこと | 分けて考えたいこと |
|---|---|
| 資産が移動する | 送信元でロック・バーンし、宛先で対応する状態を作る場合が多い |
| メッセージを運ぶ | そのメッセージが正しいか検証することは別である |
| 公式・監査済み | 仕様、権限、待ち時間、失敗時対応まで確認が必要である |
| trustless | 何も信頼しないのではなく、信頼する対象を小さく・明確にする考え方である |
この記事を読み終えるころには、ブリッジを見たときに次のような問いを立てられることを目指します。
このブリッジは、
何を渡しているのか
資産はどう表現されているのか
誰が送信元チェーンの出来事を検証しているのか
どこに信頼仮定があるのか
失敗したとき何が起こるのか
対象読者
この記事は、次のような人を想定しています。
- ブロックチェーンを学び始めた人
- EthereumやL2、Rollupに興味がある人
- DeFiやマルチチェーンアプリケーションでブリッジを見かけたことがある人
- ブリッジ攻撃のニュースを見て、何が問題だったのか整理したい人
- 暗号資産AMLやオンチェーン分析の前提として、クロスチェーン移動を理解したい人
- 情報セキュリティの観点から、ブリッジの信頼モデルやリスクを学びたい人
- 技術的な細部に入る前に、まず全体像をつかみたい人
前提知識としては、次の程度を想定しています。
| 前提知識 | 必要度 |
|---|---|
| ブロックチェーンが取引や状態を記録する仕組みであること | あると読みやすい |
| トークンやアドレスという言葉を聞いたことがあること | 記事内で説明するため、なくてもよい |
| スマートコントラクトの詳しい実装 | なくてもよい |
| 暗号技術や署名検証の詳細 | なくてもよい |
| 実際のブリッジ利用経験 | なくてもよい |
| セキュリティ監査やインシデント対応の経験 | なくてもよい |
途中で、Lock and Mint、Burn and Mint、ラップドトークン、リレイヤー、ガーディアン、ライトクライアント、アテステーション、finality、replay、nonceなどの言葉が出てきます。
ただし、最初からすべてを知っている必要はありません。
それぞれの用語は、銀行振込、ポイント交換、両替、荷物の引換券、郵便配達、承認印のような身近な例と結びつけながら説明します。
本記事で扱わないこと
本記事は、ブロックチェーンブリッジの仕組みとリスクを、初学者向けに整理する記事です。
そのため、以下は扱いません。
- 実在ブリッジの利用推奨
- 特定ブリッジの安全性ランキング
- 投資判断や利回り比較
- 攻撃手順や脆弱性悪用手順
- 攻撃コードやPoCの再現
- 実在アドレスや実在組織の追跡
- 個別事件の犯人特定
- 法律上・規制上の助言
- すべてのブリッジ実装の網羅的な比較
攻撃事例として、Wormhole、Ronin Bridge、Nomad、BSC Token Hubなどに触れます。
ただし、それらは攻撃を再現するためではなく、署名検証、鍵管理、アップグレード、証明検証、監視、緊急停止といった設計・運用上の学びを整理するために扱います。
また、ブリッジの仕様、対応チェーン、対応トークン、手数料、待ち時間、被害額、規制情報は変化します。
投稿前や実際の利用前には、必ず公式情報や最新資料を確認してください。
| 扱う観点 | 扱わない観点 |
|---|---|
| ブリッジの基本的な仕組み | 特定サービスの利用推奨 |
| 検証モデルや信頼仮定の整理 | 安全性ランキング |
| インシデントから得られる設計・運用上の教訓 | 攻撃手順や悪用コード |
| 利用者・開発者の確認ポイント | 投資判断や法的助言 |
コード・図を使う場合の前提
本記事では、ブリッジの処理を理解しやすくするために、Mermaid図、表、Pythonの小さなコード例を使います。
ただし、これらはすべて 概念理解のための学習用 です。
実在するブリッジ、スマートコントラクト、署名検証、Merkle proof検証、アテステーションサービス、取引監視システムを再現するものではありません。
本記事で使う例は、次のような架空の前提にします。
| 項目 | 内容 |
|---|---|
| チェーン名 |
Chain A、Chain B などの架空チェーン |
| トークン名 |
TEST Token、wrapped TEST などの架空トークン |
| ユーザー名 |
alice などの説明用の名前 |
| コードの目的 | ロック量とミント量、状態遷移、nonce管理、チェックリストを理解するため |
| 扱わないこと | 実在ブリッジの実装、攻撃再現、実資産の操作 |
たとえば、Lock and Mintを説明するときは、次のような単純化した流れを使います。
UserがChain Aで100 TESTをロックする
↓
Sample Bridgeが「100 TESTがロックされた」という出来事を確認する
↓
RelayerがそのメッセージをChain Bへ運ぶ
↓
Chain Bで100 wrapped TESTがミントされる
図にすると、次のようなイメージです。
実際のブリッジでは、finality、署名者セット、ガス代、手数料、対応トークン、失敗時のclaim、rate limit、emergency pause、アップグレード権限など、さらに多くの要素が関係します。
そのため、本文中のコードや図は、細部を正確に再現するものではなく、どこで状態が変わり、どこで検証が必要になるのか を理解するための補助として読んでください。
全体の流れ
この記事では、次の順番で話を進めます。
最初は、銀行振込、ポイント交換、両替、電子マネー残高、ゲーム内アイテムのような身近な例から入ります。
そこで、別々の仕組みにある残高や価値を、そのまま別の場所で使えるわけではない という感覚を押さえます。
次に、ブロックチェーンブリッジを「異なるチェーンの間で、資産やメッセージを扱えるようにする仕組み」として整理します。
そのうえで、資産が本当に移動しているのではなく、ロック、バーン、ミント、リリース、流動性などによって、別チェーン側に対応する状態を作っている場合が多いことを見ます。
後半では、送信元チェーンの出来事をどう検証するのかを整理します。
ライトクライアント型、ガーディアン型、発行体アテステーション型、Optimistic型、流動性ネットワーク型などを比較しながら、ブリッジの信頼モデルを見ていきます。
さらに、代表的なブリッジや相互運用プロトコル、セキュリティリスク、過去のインシデント、利用者・開発者の確認ポイント、よくある誤解を整理します。
この記事を通じて、最終的には次のような見方ができるようになることを目指します。
ブロックチェーンブリッジは、単に「別チェーンへ送る便利な機能」ではありません。
別々の台帳の間で状態を対応させる仕組みであり、誰が何を検証しているのか、どこに信頼仮定があるのか、失敗したとき何が起こるのかを分けて考えることが大切です。
次の章では、まず身近な 「残高移動」 から考えます。
銀行振込やポイント交換を例に、別々の台帳をつなぐとはどういうことなのかを整理していきます。
1. 身近な「残高移動」から考える
この章では、ブロックチェーンブリッジに入る前に、銀行振込、両替、ポイント交換、電子マネー残高のような身近な例から考えます。
ポイントは、別々の仕組みに記録された価値を、そのまま共有することはできない という感覚です。
ここまでの章では、本記事の立ち位置や全体の流れを整理しました。
ここからは、いよいよ本文に入っていきます。
ただし、最初から Lock and Mint や cross-chain messaging のような用語を並べると、少し遠い話に感じてしまうかもしれません。
そこで、この章ではブロックチェーンから少し離れて、普段の生活にある 残高移動 から考えてみます。
たとえば、次のような場面を思い浮かべてください。
| 身近な場面 | 何をしたいか | すぐにはできない理由 |
|---|---|---|
| A銀行からB銀行へ振り込む | A銀行の残高をB銀行側へ反映したい | 銀行ごとに台帳が分かれている |
| 円をユーロに両替する | 円の価値をユーロとして使いたい | 通貨の単位や利用できる場所が違う |
| A社ポイントをB社ポイントへ交換する | A社のポイントをB社サービスで使いたい | ポイントを管理する会社やルールが違う |
| 交通系ICカードの残高を別アプリで使う | ICカード残高を別サービスでも使いたい | 残高を記録している仕組みが違う |
| ゲームAのアイテムをゲームBで使う | あるゲームのアイテムを別ゲームでも使いたい | ゲームごとにデータベースやルールが違う |
このように、同じ「価値」に見えるものでも、記録されている場所やルールが違うと、そのまま別の仕組みで使えるわけではありません。
ブロックチェーンブリッジも、まずはこの感覚から考えると分かりやすいです。
Ethereum上にあるトークンは、Ethereumの台帳上に記録されています。
Solana上にあるトークンは、Solanaの台帳上に記録されています。
L2上の残高も、そのL2の状態として管理されています。
つまり、チェーンが違えば、残高や状態を記録している場所も違います。
そのため、あるチェーンにある資産を、別のチェーンでそのまま使うことはできません。
この章では、まず身近な残高移動から、別々の台帳をどう整合させるか という考え方を整理します。
1.1 銀行Aから銀行Bへ振り込むと何が起きるのか
まず、銀行振込で考えてみます。
A銀行の口座からB銀行の口座へ10,000円を振り込むとします。
利用者の画面では、単に「10,000円を送った」と見えるかもしれません。
しかし、裏側では少なくとも次のようなことを整合させる必要があります。
A銀行側:
送金者の残高を10,000円減らす
B銀行側:
受取人の残高を10,000円増やす
銀行間:
本当にA銀行側で送金処理が行われたことを確認する
ここで大切なのは、A銀行とB銀行がそれぞれ別の台帳を持っているという点です。
A銀行の残高が減ったからといって、B銀行の台帳が自動で更新されるわけではありません。
銀行間の仕組みや決済ネットワークがあるからこそ、A銀行側の処理とB銀行側の処理を対応させることができます。
かなり単純化すると、次のような流れです。
この例は、ブロックチェーンブリッジを理解する入口になります。
ブロックチェーンでも、Chain AとChain Bは別々の台帳を持っています。
Chain A側で資産をロックしたことを、Chain B側が何らかの方法で知り、対応する処理を行う必要があります。
ただし、銀行振込とブロックチェーンブリッジは同じものではありません。
銀行振込では金融機関や決済ネットワークが中心になりますが、ブリッジではスマートコントラクト、署名、検証者、リレイヤー、メッセージなどが関係します。
ここではまず、別々の台帳をどう対応させるか という感覚だけ押さえておけば十分です。
1.2 ポイント交換では、片方を減らして片方を増やす
次に、ポイント交換で考えてみます。
たとえば、A社ポイント10,000ポイントを、B社ポイント8,000ポイントに交換する場面を考えます。
このとき、A社ポイントが物理的にB社へ移動しているわけではありません。
実際には、かなり単純化すると次のような処理になります。
1. A社側で、ユーザーのA社ポイントを10,000ポイント減らす
2. 交換レートを確認する
3. B社側で、ユーザーのB社ポイントを8,000ポイント増やす
表にすると、次のようになります。
| 時点 | A社ポイント | B社ポイント | 状態 |
|---|---|---|---|
| 交換前 | 10,000 | 0 | A社側にポイントがある |
| A社ポイント減算後 | 0 | 0 | A社側のポイントが使えない状態になる |
| B社ポイント反映後 | 0 | 8,000 | B社側で使えるポイントが増える |
ここで見てほしいのは、片方を減らして、もう片方を増やす という構造です。
この考え方は、ブリッジの Lock and Mint や Burn and Mint を理解するうえで役立ちます。
もちろん、実際のポイント交換とブロックチェーンブリッジは違います。
しかし、「元の場所で使えない状態にして、別の場所で対応する表現を作る」という考え方はかなり似ています。
ブリッジでも、次のような処理が出てきます。
| 身近なポイント交換 | ブリッジでの対応イメージ |
|---|---|
| A社ポイントを減らす | 送信元チェーンでトークンをロックまたはバーンする |
| 交換レートや条件を確認する | メッセージや証明を検証する |
| B社ポイントを増やす | 宛先チェーンで対応するトークンをミントまたはアンロックする |
| 二重利用できないようにする | 元資産と発行資産の対応を管理する |
ここで重要なのは、両方の場所で同じ価値を同時に自由に使えてしまうと困る という点です。
A社ポイントを減らさずにB社ポイントだけ増やせるなら、ポイントが不正に増えてしまいます。
ブリッジでも、送信元チェーンで資産がロックされていないのに宛先チェーンでトークンがミントされると、裏付けのない資産が生まれてしまいます。
この「二重に増えてはいけない」という感覚は、ブリッジのセキュリティを理解するときにとても重要です。
1.3 電子マネーやゲームアイテムでも「別の世界」ではそのまま使えない
もう少し身近な例を増やしてみます。
たとえば、ある電子マネーの残高を、別の電子マネーサービスでそのまま使えるとは限りません。
残高を管理している会社、利用できる店舗、決済ネットワーク、利用規約が違うからです。
ゲーム内アイテムも似ています。
ゲームAで手に入れた剣を、ゲームBでそのまま使えるとは限りません。
ゲームごとにアイテムID、能力値、ルール、データベースが違うからです。
この例から分かるのは、同じように見える価値でも、記録されている世界が違うと、そのまま移動できない ということです。
ブロックチェーンでも同じです。
EthereumのトークンはEthereumのルールに従って存在しています。
別のチェーンでは、アドレス形式、手数料の仕組み、スマートコントラクトの実行環境、finalityの考え方が違う場合があります。
そのため、Chain AにあるトークンをChain Bで使えるようにするには、何らかの連携が必要です。
💡 豆知識
「別の世界でそのまま使えない」という感覚は、ゲームで考えると分かりやすいです。
ゲームAのレアアイテムをゲームBで使いたいなら、ゲームB側がそのアイテムを理解できる形に変換する必要があります。
ブリッジでも、別チェーン側が理解できる形で資産やメッセージを扱えるようにする必要があります。
1.4 小さなアルゴリズムで「別々の台帳」を見てみる
ここで、かなり単純化したPythonコードを使って、別々の台帳を持つ2つのサービス間で残高を移す流れを見てみます。
このコードは、実在する銀行、ポイントサービス、ブロックチェーン、ブリッジを再現するものではありません。
目的は、片方の台帳を減らし、もう片方の台帳を増やすときに、どのような確認が必要になるのか を理解することです。
# このコードは、別々の台帳を持つ2つのサービス間で
# 残高を移す考え方を理解するための学習用コードです。
# 実在する銀行、ポイントサービス、ブロックチェーン、ブリッジの処理ではありません。
from dataclasses import dataclass
@dataclass
class Ledger:
"""
1つのサービスやチェーンの台帳を表す簡単なクラスです。
name:
台帳の名前です。例: "Service A", "Service B"
balances:
ユーザーごとの残高を持つ辞書です。
例: {"alice": 10000}
"""
name: str
balances: dict
def get_balance(self, user_id):
"""
指定したユーザーの残高を取得します。
残高がまだ存在しない場合は0として扱います。
"""
return self.balances.get(user_id, 0)
def debit(self, user_id, amount):
"""
指定したユーザーの残高を減らします。
ブリッジでいうと、送信元チェーンで資産をロックしたり、
バーンしたりする処理のイメージに近いです。
"""
if amount <= 0:
raise ValueError("amountは正の値である必要があります")
if self.get_balance(user_id) < amount:
raise ValueError(f"{self.name}: 残高不足です")
self.balances[user_id] = self.get_balance(user_id) - amount
def credit(self, user_id, amount):
"""
指定したユーザーの残高を増やします。
ブリッジでいうと、宛先チェーンで対応するトークンを
ミントしたり、アンロックしたりする処理のイメージに近いです。
"""
if amount <= 0:
raise ValueError("amountは正の値である必要があります")
self.balances[user_id] = self.get_balance(user_id) + amount
def transfer_between_ledgers(source, destination, user_id, amount, rate=1.0):
"""
2つの台帳の間で残高を移す、かなり単純化した関数です。
source:
残高を減らす側の台帳です。
destination:
残高を増やす側の台帳です。
user_id:
残高を移すユーザーIDです。
amount:
source側で減らす数量です。
rate:
交換レートです。ポイント交換や両替をイメージしています。
注意:
この関数は学習用です。
実際のブリッジでは、署名、証明、finality、手数料、
リレイヤー、失敗時の復旧など、さらに多くの要素が関係します。
"""
# 1. 送信元の残高を確認します。
if source.get_balance(user_id) < amount:
raise ValueError("送信元の残高が不足しています")
# 2. 送信元の残高を減らします。
# これは、ブリッジでいうロックやバーンに似た役割です。
source.debit(user_id, amount)
# 3. 交換レートをもとに、宛先側で増やす数量を計算します。
# たとえば、100 Aポイント -> 80 Bポイントのような変換を想定できます。
minted_amount = amount * rate
# 4. 宛先の残高を増やします。
# これは、ブリッジでいうミントやアンロックに似た役割です。
destination.credit(user_id, minted_amount)
# 5. 処理結果を返します。
return {
"user_id": user_id,
"source": source.name,
"destination": destination.name,
"debited_amount": amount,
"credited_amount": minted_amount,
}
# ここから下は、動作確認用の架空データです。
# aliceがService Aに10,000ポイントを持っている想定にします。
service_a = Ledger(name="Service A", balances={"alice": 10000})
service_b = Ledger(name="Service B", balances={"alice": 0})
print("交換前")
print("Service A:", service_a.get_balance("alice"))
print("Service B:", service_b.get_balance("alice"))
# Service Aの10,000ポイントを、交換レート0.8でService Bへ反映します。
result = transfer_between_ledgers(
source=service_a,
destination=service_b,
user_id="alice",
amount=10000,
rate=0.8,
)
print("\n交換結果")
print(result)
print("\n交換後")
print("Service A:", service_a.get_balance("alice"))
print("Service B:", service_b.get_balance("alice"))
このコードを実行すると、ざっくり次のような結果になります。
交換前
Service A: 10000
Service B: 0
交換結果
{'user_id': 'alice', 'source': 'Service A', 'destination': 'Service B', 'debited_amount': 10000, 'credited_amount': 8000.0}
交換後
Service A: 0
Service B: 8000.0
ここで見てほしいのは、次の流れです。
- 送信元の残高を確認する
- 送信元の残高を減らす
- 交換レートに応じて宛先側の数量を計算する
- 宛先側の残高を増やす
これは、ブリッジそのものではありません。
ただし、片方の台帳を減らし、もう片方の台帳を増やす という感覚をつかむには役立ちます。
ブリッジでは、この単純な流れに加えて、次のような要素が必要になります。
| このコードの処理 | ブリッジで追加される考え方 |
|---|---|
| 送信元の残高を確認する | 送信元チェーンで本当に資産があるか、ロックできるかを確認する |
| 送信元の残高を減らす | ロック、バーンなどで二重利用を防ぐ |
| 宛先側の残高を増やす | ミント、アンロック、流動性からの支払いを行う |
| 関数内で直接処理する | 実際にはチェーンが分かれているため、メッセージや証明が必要になる |
| 失敗時を単純な例外で扱う | 実際には返金、再実行、claim、手動対応などが必要になる場合がある |
つまり、このコードはあくまで「考え方の模型」です。
実際のブリッジは、もっと複雑です。
1.5 ブリッジに近づけると、何が難しくなるのか
先ほどのコードでは、transfer_between_ledgers() という1つの関数の中で、送信元の減算と宛先の加算をまとめて行いました。
しかし、ブロックチェーンブリッジでは、ここがもっと難しくなります。
理由は、送信元チェーンと宛先チェーンが別々に動いているからです。
たとえば、Chain Aで100 TESTをロックしたあと、Chain Bでwrapped TESTをミントする場合を考えます。
このとき、Chain BはChain Aの状態をそのまま直接読めるわけではありません。
そのため、次のような問いが出てきます。
| 問い | なぜ難しいか |
|---|---|
| Chain Aで本当にロックされたのか | Chain BはChain Aの台帳を直接信頼できるとは限らない |
| そのメッセージは改ざんされていないか | 不正なメッセージでミントされると裏付けのない資産が生まれる |
| 同じロックイベントを二重に使っていないか | 二重ミントにつながる可能性がある |
| Chain Aの取引は巻き戻らないか | finalityが不十分だと状態が食い違う可能性がある |
| Chain B側のミントに失敗したらどうするか | 資産が途中で止まったように見える場合がある |
| 誰がメッセージを運び、誰が検証するのか | 信頼モデルやセキュリティリスクに直結する |
図にすると、次のようになります。
この図で中心になるのは、正しいメッセージか検証する という部分です。
ブリッジのリスクを考えるうえでは、ここがとても重要になります。
不正なメッセージを正しいものとして扱ってしまうと、宛先チェーンで本来発行してはいけないトークンがミントされる可能性があります。
逆に、正しいメッセージなのに届かない、検証されない、実行に失敗する場合は、ユーザーから見ると資産が途中で止まったように見えるかもしれません。
つまり、ブリッジでは単に「片方を減らして、もう片方を増やす」だけでなく、次のようなことを考える必要があります。
- メッセージをどう作るか
- 誰がメッセージを運ぶか
- 誰がメッセージを検証するか
- いつ取引が十分に確定したと見るか
- 同じメッセージを二重に使えないようにするにはどうするか
- 失敗したときに資産やメッセージをどう扱うか
ここまで来ると、ブリッジが単なる「送金機能」ではなく、かなり複雑な信頼モデルを持つ仕組みだと分かってきます。
1.6 残高移動で大切なのは「整合性」
ここまでの例をまとめると、残高移動で大切なのは 整合性 です。
整合性とは、ざっくり言えば「記録同士のつじつまが合っていること」です。
たとえば、ポイント交換で次のような状態になると困ります。
| 状態 | 何が問題か |
|---|---|
| A社ポイントが減っていないのに、B社ポイントだけ増えた | ポイントが不正に増えている |
| A社ポイントは減ったのに、B社ポイントが増えていない | 利用者から見るとポイントが消えたように見える |
| 同じ交換申請でB社ポイントが2回増えた | 二重発行になっている |
| 交換レートと違う数量が増えた | 計算や設定に問題がある |
| 途中で失敗したのに記録が残っていない | 復旧や確認が難しくなる |
ブリッジでも同じように、整合性が重要になります。
| ブリッジでの状態 | 起こり得る問題 |
|---|---|
| ロックされていないのにミントされた | 裏付けのないトークンが発行される |
| ロックされたのにミントされない | ユーザー資産が途中で止まったように見える |
| 同じメッセージで複数回ミントされた | 二重ミントにつながる |
| ロック量と発行量が合わない | ラップド資産の信頼が崩れる |
| 失敗時の記録や復旧手段がない | トラブル対応が難しくなる |
この章では、まだ詳しいセキュリティリスクまでは扱いません。
ただし、後の章で扱うスマートコントラクトリスク、検証者リスク、流動性リスク、リプレイリスクなどは、すべてこの整合性の話につながっています。
💡 豆知識
ブリッジの安全性を考えるときは、「ちゃんと届くか」だけでなく、「二重に増えないか」「途中で止まったときに分かるか」「ロック量と発行量が合っているか」も重要です。
これは、銀行振込やポイント交換で残高のつじつまが合っているかを確認する感覚に近いです。
1.7 ブロックチェーンに置き換えるとどう見えるか
ここまで、銀行振込やポイント交換を例にして、別々の台帳をつなぐ感覚を見てきました。
では、ブロックチェーンに置き換えるとどうなるでしょうか。
| 身近な例 | ブロックチェーンでの対応イメージ |
|---|---|
| A銀行の台帳 | Chain Aの台帳 |
| B銀行の台帳 | Chain Bの台帳 |
| A社ポイント | Chain A上のトークン |
| B社ポイント | Chain B上のトークン、またはラップドトークン |
| 交換申請 | ブリッジの利用リクエスト |
| 交換レートや条件確認 | メッセージや証明の検証 |
| 片方を減らして片方を増やす | ロック・バーン・ミント・アンロック |
| 残高のつじつま | ロック量と発行量の整合性 |
この対応を見ると、ブリッジの入口はかなり身近な話とつながっていることが分かります。
もちろん、ブロックチェーンでは銀行やポイントサービスとは違い、スマートコントラクト、署名、検証者、finality、ガス代などが関係します。
しかし、最初の感覚としては、別々の台帳をどう整合させるか と考えると理解しやすくなります。
ここまでの話を、ブリッジ寄りの図にすると次のようになります。
この図の中で、次の章以降で詳しく見ていくポイントは3つです。
- ロック・バーン・ミントとは何か
- 出来事をどう伝え、誰が検証するのか
- どこが失敗すると、どのようなリスクになるのか
この3つを順番に見ていくことで、ブリッジの全体像がかなり見えやすくなります。
1.8 この章のまとめ
この章では、ブロックチェーンブリッジに入る前に、銀行振込、ポイント交換、電子マネー、ゲームアイテムのような身近な残高移動から考えました。
身近な例を見ると、次のことが分かります。
- 価値の記録が別々の仕組みに分かれている場合、そのまま共有することはできない
- 銀行振込では、A銀行側の台帳とB銀行側の台帳を対応させる必要がある
- ポイント交換では、片方のポイントを減らし、もう片方のポイントを増やす処理が行われる
- 電子マネーやゲームアイテムも、別の仕組みではそのまま使えるとは限らない
- 別々の台帳をつなぐときは、残高の整合性が重要になる
- ブリッジでも、ロック、バーン、ミント、アンロックを通じて、別チェーン側に対応する状態を作る
- ただし、ブリッジではメッセージの伝達、検証者、署名、finality、失敗時対応などが加わるため、より複雑になる
この章で押さえたいポイントは、ブリッジは突然出てくる特殊な技術ではなく、別々の台帳をどう整合させるかという問題の延長にある ということです。
次の章では、ここで見た身近な例をもとに、ブロックチェーンブリッジを一言でいうと何なのか を整理します。
いよいよ、ブリッジを「異なるチェーンの間で、資産やメッセージを扱えるようにする仕組み」として見ていきます。
2. ブロックチェーンブリッジを一言でいうと
この章では、前章で見た「別々の台帳をどう整合させるか」という感覚をもとに、ブロックチェーンブリッジを一言で整理します。
ポイントは、ブリッジを単なる送金機能ではなく、異なるチェーンの間で、資産やメッセージを扱えるようにする仕組み として見ることです。
前章では、銀行振込やポイント交換を例にして、別々の台帳をつなぐ感覚を確認しました。
A銀行の台帳とB銀行の台帳は別です。
A社ポイントとB社ポイントも別々の仕組みで管理されています。
そのため、片方の記録が変わったからといって、もう片方の記録が自動で変わるわけではありません。
ブロックチェーンでも同じように、Ethereum、Solana、Arbitrum、Optimism、Avalancheなどは、それぞれ別の台帳、別のルール、別の状態を持っています。
そのため、Ethereum上にあるトークンを、Solanaのような別L1やL2上でそのまま使えるわけではありません。
また、あるチェーン上のスマートコントラクトで起きた出来事を、別のチェーンのスマートコントラクトが自動で理解できるわけでもありません。
そこで登場するのが、ブロックチェーンブリッジです。
2.1 ブリッジは「異なるチェーンをつなぐ仕組み」
ブロックチェーンブリッジを一言でいうと、次のように整理できます。
ブロックチェーンブリッジとは、異なるブロックチェーンの間で、資産やメッセージを扱えるようにする仕組みです。
ここで大切なのは、ブリッジが単に「送金する道具」ではないという点です。
もちろん、ユーザーから見ると「Chain AからChain Bへトークンを送る機能」に見えることが多いです。
しかし、裏側では、次のような処理が関係します。
- 送信元チェーンで資産をロックする
- 送信元チェーンで資産をバーンする
- 送信元チェーンで起きたイベントを検出する
- その出来事をメッセージや証明として宛先チェーンへ伝える
- 宛先チェーン側でメッセージの正しさを確認する
- 宛先チェーンで対応するトークンをミントする
- 宛先チェーンで既存の流動性から支払う
- 別チェーンのスマートコントラクトを呼び出す
Ethereum.orgの開発者向け資料でも、ブリッジは孤立したブロックチェーン環境を接続し、トークン、メッセージ、任意データ、スマートコントラクト呼び出しを別チェーンへ転送できる経路を作るものとして説明されています。
つまり、ブリッジは「資産を送るだけ」の仕組みではなく、別々のチェーンの間で情報や状態を対応させる仕組み と見ると分かりやすくなります。
この図では、ブリッジを「道」ではなく、出来事を伝えて、正しさを確認し、宛先側で対応する処理を行う仕組み として描いています。
2.2 「チェーンが違う」とはどういうことか
ブリッジを理解するには、まず「チェーンが違う」とは何が違うのかを押さえる必要があります。
たとえば、EthereumとSolanaでは、使われるアドレス形式、取引の処理方法、スマートコントラクトの実行環境、手数料の仕組み、finalityの考え方などが異なります。
EthereumとL2の間でも、L1とL2で状態が分かれており、引き出し時にチャレンジ期間が関係する場合があります。
ここでは細かい仕様に深入りしませんが、次のように考えると分かりやすいです。
| 違いの例 | 何が変わるか | ブリッジで気にすること |
|---|---|---|
| 台帳が違う | 残高や取引履歴が別々に管理される | 片方の出来事をもう片方がどう知るか |
| ルールが違う | 取引の成立条件や手数料が違う | どのタイミングで処理済みと見るか |
| スマートコントラクト環境が違う | 実行できるプログラムや仕様が違う | 宛先側でどう実行するか |
| finalityが違う | 取引が巻き戻りにくくなるまでの考え方が違う | いつメッセージを安全に扱うか |
| トークン規格が違う | 同じ名前の資産でも実装が違う | 元資産とラップド資産をどう対応させるか |
| アドレス形式が違う | 送信先の表し方が違う | 誤送信や宛先指定ミスに注意する |
身近な例でいうと、別々の会社が管理するポイントサービスに近いです。
A社ポイントとB社ポイントは、どちらも「ポイント」と呼ばれるかもしれません。
しかし、残高を管理しているデータベース、交換レート、利用できる店舗、有効期限、規約は別々です。
ブロックチェーンでも、同じ「トークン」や「送金」という言葉を使っていても、チェーンごとに状態やルールが違います。
そのため、別チェーンで使えるようにするには、何らかの変換・伝達・検証が必要になります。
2.3 トークンだけでなく、メッセージも渡せる
ブリッジというと、まずトークン転送を思い浮かべる人が多いと思います。
たとえば、次のような操作です。
Ethereum上のトークンをL2へ移す
Solana上の資産を別チェーンで使えるようにする
あるチェーン上のUSDCを別チェーン側で使えるようにする
もちろん、これはブリッジの重要な用途です。
ただし、最近のクロスチェーン系プロトコルでは、トークンだけでなく メッセージ も重要になります。
ここでいうメッセージは、日常会話のメッセージではありません。
別チェーンのスマートコントラクトへ渡す命令やデータのようなものです。
かなり単純化すると、次のようなイメージです。
Chain Aでユーザーが操作する
↓
「Chain Bのコントラクトで、この処理を実行してほしい」というメッセージを作る
↓
そのメッセージが正しいか検証される
↓
Chain B側でスマートコントラクトが実行される
Chainlink CCIPの公式ドキュメントでは、CCIPはトークン転送、メッセージング、プログラム可能なトークン転送のためのクロスチェーン相互運用プロトコルとして説明されています。
また、Wormholeの公式ドキュメントでも、Wormholeは複数ブロックチェーン間の安全で効率的な通信を可能にする generic message-passing protocol と説明されています。
参考: Wormhole Docs: Introduction to Wormhole
このように、ブリッジや相互運用プロトコルでは、トークン転送とメッセージ伝達を分けて考えることが大切です。
| 種類 | 例 | 見るポイント |
|---|---|---|
| トークン転送 | Chain Aの資産をChain Bで使えるようにする | ロック、バーン、ミント、アンロック、裏付け |
| メッセージ伝達 | Chain Bのスマートコントラクトへ命令を送る | 正しさの検証、重複実行防止、実行失敗 |
| 任意データ | 状態、証明、ペイロードなどを渡す | 改ざんされていないか、形式が正しいか |
| プログラム可能な転送 | トークン転送と同時に宛先側で処理を行う | 資産移動とコントラクト実行の両方を見る |
トークン転送だけであれば、「何枚のトークンがどこでロックされ、どこで発行されたか」を中心に見ます。
一方、メッセージ伝達では、「その命令が正しいか」「一度だけ実行されるか」「失敗した場合にどうなるか」も重要になります。
2.4 「橋を渡る」という比喩で誤解しやすい点
「ブリッジ」という言葉は、とても分かりやすい比喩です。
橋があれば、川の向こう側へ渡れます。
ブロックチェーンブリッジも、異なるチェーンの間をつないでくれる仕組みです。
ただし、この比喩には少し注意が必要です。
現実の橋では、人や車がこちら側から向こう側へ物理的に移動します。
しかし、ブロックチェーンブリッジでは、トークンが物理的に別チェーンへ移動しているわけではありません。
多くの場合は、次のような処理で「移動したように扱う」形になります。
たとえば、Lock and Mintでは、送信元チェーンで元のトークンをロックし、宛先チェーンで対応するトークンをミントします。
Burn and Mintでは、送信元チェーンでトークンをバーンし、宛先チェーンで同量をミントします。
つまり、ユーザーからは「Chain AからChain Bへ移動した」ように見えても、技術的には Chain A側の状態変更 と Chain B側の状態変更 が対応している、という見方の方が正確です。
ここを混同すると、次のような誤解につながります。
| 誤解 | より正確な見方 |
|---|---|
| トークンが橋を渡って別チェーンへ移動する | 多くの場合、送信元でロック・バーンし、宛先で対応する表現を作る |
| 宛先チェーンのトークンは元のトークンと完全に同じ | ラップドトークンなど、裏付けや発行の仕組みが異なる場合がある |
| ブリッジを通れば自動で安全に反映される | メッセージ検証、署名、finality、失敗時対応が必要になる |
| 速く届けばよいブリッジである | 速度だけでなく、信頼モデルや失敗時の扱いも重要になる |
ブリッジという言葉は入口として便利です。
ただし、理解を深めるときは、橋そのものよりも 別々の台帳の間で対応する記録をどう作るか に注目すると、より正確に見えてきます。
💡 豆知識
ブリッジを「橋」として考えると、トークンが移動しているように見えます。
しかし、実際には「片方の世界で使えない状態にして、もう片方の世界で使える表現を作る」ことが多いです。
ポイント交換や両替に近いイメージを持つと、誤解しにくくなります。
2.5 ブリッジで大切なのは「何を誰が検証するか」
ブリッジの説明で一番大切なのは、何を誰が検証するのか です。
たとえば、Chain Aで100 TESTがロックされたとします。
Chain Bで100 wrapped TESTをミントするには、Chain B側が次のようなことを確認する必要があります。
- Chain Aで本当に100 TESTがロックされたのか
- そのロックイベントは確定しているのか
- メッセージは改ざんされていないか
- そのメッセージはすでに使われていないか
- 宛先は正しいか
- ミントしてよい数量は正しいか
- 誰の署名や証明を信じるのか
ここで、「メッセージを運ぶこと」と「メッセージを正しいと確認すること」は別です。
身近な例でいうと、郵便配達員は手紙を届けてくれます。
しかし、その手紙の内容が本当に正しいか、差出人が本物か、契約内容が有効かまで、配達員がすべて保証しているわけではありません。
ブリッジでも同じです。
| 役割 | ざっくりした説明 | 注意点 |
|---|---|---|
| リレイヤー | メッセージや証明を別チェーンへ運ぶ | 運ぶだけで、正しさを保証するとは限らない |
| 検証者・ガーディアン | メッセージの正しさを確認し、署名する | 鍵管理や閾値設計が重要 |
| ライトクライアント | 別チェーンの状態を検証する | 実装や検証コストが難しくなる場合がある |
| 発行体 | バーンやミントに関する証明を出す | 発行体への信頼が重要 |
| Watcher | 不正がないか監視し、必要に応じて異議を出す | 監視が機能しないとリスクが高まる |
このように、ブリッジでは「誰が運ぶのか」だけでなく、「誰が正しいと判断するのか」を見る必要があります。
この図では、リレイヤーはメッセージを運ぶ役割です。
一方で、そのメッセージが正しいかを判断するのは、検証者やスマートコントラクト、ライトクライアント、発行体のアテステーションなどです。
ここを分けて理解すると、ブリッジのリスクも見えやすくなります。
2.6 小さな疑似コードで見る「検証してから実行する」流れ
ここで、ブリッジの基本的な考え方を、かなり単純化した疑似コードで見てみます。
これは実在ブリッジの実装ではありません。
攻撃手順や実用コードでもありません。
目的は、ブリッジでよく出てくる 検証してから実行する、同じメッセージを二重に使わせない という考え方を理解することです。
# このコードは、ブリッジの考え方を理解するための学習用コードです。
# 実在するブリッジ、スマートコントラクト、署名検証、証明検証を再現するものではありません。
from dataclasses import dataclass
@dataclass(frozen=True)
class BridgeMessage:
"""
チェーンをまたいで運ばれるメッセージを表す簡単なデータです。
source_chain:
メッセージが発生した送信元チェーンです。
destination_chain:
メッセージを実行したい宛先チェーンです。
sender:
送信元のユーザーやコントラクトを表します。
receiver:
宛先側で受け取るユーザーやコントラクトを表します。
amount:
移動・反映したい数量です。
nonce:
メッセージを一意に識別するための番号です。
同じメッセージの二重実行を防ぐために使います。
"""
source_chain: str
destination_chain: str
sender: str
receiver: str
amount: int
nonce: int
class SimpleBridgeExecutor:
"""
宛先チェーン側でメッセージを処理する役割を、かなり単純化したクラスです。
"""
def __init__(self, chain_name):
# このExecutorが担当する宛先チェーン名です。
self.chain_name = chain_name
# すでに処理したメッセージIDを記録します。
# これにより、同じメッセージの二重実行を防ぐイメージを表します。
self.processed_message_ids = set()
# 宛先チェーン側の残高を表す簡単な辞書です。
self.balances = {}
def make_message_id(self, message):
"""
メッセージを一意に識別するIDを作ります。
実際のブリッジでは、tx hash、chain id、emitter address、sequence、
nonceなどを組み合わせる場合があります。
ここでは学習用に単純化しています。
"""
return (
message.source_chain,
message.destination_chain,
message.sender,
message.receiver,
message.amount,
message.nonce,
)
def verify_source_event(self, message, proof):
"""
送信元チェーンで本当に出来事が起きたかを検証する処理のイメージです。
注意:
ここでは説明を簡単にするため、proof == "valid" のときだけ正しいとします。
実際のブリッジでは、署名検証、Merkle proof、ライトクライアント検証、
アテステーション検証など、方式ごとに異なる検証が行われます。
"""
return proof == "valid"
def execute_message(self, message, proof):
"""
メッセージを検証し、問題がなければ宛先側の残高を増やします。
"""
# 1. このメッセージが、このチェーン宛てか確認します。
if message.destination_chain != self.chain_name:
raise ValueError("このチェーン宛てのメッセージではありません")
# 2. メッセージIDを作成します。
message_id = self.make_message_id(message)
# 3. 同じメッセージがすでに処理済みでないか確認します。
# これはリプレイや二重実行を防ぐための基本的な考え方です。
if message_id in self.processed_message_ids:
raise ValueError("このメッセージはすでに処理済みです")
# 4. 送信元チェーンで本当に出来事が起きたかを検証します。
# 実際には、ここがブリッジ方式ごとの重要な違いになります。
if not self.verify_source_event(message, proof):
raise ValueError("送信元チェーンの出来事を検証できませんでした")
# 5. 検証に成功したら、宛先側で対応する処理を行います。
# ここでは、receiverの残高を増やす処理として表現しています。
self.balances[message.receiver] = self.balances.get(message.receiver, 0) + message.amount
# 6. 処理済みメッセージとして記録します。
# これにより、同じメッセージが再利用されることを防ぐイメージです。
self.processed_message_ids.add(message_id)
return {
"status": "executed",
"receiver": message.receiver,
"credited_amount": message.amount,
}
# ここから下は、動作確認用の架空データです。
executor = SimpleBridgeExecutor(chain_name="Chain B")
message = BridgeMessage(
source_chain="Chain A",
destination_chain="Chain B",
sender="alice",
receiver="alice",
amount=100,
nonce=1,
)
# proof="valid" として、送信元チェーンの出来事が検証できたものとして扱います。
result = executor.execute_message(message, proof="valid")
print(result)
print(executor.balances)
このコードで見てほしいのは、次の流れです。
- メッセージが宛先チェーン向けか確認する
- メッセージIDを作る
- すでに処理済みでないか確認する
- 送信元チェーンの出来事を検証する
- 検証に成功した場合だけ、宛先側で処理する
- 処理済みとして記録し、二重実行を防ぐ
実行結果のイメージは次のようになります。
{'status': 'executed', 'receiver': 'alice', 'credited_amount': 100}
{'alice': 100}
このコードは、あくまで学習用です。
実際のブリッジでは、proof == "valid" のような単純な判定ではなく、署名、Merkle proof、ライトクライアント、ガーディアン署名、アテステーションなど、方式ごとに異なる検証が行われます。
それでも、この小さな例から次のことは見えてきます。
| コード上の処理 | ブリッジで重要になる理由 |
|---|---|
| 宛先チェーンを確認する | 別チェーン向けのメッセージを誤って実行しないため |
| メッセージIDを作る | 同じメッセージを識別するため |
| 処理済みか確認する | リプレイや二重実行を防ぐため |
| proofを検証する | 送信元チェーンの出来事が本当に正しいか確認するため |
| 検証後に実行する | 不正なメッセージでミントや実行をしないため |
| 処理済みとして記録する | 同じ出来事を何度も使えないようにするため |
この章の段階では、まだ各検証方式の詳細には入りません。
ただし、ブリッジを理解するうえで、検証してから実行する、一度使ったメッセージを再利用させない という考え方はとても大切です。
2.7 Trusted bridgeとTrustless bridgeという分類
ブリッジを調べていると、trusted bridge や trustless bridge という言葉が出てくることがあります。
Ethereum.orgでは、ブリッジを大きく trusted bridge と trustless bridge に分けて説明しています。
trusted bridgeは中央の主体やシステムに依存するもの、trustless bridgeはスマートコントラクトやアルゴリズムを使い、追加の信頼仮定をできるだけ小さくしようとするものとして説明されています。
参考: Ethereum.org: Introduction to blockchain bridges
ただし、ここで注意したいのは、trustless という言葉を 何も信頼しなくてよい と読まないことです。
ブロックチェーンの文脈で trustless と言う場合、多くは「特定の中央主体を信頼しなくてもよいように設計されている」「信頼をプロトコルや検証に寄せている」という意味で使われます。
それでも、実装、スマートコントラクト、基盤チェーン、暗号技術、運用、アップグレード権限などへの信頼は残ります。
| 分類 | ざっくりした意味 | 注意点 |
|---|---|---|
| Trusted bridge | 特定の運営主体、管理者、検証者セットなどを信頼する設計 | 鍵管理、権限、運用体制が重要 |
| Trustless bridge | スマートコントラクトや暗号学的検証により、追加の信頼仮定を小さくしようとする設計 | 実装、検証コスト、基盤チェーンへの信頼は残る |
つまり、trustedとtrustlessは「安全」と「危険」を単純に分けるラベルではありません。
大切なのは、何を信頼しているのか を見ることです。
💡 豆知識
trustlessは「信頼がゼロ」というより、「特定の人や会社への信頼をできるだけ減らし、コードや暗号学的検証に寄せる」という意味で使われることが多いです。
そのため、trustlessと書かれていても、実装や運用を何も確認しなくてよいわけではありません。
2.8 この章のまとめ
この章では、ブロックチェーンブリッジを一言で整理しました。
ブリッジは、異なるチェーンの間で資産やメッセージを扱えるようにする仕組みです。
ただし、トークンが物理的に橋を渡るわけではありません。
多くの場合、送信元チェーンでロックやバーンを行い、宛先チェーンで対応するトークンをミントしたり、メッセージを実行したりします。
この章で押さえたいポイントは、次の通りです。
- ブリッジは、異なるチェーンの間で資産やメッセージを扱えるようにする仕組みである
- チェーンごとに台帳、ルール、状態、スマートコントラクト環境が違う
- ブリッジでは、トークン転送だけでなく、メッセージや任意データも重要になる
- 「橋を渡る」という比喩は便利だが、資産が物理的に移動するわけではない
- 大切なのは、送信元チェーンの出来事を誰がどう検証するのかである
- メッセージを運ぶ役割と、メッセージを検証する役割は分けて考える
- trusted / trustless という分類は、安全・危険の単純なラベルではなく、信頼仮定を見るための入口である
次の章では、ブリッジで特に誤解しやすい 「資産は本当にチェーンを移動しているのか」 をもう少し詳しく見ていきます。
Lock and Mint、Burn and Mint、Lock and Release、ラップドトークンを整理しながら、別チェーン側で資産がどのように表現されるのかを確認します。
3. 資産は本当にチェーンを移動しているのか
この章では、ブリッジで特に誤解しやすい「資産は本当に別チェーンへ移動しているのか」を整理します。
ポイントは、多くの場合、資産が物理的に移動するのではなく、送信元チェーンと宛先チェーンで対応する状態を作っている ということです。
前の章では、ブロックチェーンブリッジを、異なるチェーンの間で資産やメッセージを扱えるようにする仕組みとして整理しました。
ここで、もう少し踏み込んで考えたいことがあります。
それは、ユーザー画面でよく見る 「Chain AからChain Bへ送る」 という表現です。
この表現は直感的で分かりやすいです。
しかし、技術的には少し注意が必要です。
多くのブリッジでは、トークンそのものが物理的に別チェーンへ移動しているわけではありません。
そもそもブロックチェーンは、それぞれ別の台帳を持っています。
Chain A上のトークン残高はChain Aの状態であり、Chain B上の残高はChain Bの状態です。
そのため、ブリッジでは、次のような考え方がよく使われます。
送信元チェーン側:
元の資産をロックする、またはバーンする
宛先チェーン側:
対応する資産表現をミントする、または既存流動性から支払う
つまり、ユーザーからは「資産が移動した」ように見えても、裏側では 片方のチェーンで状態を変え、もう片方のチェーンで対応する状態を作る ことで実現している場合が多いです。
この章では、その代表的な方式として、次の4つを整理します。
| 方式 | ざっくりした説明 | 身近なたとえ |
|---|---|---|
| Lock and Mint | 送信元で資産をロックし、宛先で対応するトークンをミントする | 荷物を預けて、別の場所で引換券を受け取る |
| Burn and Mint | 送信元で資産をバーンし、宛先で同量をミントする | 古いチケットを無効化し、別会場で新しいチケットを発行する |
| Lock and Release | 送信元で資産をロックし、宛先側の既存資産をリリースする | 両替所が手元の通貨から支払う |
| Liquidity Network | 流動性提供者やフィラーが先に支払い、あとで精算する | 別店舗の在庫から先に渡し、あとで店舗間で調整する |
Ethereum.orgの開発者向け資料でも、ブリッジにおける代表的な資産移転方式として、Lock and Mint、Burn and Mint、Atomic Swapが整理されています。
3.1 まずはポイント交換で考える
いきなりトークンの話に入る前に、もう一度ポイント交換で考えてみます。
A社ポイント10,000ポイントを、B社ポイント8,000ポイントに交換する場面を想像してください。
このとき、A社ポイントがB社のデータベースへそのまま移動するわけではありません。
多くの場合、次のような処理になります。
1. A社側で、ユーザーのA社ポイントを10,000ポイント減らす
2. 交換条件を確認する
3. B社側で、ユーザーのB社ポイントを8,000ポイント増やす
表にすると、次のようになります。
| 時点 | A社ポイント | B社ポイント | 説明 |
|---|---|---|---|
| 交換前 | 10,000 | 0 | A社側にポイントがある |
| A社側の処理後 | 0 | 0 | A社ポイントは使えない状態になる |
| B社側の反映後 | 0 | 8,000 | B社側で使えるポイントが増える |
ここで大切なのは、A社ポイントとB社ポイントは別々の記録である という点です。
ブリッジでも同じです。
Chain A上のトークンと、Chain B上のトークンは別々のチェーン上にあります。
そのため、「Chain Aで使えない状態にする」「Chain Bで対応する表現を作る」という考え方が必要になります。
3.2 Lock and Mint:預けて、別チェーンで表現を作る
まずは、代表的な方式の一つである Lock and Mint から見ていきます。
Lock and Mintは、ざっくり言うと次のような方式です。
送信元チェーン:
元のトークンをブリッジコントラクトにロックする
宛先チェーン:
ロックされたことを確認して、対応するトークンをミントする
図にすると、次のようになります。
ここで出てくる wrapped TEST は、元のTEST Tokenに対応する別チェーン上の表現です。
身近なたとえでいうと、荷物を預けて引換券を受け取るイメージに近いです。
- 元の荷物は預けられていて、自由には使えない
- 手元には、その荷物に対応する引換券がある
- 引換券自体は便利だが、裏側には「本当に荷物が預けられている」という前提がある
Lock and Mintでも同じです。
Chain Aで100 TESTがロックされているからこそ、Chain Bで100 wrapped TESTを発行できます。
もしChain A側でロックされていないのにChain B側でwrapped TESTだけ発行できてしまうと、裏付けのないトークンが生まれてしまいます。
| 観点 | Lock and Mintで見ること |
|---|---|
| 送信元チェーン | 元資産がロックされているか |
| 宛先チェーン | 対応するトークンがミントされているか |
| 重要な対応関係 | ロック量とミント量が合っているか |
| 主な注意点 | ロックされていないのにミントされないか、二重ミントされないか |
OptimismのStandard Bridgeの公式ドキュメントでも、ネイティブトークンをブリッジ表現へ変換する際に、片側でネイティブトークンをロックし、もう片側でブリッジされた表現をミントする lock-and-mint mechanism が説明されています。
参考: Optimism Docs: Using the Standard Bridge
ただし、実際のL2ブリッジでは、deposit、withdrawal、challenge period、fault proofなども関係する場合があります。
ここではまず、Lock and Mintの基本的な考え方として、「片方でロックし、もう片方で対応する表現を作る」と押さえておけば大丈夫です。
3.3 Burn and Mint:片方で消して、もう片方で発行する
次に、Burn and Mint を見ていきます。
Burn and Mintは、ざっくり言うと次のような方式です。
送信元チェーン:
トークンをバーンする
宛先チェーン:
バーンされたことを確認して、同量のトークンをミントする
ここでいう Burn は、トークンを使えない状態にする、または供給から取り除く処理です。
日常的なイメージでいうと、使い終わったチケットに穴を開けて再利用できないようにする感覚に近いです。
図にすると、次のようになります。
Lock and Mintとの違いは、送信元チェーン側で資産を「預ける」のではなく、「消す」点です。
| 比較 | Lock and Mint | Burn and Mint |
|---|---|---|
| 送信元チェーン | 資産をロックする | 資産をバーンする |
| 宛先チェーン | 対応するトークンをミントする | 同量のトークンをミントする |
| 元資産 | ブリッジコントラクトに残る | 供給から取り除かれる |
| イメージ | 荷物を預けて引換券を受け取る | 古いチケットを無効化して新しいチケットを発行する |
CircleのCCTP公式資料では、CCTPは送信元ブロックチェーンでUSDCをバーンし、宛先ブロックチェーンでUSDCをミントすることで、従来型のブリッジ流動性プールやラップドトークンなしに1:1の転送を可能にする仕組みとして説明されています。
参考: Circle Developers: Cross-Chain Transfer Protocol
このようなBurn and Mintでは、発行体やアテステーションの役割も重要になります。
つまり、「本当にバーンされたのか」「誰がそれを証明するのか」「宛先でミントしてよいのは誰か」という点を見る必要があります。
3.4 Lock and Release:既存の流動性から支払う
次に、Lock and Release の考え方を見てみます。
Lock and Releaseは、ざっくり言うと次のような方式です。
送信元チェーン:
ユーザーの資産をロックする
宛先チェーン:
すでに用意されている資産をユーザーへリリースする
Lock and Mintでは、宛先チェーン側で新しくトークンをミントします。
一方、Lock and Releaseでは、宛先側にあらかじめ用意されている流動性から支払います。
身近な例でいうと、両替所に近いです。
あなたが日本円を両替所に渡すと、両替所は手元にあるユーロを渡してくれます。
あなたの日本円そのものがユーロに変身しているわけではありません。
両替所が在庫として持っているユーロを渡し、裏側で会計を合わせています。
この方式では、宛先チェーン側に十分な流動性があるかが重要になります。
| 観点 | Lock and Releaseで見ること |
|---|---|
| 送信元チェーン | 資産がロックされたか |
| 宛先チェーン | 既存の資産をリリースできるか |
| 重要な要素 | 宛先側の流動性 |
| 主な注意点 | 流動性不足、手数料、精算の仕組み |
Chainlink CCIPのクロスチェーントークン関連資料でも、トークンプールの方式として、burn/mintやlock/releaseの考え方が整理されています。
参考: Chainlink Docs: Cross-Chain Token Standard - Overview
Lock and Releaseは、ユーザー体験としては速く見える場合があります。
ただし、宛先側の流動性が不足していると、期待通りに受け取れない可能性があります。
3.5 流動性ネットワーク:先に支払って、あとで精算する
Lock and Releaseと近い考え方として、流動性ネットワーク があります。
流動性ネットワークでは、流動性提供者、フィラー、マーケットメイカーのような参加者が、宛先チェーン側で先に支払う場合があります。
その後、裏側で送信元チェーン側の資産や精算処理と対応させます。
身近なたとえでいうと、別店舗の在庫から先に商品を渡し、あとで店舗間で在庫や会計を調整するイメージです。
この方式では、ユーザーから見ると速く受け取れることがあります。
一方で、流動性提供者が関係するため、手数料、価格差、流動性不足、精算失敗などの観点も重要になります。
| 観点 | 流動性ネットワークで見ること |
|---|---|
| ユーザー体験 | 速く受け取れる場合がある |
| 関係者 | LP、フィラー、マーケットメイカーなど |
| 重要な要素 | 流動性、手数料、精算 |
| 主な注意点 | 流動性不足、価格差、失敗時対応 |
ここまで見ると、ブリッジにはいくつかの実現方法があることが分かります。
大切なのは、方式名を暗記することではありません。
「どこで減らし、どこで増やしているのか」「誰がその対応関係を保証しているのか」を見ることです。
3.6 ラップドトークンとは何か
Lock and Mintを理解するときに重要になるのが、ラップドトークン です。
ラップドトークンとは、ざっくり言うと、元の資産に対応する別チェーン上の表現です。
たとえば、Chain AにあるTEST Tokenをロックし、Chain Bでwrapped TESTを発行する場合を考えます。
| 資産 | 存在する場所 | 役割 |
|---|---|---|
| TEST Token | Chain A | 元の資産 |
| wrapped TEST | Chain B | Chain A上のTESTに対応する表現 |
このとき、wrapped TESTはChain B上で使えるかもしれません。
ただし、元のTEST Tokenと完全に同じものではありません。
wrapped TESTの信頼性は、次のような要素に依存します。
- Chain A側で本当にTEST Tokenがロックされているか
- ロック量とwrapped TESTの発行量が合っているか
- ブリッジコントラクトにバグがないか
- メッセージ検証が正しく行われているか
- 管理者権限やアップグレード権限がどうなっているか
- 停止時や失敗時の対応がどうなっているか
図にすると、次のような関係です。
ラップドトークンは便利です。
別チェーン上のdAppsで、元資産に近い形で使える場合があります。
しかし、便利である一方で、元資産そのものではありません。
裏側には、ブリッジや発行元への信頼、ロック量と発行量の整合性、スマートコントラクトの安全性が関係します。
💡 豆知識
wrappedは「包まれた」という意味です。
ラップドトークンは、元の資産を別チェーンで扱いやすい形に「包み直した表現」と考えると分かりやすいです。
ただし、包み直された表現である以上、元資産との対応関係を誰がどう管理しているのかを見る必要があります。
3.7 小さなコードでロック量と発行量の整合性を見てみる
ここで、Lock and Mintの考え方を、かなり単純化したPythonコードで見てみます。
このコードは学習用です。
実在するブリッジ、スマートコントラクト、署名検証、証明検証を再現するものではありません。
目的は、ロックされた数量とミントされた数量のつじつまが合っているか を確認する考え方を理解することです。
# このコードは、Lock and Mintの整合性を理解するための学習用コードです。
# 実在するブリッジやスマートコントラクトの実装ではありません。
from dataclasses import dataclass, field
@dataclass
class SimpleLockMintBridge:
"""
Lock and Mintの状態を、かなり単純化して表すクラスです。
locked_on_source:
送信元チェーンでロックされた元資産の合計量です。
minted_on_destination:
宛先チェーンでミントされたラップド資産の合計量です。
processed_deposits:
すでに処理したdeposit_idを記録します。
同じ入金を二重にミントしないための簡易的な仕組みです。
"""
locked_on_source: int = 0
minted_on_destination: int = 0
processed_deposits: set = field(default_factory=set)
def lock(self, deposit_id, amount):
"""
送信元チェーンで資産をロックする処理を表します。
deposit_id:
入金イベントを識別するIDです。
amount:
ロックする数量です。
"""
if amount <= 0:
raise ValueError("amountは正の値である必要があります")
# deposit_idがすでに使われていないか確認します。
# 実際のブリッジでは、tx hashやevent indexなどで一意性を確認する場合があります。
if deposit_id in self.processed_deposits:
raise ValueError("このdeposit_idはすでに処理されています")
# 送信元チェーンでロックされた数量を増やします。
self.locked_on_source += amount
# このdeposit_idを処理済みとして記録します。
self.processed_deposits.add(deposit_id)
def mint(self, amount):
"""
宛先チェーンでラップド資産をミントする処理を表します。
注意:
本来は、ロックイベントの証明や署名を検証してからミントする必要があります。
ここでは整合性の考え方を示すため、検証処理は省略しています。
"""
if amount <= 0:
raise ValueError("amountは正の値である必要があります")
# 宛先チェーンでミントされた数量を増やします。
self.minted_on_destination += amount
def check_invariant(self):
"""
ロック量とミント量の整合性を確認します。
Lock and Mintでは、単純化すると、
宛先チェーンでミントされた量が、送信元チェーンでロックされた量を
上回らないことが重要です。
"""
return self.minted_on_destination <= self.locked_on_source
# 学習用の動作例です。
bridge = SimpleLockMintBridge()
# Chain Aで100 TESTをロックしたとします。
bridge.lock(deposit_id="deposit-001", amount=100)
# Chain Bで100 wrapped TESTをミントしたとします。
bridge.mint(amount=100)
print("locked_on_source:", bridge.locked_on_source)
print("minted_on_destination:", bridge.minted_on_destination)
print("invariant_ok:", bridge.check_invariant())
実行結果のイメージは次の通りです。
locked_on_source: 100
minted_on_destination: 100
invariant_ok: True
ここでは、ロック量100に対してミント量100なので、単純な整合性は保たれています。
もし、ロック量100に対してミント量が150になっていたらどうでしょうか。
# これは不整合の例です。
# 100しかロックされていないのに、150ミントされている状態を作っています。
bridge = SimpleLockMintBridge()
bridge.lock(deposit_id="deposit-001", amount=100)
bridge.mint(amount=150)
print("locked_on_source:", bridge.locked_on_source)
print("minted_on_destination:", bridge.minted_on_destination)
print("invariant_ok:", bridge.check_invariant())
実行結果のイメージは次の通りです。
locked_on_source: 100
minted_on_destination: 150
invariant_ok: False
これは、裏付けよりも多くのラップド資産が発行されている状態です。
実際のブリッジではもっと複雑な確認が必要ですが、考え方としては、ロック量と発行量の整合性を確認することが重要 です。
| コード上の要素 | ブリッジ理解での意味 |
|---|---|
locked_on_source |
送信元チェーンでロックされている元資産 |
minted_on_destination |
宛先チェーンで発行されているラップド資産 |
processed_deposits |
同じ入金イベントを二重に使わないための記録 |
check_invariant() |
ロック量と発行量のつじつまを見る簡易チェック |
もちろん、実際のブリッジでは、単純な合計量だけ見ればよいわけではありません。
トークンごと、チェーンごと、ユーザーごと、メッセージごと、手数料、decimals、失敗時の処理なども関係します。
それでも、この小さなモデルから、ブリッジでなぜ整合性が重要なのかをつかむことができます。
3.8 裏付けが壊れると何が起こるのか
ここまで見てきたように、Lock and Mintでは、送信元チェーンでロックされた資産と、宛先チェーンでミントされたラップド資産の対応関係が重要です。
では、この対応関係が壊れるとどうなるでしょうか。
たとえば、次のような状態が考えられます。
| 状態 | 起こり得る問題 |
|---|---|
| ロックされていないのにミントされる | 裏付けのないラップド資産が発行される |
| ロック量よりミント量が多い | ラップド資産の信頼が崩れる |
| ロックされたのにミントされない | ユーザーから見ると資産が途中で止まる |
| 同じロックイベントで複数回ミントされる | 二重発行につながる |
| ロック資産が失われる | ラップド資産の裏付けがなくなる |
| ブリッジが停止する | 資産を戻せない、移せない状態になる可能性がある |
ブリッジでは、このような不整合が大きな影響につながる場合があります。
たとえば、ラップドトークンがDeFiで担保として使われている場合、裏付けへの信頼が崩れると、そのトークンを使っている複数のアプリケーションにも影響が広がる可能性があります。
ここで大切なのは、ブリッジのリスクはユーザーが直接使っている画面だけで完結しない場合があるという点です。
もちろん、すべてのブリッジで同じような影響が出るわけではありません。
影響範囲は、方式、資産規模、接続先チェーン、利用されているdApps、停止・復旧の仕組みによって変わります。
そのため、本記事では今後、ブリッジの方式だけでなく、信頼モデルや失敗時の影響も分けて見ていきます。
3.9 この章のまとめ
この章では、ブリッジで資産がどのように別チェーン側で表現されるのかを整理しました。
ユーザーからは「Chain AからChain Bへ移動した」ように見えても、多くの場合、実際には送信元チェーンと宛先チェーンで対応する状態を作っています。
この章で押さえたいポイントは、次の通りです。
- ブリッジでは、トークンが物理的に別チェーンへ移動しているわけではない
- Lock and Mintでは、送信元で資産をロックし、宛先で対応するトークンをミントする
- Burn and Mintでは、送信元で資産をバーンし、宛先で同量をミントする
- Lock and Releaseでは、送信元でロックし、宛先側の既存流動性からリリースする
- 流動性ネットワークでは、LPやフィラーが先に支払い、あとで精算する場合がある
- ラップドトークンは元資産に対応する別チェーン上の表現であり、元資産と完全に同じではない
- ロック量と発行量の整合性が崩れると、裏付けのない資産や二重発行につながる可能性がある
- 方式名だけでなく、どこで減らし、どこで増やし、誰が対応関係を確認しているのかを見ることが重要である
次の章では、ここで整理した資産表現を踏まえて、実際にブリッジ処理がどのような順番で進むのかを整理します。
ユーザー、送信元チェーン、宛先チェーン、ブリッジコントラクト、リレイヤー、検証者といった登場人物を分けながら、処理の流れを図で追っていきます。
4. ブリッジの基本的な処理の流れ
この章では、ブリッジの処理を、登場人物と流れに分けて整理します。
ポイントは、ブリッジでは 送信元チェーンで起きた出来事を、誰かが観測・伝達・検証し、宛先チェーン側で対応する処理を行う ということです。
前の章では、ブリッジにおける資産の表現方法を整理しました。
特に、次のような方式を見てきました。
- 送信元チェーンで資産をロックし、宛先チェーンで対応するトークンをミントする
Lock and Mint - 送信元チェーンで資産をバーンし、宛先チェーンで同量をミントする
Burn and Mint - 送信元チェーンでロックし、宛先チェーン側の既存流動性からリリースする
Lock and Release - 流動性提供者やフィラーが先に支払い、あとで精算する流動性ネットワーク
ここでは、これらの方式が実際にどのような順番で進むのかを、もう少し処理の流れとして見ていきます。
ユーザーから見ると、ブリッジは「送る」ボタンを押すだけに見えるかもしれません。
しかし、裏側では複数の役割が関係します。
たとえば、次のような登場人物です。
- ユーザー
- 送信元チェーン
- 宛先チェーン
- ブリッジコントラクト
- リレイヤー
- 検証者・ガーディアン
- 流動性提供者
- 発行体
この章では、これらを一つずつ分けながら、ブリッジ処理の基本的な流れを整理します。
4.1 登場人物を整理する
まず、ブリッジ処理に関係する登場人物を整理します。
| 登場人物 | 役割 | 身近なたとえ |
|---|---|---|
| ユーザー | ブリッジを使って資産やメッセージを送る人 | 振込やポイント交換を依頼する人 |
| 送信元チェーン | 資産をロック・バーンする側のチェーン | A銀行やA社ポイント側 |
| 宛先チェーン | 資産をミント・アンロックする側のチェーン | B銀行やB社ポイント側 |
| ブリッジコントラクト | ロック、バーン、ミント、アンロックなどを行うスマートコントラクト | 交換処理を管理する窓口 |
| リレイヤー | メッセージや証明を別チェーンへ運ぶ役割 | 手紙や申請書を運ぶ配達役 |
| 検証者・ガーディアン | メッセージが正しいかを確認し、署名する役割 | 申請内容を確認する審査担当 |
| ライトクライアント | 別チェーンの状態や合意を検証する仕組み | 公式記録を自分で照合する仕組み |
| 発行体 | バーンやミントの証明を出す主体 | 通貨やポイントの発行元 |
| 流動性提供者・フィラー | 宛先チェーン側で先に資産を支払う役割 | 両替所や立替払いをする人 |
ここで特に大切なのは、メッセージを運ぶ役割 と メッセージを正しいと確認する役割 は同じとは限らない、という点です。
身近な例でいうと、郵便配達員は手紙を届けます。
しかし、手紙の内容が本当に正しいか、差出人が本物か、書かれている契約が有効かまでは、別の確認が必要です。
ブリッジでも同じです。
この「運ぶ」と「検証する」の違いを分けておくと、後の章で出てくるリレイヤー、ガーディアン、ライトクライアント、アテステーションの話が理解しやすくなります。
4.2 Lock and Mintの流れ
まず、Lock and Mintの流れを見てみます。
Lock and Mintでは、送信元チェーンで資産をロックし、宛先チェーンで対応するトークンをミントします。
かなり単純化すると、流れは次の通りです。
1. ユーザーがChain Aでブリッジを依頼する
2. Chain Aのブリッジコントラクトが資産をロックする
3. ロックされたことを示すイベントが発生する
4. そのイベントをリレイヤーや検証者が観測する
5. メッセージや証明がChain Bへ伝えられる
6. Chain B側でメッセージが検証される
7. 問題がなければ、Chain Bで対応するトークンがミントされる
図にすると、次のようになります。
ここで見るべきポイントは、送信元チェーンと宛先チェーンで別々の処理が起きていることです。
| 段階 | 起きていること | 注意点 |
|---|---|---|
| ユーザー依頼 | Chain Aでブリッジ操作を行う | 宛先チェーンや宛先アドレスを間違えない |
| ロック | Chain Aで元資産をロックする | ロックされていないのにミントしてはいけない |
| イベント発行 | ロックされたことを示す情報が出る | イベントをどう観測するか |
| 伝達 | メッセージや証明をChain Bへ送る | リレイヤーが停止すると遅れる可能性がある |
| 検証 | Chain B側で正しさを確認する | 署名・証明・重複実行の確認が重要 |
| ミント | Chain Bで対応するトークンを発行する | 二重ミントや数量誤りを防ぐ |
Ethereum.orgの開発者向け資料では、Lock and Mintは送信元チェーンで資産をロックし、宛先チェーンで資産をミントする方式として説明されています。
この流れで特に重要なのは、ロックされたことを、宛先チェーン側がどのように信じるのか です。
そこに、外部バリデータ、ガーディアン、ライトクライアント、アテステーションといった検証モデルが関係します。
4.3 Burn and Mintの流れ
次に、Burn and Mintの流れを見てみます。
Burn and Mintでは、送信元チェーンでトークンをバーンし、宛先チェーンで同量のトークンをミントします。
流れは次のようになります。
1. ユーザーがChain Aでブリッジを依頼する
2. Chain Aでトークンをバーンする
3. バーンされたことを示すイベントや証明が作られる
4. メッセージや証明がChain Bへ伝えられる
5. Chain B側で内容を検証する
6. 問題がなければ、Chain Bで同量のトークンをミントする
Burn and Mintでは、送信元側のトークンがバーンされるため、Lock and Mintのように元資産がブリッジコントラクト内に残るわけではありません。
| 比較 | Lock and Mint | Burn and Mint |
|---|---|---|
| 送信元チェーン | 資産をロックする | 資産をバーンする |
| 宛先チェーン | 対応する表現をミントする | 同量をミントする |
| 主な確認 | ロックされたか | バーンされたか |
| 信頼の見どころ | ロック量と発行量の整合性 | バーン証明と発行権限 |
CircleのCCTP公式資料では、送信元チェーンでUSDCをバーンし、宛先チェーンでUSDCをミントする仕組みとして説明されています。
参考: Circle Developers: Cross-Chain Transfer Protocol
この方式では、発行体やアテステーションサービスが重要になります。
つまり、「本当にバーンされたのか」「誰がそれを確認したのか」「誰が宛先チェーンでミントできるのか」を見る必要があります。
4.4 L2ブリッジでは、方向によって待ち時間が違うことがある
ブリッジ処理の流れを考えるとき、L1とL2のブリッジも重要です。
たとえば、OptimismのStandard Bridgeは、EthereumとOP Mainnetの間でETHや多くのERC-20トークンを移動できる基本的なブリッジシステムとして説明されています。
公式ドキュメントでは、EthereumからOP Mainnetへの転送は通常1〜3分程度で完了し、OP MainnetからEthereumへの転送はwithdrawal challenge periodのため7日かかると説明されています。
参考: Optimism Docs: Using the Standard Bridge
ここで大切なのは、同じブリッジでも 方向によって処理の性質が違う場合がある という点です。
| 方向 | ユーザーから見える例 | 注意点 |
|---|---|---|
| L1 → L2 | EthereumからL2へ預ける | 比較的短時間で反映される場合がある |
| L2 → L1 | L2からEthereumへ引き出す | チャレンジ期間や証明が関係し、時間がかかる場合がある |
これは、身近な例でいうと、入金はすぐ反映されるけれど、出金には確認期間があるサービスに少し似ています。
もちろん、L2ごとに設計は異なります。
そのため、実際に利用する場合は、必ず公式ドキュメントで待ち時間、手数料、失敗時の扱いを確認する必要があります。
Arbitrumでは、L1からL2へのメッセージングに retryable ticket という仕組みが使われます。
Arbitrumの公式ドキュメントでは、retryable ticketは親チェーンから子チェーンへのメッセージを作成するための標準的な仕組みとして説明されています。
参考: Arbitrum Docs: Bridging from a parent chain to a child chain
ここでは詳細には入りませんが、L2ブリッジでは「送ったらすぐ終わり」ではなく、メッセージ作成、実行、再実行、チャレンジ期間などが関係する場合があります。
💡 豆知識
ブリッジでは、「行き」と「帰り」で待ち時間が大きく違うことがあります。
特にOptimistic Rollup系のL2では、L2からL1へ戻すときにチャレンジ期間が関係する場合があります。
ユーザー画面で同じ「Bridge」に見えても、裏側の確認方法が違うことがあります。
4.5 メッセージング型の流れ
ここまで、トークンを中心に見てきました。
次に、メッセージング型の流れも整理しておきます。
メッセージング型では、別チェーンへ単にトークンを渡すだけでなく、命令やデータを送ります。
たとえば、次のような処理が考えられます。
Chain A:
ユーザーがコントラクトを操作する
メッセージ:
「Chain Bのコントラクトで、この処理を実行してほしい」
Chain B:
メッセージを検証し、問題がなければコントラクトを実行する
Wormholeの公式ドキュメントでは、VAAs(Verified Action Approvals)はWormholeの中核的なメッセージングの基本要素であり、Guardiansがコントラクトから発行されたメッセージを検証し、3分の2以上のsupermajorityが有効と認めると署名すると説明されています。
単純化した流れは次のようになります。
ここで大切なのは、メッセージング型では 宛先チェーン側で何かを実行する という点です。
トークン転送では、主に「残高を増やす」「トークンを発行する」という処理が中心になります。
一方、メッセージング型では、宛先側のスマートコントラクトが任意の処理を行う場合があります。
そのため、次のような注意が必要です。
| 注意点 | 内容 |
|---|---|
| メッセージの正しさ | 送信元が本当に正しいコントラクトか |
| 重複実行 | 同じメッセージが複数回実行されないか |
| 宛先の権限 | 誰が宛先コントラクトを呼び出せるか |
| 実行失敗 | 宛先側でガス不足や条件不一致が起きたらどうなるか |
| 順序 | 複数メッセージが順番通りに処理される必要があるか |
| リプレイ | 過去のメッセージが再利用されないか |
メッセージング型は便利です。
複数チェーンをまたいだアプリケーションを作れるようになります。
しかし、便利さが増えるほど、確認すべきことも増えます。
4.6 小さな状態遷移モデルでブリッジ処理を見てみる
ここで、ブリッジ処理の流れを、かなり単純化した状態遷移モデルとして見てみます。
これは実在ブリッジの実装ではありません。
目的は、ブリッジ処理が一気に終わるのではなく、いくつかの状態を通って進むことを理解することです。
# このコードは、ブリッジ処理の状態遷移を理解するための学習用コードです。
# 実在するブリッジ、スマートコントラクト、署名検証、証明検証を再現するものではありません。
from dataclasses import dataclass
from enum import Enum
class TransferStatus(Enum):
"""
ブリッジ処理の状態を表します。
"""
REQUESTED = "requested" # ユーザーがブリッジを依頼した状態
LOCKED = "locked" # 送信元チェーンで資産がロックされた状態
MESSAGE_SENT = "message_sent" # メッセージや証明が送られた状態
VERIFIED = "verified" # 宛先チェーン側で検証が完了した状態
EXECUTED = "executed" # 宛先チェーン側でミントや実行が完了した状態
FAILED = "failed" # 途中で失敗した状態
@dataclass
class BridgeTransfer:
"""
1件のブリッジ処理を表す簡単なデータです。
transfer_id:
ブリッジ処理を一意に識別するIDです。
user:
ブリッジを依頼したユーザーです。
amount:
ブリッジしたい数量です。
status:
現在の処理状態です。
"""
transfer_id: str
user: str
amount: int
status: TransferStatus = TransferStatus.REQUESTED
class SimpleBridgeStateMachine:
"""
ブリッジ処理の状態遷移を表す簡単なクラスです。
"""
def lock_on_source(self, transfer):
"""
送信元チェーンで資産をロックする処理です。
"""
if transfer.status != TransferStatus.REQUESTED:
raise ValueError("REQUESTED状態のときだけロックできます")
# 実際には、ここで残高確認やトークン転送が行われます。
transfer.status = TransferStatus.LOCKED
def send_message(self, transfer):
"""
ロックされたことを示すメッセージを送る処理です。
"""
if transfer.status != TransferStatus.LOCKED:
raise ValueError("LOCKED状態のときだけメッセージを送れます")
# 実際には、リレイヤーや証明生成の処理が関係します。
transfer.status = TransferStatus.MESSAGE_SENT
def verify_on_destination(self, transfer, proof_is_valid):
"""
宛先チェーン側でメッセージや証明を検証する処理です。
"""
if transfer.status != TransferStatus.MESSAGE_SENT:
raise ValueError("MESSAGE_SENT状態のときだけ検証できます")
# 実際には、署名検証、Merkle proof検証、ライトクライアント検証などが行われます。
if not proof_is_valid:
transfer.status = TransferStatus.FAILED
return
transfer.status = TransferStatus.VERIFIED
def execute_on_destination(self, transfer):
"""
検証後、宛先チェーン側でミントやコントラクト実行を行う処理です。
"""
if transfer.status != TransferStatus.VERIFIED:
raise ValueError("VERIFIED状態のときだけ実行できます")
# 実際には、ミント、アンロック、宛先コントラクト呼び出しなどが行われます。
transfer.status = TransferStatus.EXECUTED
# 学習用の動作例です。
transfer = BridgeTransfer(
transfer_id="transfer-001",
user="alice",
amount=100,
)
machine = SimpleBridgeStateMachine()
print("初期状態:", transfer.status.value)
machine.lock_on_source(transfer)
print("ロック後:", transfer.status.value)
machine.send_message(transfer)
print("メッセージ送信後:", transfer.status.value)
machine.verify_on_destination(transfer, proof_is_valid=True)
print("検証後:", transfer.status.value)
machine.execute_on_destination(transfer)
print("実行後:", transfer.status.value)
実行結果のイメージは次の通りです。
初期状態: requested
ロック後: locked
メッセージ送信後: message_sent
検証後: verified
実行後: executed
このモデルで見てほしいのは、ブリッジ処理が次のような段階を踏むことです。
| 状態 | 意味 | 失敗し得ること |
|---|---|---|
| requested | ユーザーが依頼した | 宛先や数量の指定ミス |
| locked | 送信元でロックされた | ロック処理の失敗、残高不足 |
| message_sent | メッセージが送られた | リレイヤー停止、遅延 |
| verified | 宛先側で検証された | 署名不正、証明不正、finality不足 |
| executed | 宛先側で実行された | ガス不足、宛先コントラクトの失敗 |
| failed | 途中で失敗した | 返金、再実行、手動対応が必要になる場合がある |
実際のブリッジでは、この状態管理がもっと複雑になります。
ただし、学習段階では、ブリッジ処理は一つの操作ではなく、複数の段階からなる と理解することが大切です。
4.7 途中で失敗したらどうなるのか
ブリッジで忘れてはいけないのが、途中で失敗する可能性です。
ユーザー画面では「送信中」と表示されていても、裏側では次のような失敗が起こる場合があります。
| 失敗する場所 | 例 | 起こり得る影響 |
|---|---|---|
| 送信元チェーン | 残高不足、Approve不足、ガス不足 | ブリッジ開始前に失敗する |
| ロック・バーン処理 | コントラクトエラー、対応トークン外 | 資産がロックされない、または処理が止まる |
| メッセージ伝達 | リレイヤー停止、ネットワーク遅延 | 宛先チェーンへの反映が遅れる |
| 検証 | 署名不正、証明不正、finality不足 | 宛先側で拒否される |
| 宛先実行 | ガス不足、宛先コントラクトの条件不一致 | ミントや実行が完了しない |
| UI・ユーザー操作 | 宛先アドレス間違い、チェーン選択ミス | 意図しない宛先へ送ってしまう |
ここで難しいのは、送信元チェーンでは処理済みなのに、宛先チェーンではまだ完了していない、という状態があり得ることです。
実際にどのような対応になるかは、ブリッジの設計によって変わります。
- 自動で再試行される場合
- ユーザーが手動でclaimする場合
- 一定期間待つ必要がある場合
- 返金やキャンセルが必要になる場合
- サポートやガバナンス対応が必要になる場合
そのため、ブリッジを利用するときは、待ち時間や失敗時の扱いを確認することが大切です。
4.8 処理の流れを見ると、リスクの場所も見えやすい
ここまで、ブリッジの処理を順番に見てきました。
処理の流れを分けて見ると、どこにリスクがあるのかも見えやすくなります。
| 処理段階 | 主なリスク |
|---|---|
| ユーザー操作 | 偽サイト、誤チェーン、誤アドレス、無制限Approve |
| 送信元ロック・バーン | スマートコントラクトのバグ、対応トークンの問題 |
| イベント発行 | イベントの取り違え、finality不足 |
| メッセージ伝達 | リレイヤー停止、遅延、メッセージ欠落 |
| 検証 | 署名検証不備、証明検証不備、鍵侵害 |
| 宛先実行 | 二重実行、リプレイ、ガス不足、実行失敗 |
| 失敗時対応 | 返金不能、再実行不能、状態不整合 |
ブリッジのリスクは、どこか一箇所だけで決まるわけではありません。
ユーザー操作、スマートコントラクト、検証者、リレイヤー、流動性、運用権限などが組み合わさってリスクになります。
この章で処理の流れを見た理由は、後のリスク整理につなげるためです。
「どこで何が起きるのか」が分かると、「どこで何が壊れると危険なのか」も見やすくなります。
💡 豆知識
ブリッジのトラブルを考えるときは、「送ったのに届かない」という見え方だけでなく、どの段階で止まっているのかを分けて見ると整理しやすくなります。
送信元で失敗しているのか、メッセージ伝達で止まっているのか、宛先側の実行で失敗しているのかで、対応方法が変わります。
4.9 この章のまとめ
この章では、ブリッジの基本的な処理の流れを整理しました。
ブリッジは、ユーザーがボタンを押したら一瞬で終わる単純な処理ではありません。
送信元チェーンでのロックやバーン、イベントの発行、メッセージの伝達、宛先チェーンでの検証、ミントや実行、失敗時対応など、複数の段階から成り立っています。
この章で押さえたいポイントは、次の通りです。
- ブリッジ処理には、ユーザー、送信元チェーン、宛先チェーン、ブリッジコントラクト、リレイヤー、検証者などが関係する
- Lock and Mintでは、送信元で資産をロックし、宛先で対応するトークンをミントする
- Burn and Mintでは、送信元で資産をバーンし、宛先で同量をミントする
- L2ブリッジでは、方向によって待ち時間や確認方法が異なる場合がある
- メッセージング型では、別チェーンのスマートコントラクト実行も関係する
- ブリッジ処理は、requested、locked、message_sent、verified、executedのような段階として考えると理解しやすい
- 途中で失敗した場合、再送、claim、返金、追加確認などが必要になる場合がある
- 処理の流れを分けて見ると、リスクの場所も見えやすくなる
次の章では、ブリッジの中心にある 「送信元チェーンの出来事をどう検証するのか」 をさらに詳しく見ていきます。
ライトクライアント型、外部バリデータ・ガーディアン型、発行体アテステーション型、Optimistic型、流動性ネットワーク型を比較しながら、ブリッジの信頼モデルを整理します。
5. 送信元チェーンの出来事をどう検証するのか
この章では、ブリッジの中心になる 検証モデル を整理します。
ポイントは、宛先チェーンが送信元チェーンの出来事を自動で知れるわけではないため、何らかの方法で「本当に起きた出来事なのか」を確認する必要がある、ということです。
前の章では、ブリッジの基本的な処理の流れを見ました。
送信元チェーンで資産をロックする。
その出来事をメッセージや証明として宛先チェーンへ伝える。
宛先チェーンで内容を検証し、問題がなければミントや実行を行う。
この流れの中で、特に重要なのが 検証 です。
なぜなら、宛先チェーンは送信元チェーンの状態をそのまま自動で読めるわけではないからです。
たとえば、Chain Aで「100 TESTがロックされた」という出来事があったとします。
Chain B側で100 wrapped TESTをミントするには、Chain B側が次のようなことを確認する必要があります。
- Chain Aで本当に100 TESTがロックされたのか
- その出来事は十分に確定しているのか
- メッセージは改ざんされていないか
- そのメッセージはすでに使われていないか
- 署名や証明は正しいか
- 誰の確認を信じてよいのか
この章では、この「誰が、何を、どう確認するのか」を整理します。
5.1 宛先チェーンは、送信元チェーンをそのまま読めない
まず、基本に戻ります。
ブロックチェーンは、それぞれ独立した台帳です。
Chain Aの状態はChain Aの中で管理され、Chain Bの状態はChain Bの中で管理されています。
そのため、Chain Bのスマートコントラクトが、Chain Aの最新状態を何の準備もなく直接読むことはできません。
身近な例でいうと、A銀行の内部台帳を、B銀行のシステムが勝手に直接読むことはできない、という感覚に近いです。
B銀行側で入金を反映するには、A銀行側で送金処理が行われたことを、何らかの決済ネットワークや確認手段を通して知る必要があります。
ブリッジでも同じです。
ここで問題になるのは、真ん中の メッセージ・証明・署名 の部分です。
誰かが「Chain Aで100 TESTがロックされました」と言っただけで、Chain Bがそのまま100 wrapped TESTをミントしてしまうと危険です。
その発言が本当かどうか、改ざんされていないか、すでに使われたものではないかを確認する必要があります。
この確認方法の違いが、ブリッジの信頼モデルの違いになります。
5.2 検証モデルを見るときの基本軸
検証モデルを比較するときは、まず次の問いを置くと整理しやすくなります。
| 問い | 見る理由 |
|---|---|
| 誰が送信元チェーンの出来事を確認するのか | 検証者、発行体、スマートコントラクト、Watcherなど、信頼対象が変わるため |
| 何を根拠に正しいと判断するのか | 署名、Merkle proof、ライトクライアント、アテステーションなど方式が違うため |
| 宛先チェーン上でどこまで検証するのか | オンチェーン検証が多いほどコストが増える場合があるため |
| 不正なメッセージをどう防ぐのか | 二重実行、リプレイ、不正ミントを防ぐ必要があるため |
| 検証者や運営主体が停止・侵害されたらどうなるのか | 可用性や資産安全性に影響するため |
| 取引の確定をどう扱うのか | finality不足により状態が食い違う可能性があるため |
ここで大切なのは、検証モデルに絶対的な正解があるわけではない という点です。
ある方式は信頼を小さくしやすい一方で、実装や検証コストが重くなるかもしれません。
別の方式はユーザー体験が速く見える一方で、外部検証者や発行体への信頼が増えるかもしれません。
つまり、見るべきなのは「この方式は安全か危険か」という単純な二択ではありません。
次のように考える方が、ブリッジの理解に近づきます。
このブリッジは、
何を証明しているのか
誰が証明しているのか
どこで検証しているのか
何が壊れると危険なのか
5.3 ライトクライアント型
まず、ライトクライアント型 を見てみます。
ライトクライアント型は、かなりざっくり言うと、宛先チェーン側で送信元チェーンの状態や合意を検証しようとする考え方です。
身近な例でいうと、誰かから「A銀行で送金済みです」と聞くだけでなく、自分でも公式記録に近いものを照合して確認するイメージです。
Cosmos IBCのドキュメントでは、light clientの ClientState や ConsensusState が、クライアント更新、misbehaviour検出、相手チェーン状態のproof verificationに使われることが説明されています。
参考: Cosmos IBC Docs: Light Client Overview
また、IBCでは、信頼されたrootに対してMerkle proofを使い、リモートのcounterparty state machineの状態を検証する考え方も説明されています。
ライトクライアント型の特徴を整理すると、次のようになります。
| 観点 | 内容 |
|---|---|
| 誰を信頼するか | 主に送信元チェーンの合意と、ライトクライアント実装 |
| 何を検証するか | ブロックヘッダ、状態証明、Merkle proofなど |
| 強み | 外部の少数検証者への信頼を減らしやすい |
| 注意点 | 実装が複雑になりやすく、オンチェーン検証コストも問題になり得る |
| 向いている場面 | チェーン間で検証仕様が整っている場合、IBCのようなプロトコル型の連携 |
ライトクライアント型は、信頼を最小化しやすい方向の設計として扱われることがあります。
ただし、だからといって自動的に「完全に安全」という意味ではありません。
実装バグ、対応するチェーン仕様の変更、検証コスト、クライアント更新、停止時対応などは引き続き重要です。
5.4 外部バリデータ・ガーディアン型
次に、外部バリデータ・ガーディアン型 を見てみます。
この方式では、送信元チェーンで起きた出来事を、外部の検証者セットが観測し、正しいと判断したメッセージに署名します。
宛先チェーン側では、その署名を検証して、問題がなければ処理を実行します。
Wormholeの公式ドキュメントでは、Guardian nodesがメッセージを検証・署名し、13 out of 19のようなsupermajorityが同じメッセージに署名すると有効と見なせることが説明されています。
また、ターゲットチェーン上のスマートコントラクトが、その署名とメッセージ形式を検証してから処理を承認する流れも説明されています。
参考: Wormhole Docs: Security
参考: Wormhole Docs: Guardians
参考: Wormhole Docs: VAAs
この方式では、検証者セットやガーディアンの設計がとても重要です。
| 観点 | 内容 |
|---|---|
| 誰を信頼するか | 外部バリデータ、ガーディアン、署名者セット |
| 何を検証するか | 送信元チェーンで発生したイベントやメッセージ |
| 強み | 複数チェーンに対応しやすく、汎用メッセージングにも向きやすい |
| 注意点 | 署名鍵管理、閾値設計、検証者の分散性、停止や共謀リスク |
| 向いている場面 | 多数チェーン間のメッセージング、汎用的なクロスチェーン連携 |
身近な例でいうと、複数人の承認印が必要な申請書に近いです。
1人の署名だけでは実行できない。
一定数以上の承認が集まったら、有効な申請として扱う。
ただし、その承認者の鍵や運用が侵害されると危険になります。
💡 豆知識
「13 out of 19」のような表現は、19人中13人以上の署名が必要、という意味です。
これは、単独の署名者に依存しないための設計ですが、署名者セットの分散性や鍵管理が重要である点は変わりません。
5.5 発行体アテステーション型
次に、発行体アテステーション型 を見てみます。
アテステーションは、ざっくり言えば「ある出来事が確かに起きたことを証明・確認するもの」です。
発行体アテステーション型では、トークンの発行体などが、送信元チェーンで起きたバーンなどの出来事を確認し、宛先チェーンでミントできるようにします。
代表例として、Circle CCTPがあります。
CircleのCCTP公式資料では、CCTPは送信元チェーンでUSDCをバーンし、宛先チェーンでUSDCをミントすることで、従来型のブリッジ流動性プールやラップドトークンなしに1:1転送を可能にする仕組みとして説明されています。
参考: Circle Developers: Cross-Chain Transfer Protocol
また、CircleのCCTP紹介ページでは、Circleが送信元チェーンのburn eventを観測してattestし、そのattestationを使って宛先チェーンでUSDCをミントする流れが説明されています。
参考: Circle: Cross-Chain Transfer Protocol
流れを単純化すると、次のようになります。
この方式では、発行体が大きな役割を持ちます。
| 観点 | 内容 |
|---|---|
| 誰を信頼するか | 発行体、アテステーションサービス、ミント権限の管理 |
| 何を検証するか | 送信元チェーンでのバーンイベントなど |
| 強み | ネイティブ資産の形で扱いやすく、ラップドトークンや流動性プールに依存しない設計が可能 |
| 注意点 | 発行体への依存、アテステーション停止、対応チェーン、権限管理 |
| 向いている場面 | 発行体が複数チェーンで同じ資産を管理する場合 |
ここで重要なのは、発行体アテステーション型は「何も信頼しない」方式ではないという点です。
発行体が正しくburn eventを観測し、正しくattestationを発行し、宛先チェーンで適切にミント権限を管理することが前提になります。
その一方で、ラップド資産ではなく、発行体が管理するネイティブ資産として扱える場合がある点は、大きな特徴です。
5.6 Optimistic型
次に、Optimistic型 を見てみます。
Optimistic型は、ざっくり言えば「いったん正しいものとして扱い、不正があれば一定期間内に異議を出す」考え方です。
身近なたとえでいうと、提出された申請をいったん受け付けるが、一定期間は監査や異議申し立てを受け付ける、というイメージです。
Optimistic型では、Watcherやチャレンジ期間が重要になります。
| 観点 | 内容 |
|---|---|
| 誰を信頼するか | 不正を見つけてチャレンジするWatcher、チャレンジ期間、検証ルール |
| 何を検証するか | 提出されたメッセージや状態遷移に不正がないか |
| 強み | すべてを即時に重く検証しない設計が可能 |
| 注意点 | Watcherが機能しない場合、不正を見逃す可能性がある |
| 向いている場面 | チャレンジ期間を許容できる設計、監視と異議申し立てが機能する環境 |
Optimistic型は、L2の文脈でもよく出てくる考え方です。
たとえばOptimistic Rollupでは、不正があればチャレンジできる期間を置く設計が使われます。
ただし、ブリッジにおけるOptimistic型の具体的な設計はプロトコルによって異なります。
そのため、本記事では「いったん正しいものとして扱い、一定期間内の監視や異議申し立てで安全性を支える考え方」として押さえておきます。
5.7 流動性ネットワーク型
最後に、流動性ネットワーク型 を見ておきます。
流動性ネットワーク型では、ユーザーのリクエストに対して、LPやフィラーが宛先チェーン側で先に支払う場合があります。
その後、裏側で送信元チェーン側の資産や精算処理と対応させます。
第3章でも触れたように、これは両替所や立替払いに近いイメージです。
流動性ネットワーク型では、メッセージの正しさだけでなく、流動性や精算の仕組みも重要になります。
| 観点 | 内容 |
|---|---|
| 誰を信頼するか | LP、フィラー、精算ルール、流動性管理 |
| 何を検証するか | 送信依頼、支払い、精算条件 |
| 強み | ユーザーから見ると速く受け取れる場合がある |
| 注意点 | 流動性不足、手数料、価格差、精算失敗 |
| 向いている場面 | ユーザー体験や速度を重視する送金・交換 |
流動性ネットワーク型では、必ずしも宛先チェーンで新しくトークンをミントするとは限りません。
すでに宛先チェーン側にある資産を使って支払う場合があります。
そのため、「ミントされるかどうか」だけでなく、誰が流動性を提供しているのか、あとでどう精算されるのか を見る必要があります。
5.8 検証モデルを表で整理する
ここまで見てきた検証モデルを、表で整理します。
| モデル | 誰を主に信頼するか | 何を確認するか | 強み | 注意点 |
|---|---|---|---|---|
| ライトクライアント型 | 送信元チェーンの合意、ライトクライアント実装 | ブロックヘッダ、状態証明、Merkle proofなど | 外部検証者への信頼を小さくしやすい | 実装が複雑で、検証コストが高くなり得る |
| 外部バリデータ・ガーディアン型 | 検証者セット、署名者、鍵管理 | イベントやメッセージへの閾値署名 | 複数チェーン対応や汎用メッセージングに向きやすい | 鍵侵害、共謀、停止、閾値設計が重要 |
| 発行体アテステーション型 | 発行体、アテステーションサービス | burn eventなどの確認済みメッセージ | ネイティブ資産に近い形で扱える場合がある | 発行体依存、アテステーション停止、権限管理 |
| Optimistic型 | Watcher、チャレンジ期間、異議申し立てルール | 提出されたメッセージや状態遷移への不正検出 | 即時の重い検証を避けられる場合がある | 監視が機能しないと不正を見逃す可能性 |
| 流動性ネットワーク型 | LP、フィラー、精算ルール | 支払い・精算条件 | ユーザー体験が速い場合がある | 流動性不足、手数料、精算失敗 |
この表で見てほしいのは、どの方式にも強みと注意点があることです。
ライトクライアント型は信頼を最小化しやすい一方で、実装が難しくなりがちです。
外部バリデータ型は柔軟ですが、署名者セットや鍵管理が重要になります。
発行体アテステーション型はネイティブ資産を扱いやすい一方で、発行体への信頼が前提になります。
Optimistic型はWatcherやチャレンジ期間が機能することが重要です。
流動性ネットワーク型は速さやUXに強みがある一方で、流動性や精算が重要になります。
つまり、方式名だけを見て「これは安全」「これは危険」と決めるのではなく、どこに信頼仮定があるのか を見ることが大切です。
5.9 小さなコードで検証モデルの違いを見てみる
ここで、検証モデルの違いを、かなり単純化したPythonコードで見てみます。
このコードは学習用です。
実在するブリッジ、署名検証、Merkle proof検証、アテステーション検証を再現するものではありません。
目的は、検証モデルごとに「何を確認してOKとするか」が違う ことをイメージすることです。
# このコードは、検証モデルの違いを理解するための学習用コードです。
# 実在するブリッジ、署名検証、Merkle proof、アテステーションを再現するものではありません。
from dataclasses import dataclass
from enum import Enum
class VerificationModel(Enum):
"""
ブリッジの検証モデルを簡単に表します。
"""
LIGHT_CLIENT = "light_client"
GUARDIAN = "guardian"
ATTESTATION = "attestation"
OPTIMISTIC = "optimistic"
@dataclass
class CrossChainMessage:
"""
チェーンをまたいで処理したいメッセージを表します。
amount:
宛先チェーンで反映したい数量です。
source_event_id:
送信元チェーンで起きたイベントIDです。
nonce:
二重実行を防ぐための番号です。
"""
amount: int
source_event_id: str
nonce: int
def verify_message(model, message, evidence):
"""
検証モデルごとに、メッセージを受け入れるかどうかを判定します。
model:
検証モデルです。
message:
検証したいクロスチェーンメッセージです。
evidence:
検証に使う証拠を表す辞書です。
注意:
実際の検証はもっと複雑です。
ここでは「どのモデルで何を見るか」を理解するために単純化しています。
"""
if model == VerificationModel.LIGHT_CLIENT:
# ライトクライアント型では、状態証明やヘッダ検証を通じて、
# 送信元チェーンの出来事を検証するイメージです。
return evidence.get("merkle_proof_valid") and evidence.get("header_valid")
if model == VerificationModel.GUARDIAN:
# ガーディアン型では、十分な数の検証者署名があるかを見ます。
# ここでは13署名以上ならOKという単純な例にしています。
return evidence.get("guardian_signatures", 0) >= 13
if model == VerificationModel.ATTESTATION:
# 発行体アテステーション型では、発行体の確認済みメッセージかを見ます。
return evidence.get("issuer_attestation") == "valid"
if model == VerificationModel.OPTIMISTIC:
# Optimistic型では、チャレンジ期間が終わり、
# 不正申立てがなかったかを確認するイメージです。
return evidence.get("challenge_period_over") and not evidence.get("fraud_challenge")
raise ValueError("未知の検証モデルです")
message = CrossChainMessage(
amount=100,
source_event_id="event-001",
nonce=1,
)
guardian_evidence = {
"guardian_signatures": 13,
}
print(
verify_message(
VerificationModel.GUARDIAN,
message,
guardian_evidence,
)
)
このコードでは、検証モデルごとに見る証拠を変えています。
| モデル | コード上で見ているもの | 実際の考え方 |
|---|---|---|
LIGHT_CLIENT |
merkle_proof_valid、header_valid
|
状態証明やヘッダを検証する |
GUARDIAN |
guardian_signatures |
十分な数の検証者署名を確認する |
ATTESTATION |
issuer_attestation |
発行体のアテステーションを確認する |
OPTIMISTIC |
challenge_period_over、fraud_challenge
|
チャレンジ期間と不正申立てを確認する |
実行結果のイメージは次の通りです。
True
ここでは、ガーディアン署名が13件あるため、単純化した条件ではメッセージを受け入れています。
もちろん、実際のブリッジでは、このような簡単な条件だけで安全性が決まるわけではありません。
署名の真正性、署名者セット、メッセージ内容、nonce、宛先チェーン、トークン種類、finality、処理済みチェックなど、さらに多くの確認が必要です。
それでも、この小さなコードから、検証モデルごとに「何を信じてOKとするのか」が違うことは見えてきます。
5.10 「検証」と「信頼」は切り離せない
ここまで、いくつかの検証モデルを見てきました。
どの方式でも、最終的には何らかの形で「これを正しいと扱ってよい」と判断する必要があります。
その判断の根拠が、ライトクライアントなのか、ガーディアン署名なのか、発行体アテステーションなのか、Watcherによる監視なのか、流動性提供者との精算なのかが違います。
つまり、ブリッジでは 検証モデル と 信頼モデル は切り離せません。
| 検証の根拠 | 信頼しているもの |
|---|---|
| 状態証明・ライトクライアント | 送信元チェーンの合意、検証実装 |
| ガーディアン署名 | 署名者セット、鍵管理、閾値設計 |
| 発行体アテステーション | 発行体、アテステーションサービス、権限管理 |
| Optimisticな監視 | Watcher、チャレンジ期間、異議申し立て制度 |
| 流動性提供者の支払い | LP、フィラー、精算ルール、流動性 |
ブリッジを調べるときは、技術名だけで判断しないことが大切です。
たとえば、「ライトクライアント型だから安全」「ガーディアン型だから危険」「CCTPだから常に安全」「Optimisticだから遅いだけ」といった単純化は避けたいところです。
それぞれの方式には、設計上の意図とトレードオフがあります。
- 何をオンチェーンで検証するのか
- 何をオフチェーンの主体に任せるのか
- 失敗時にどう止めるのか
- どの権限が誰にあるのか
- どの程度の待ち時間を許容するのか
- どの程度のコストを許容するのか
こうした観点を分けて見ることで、ブリッジの仕組みとリスクが見えやすくなります。
💡 豆知識
ブリッジを見るときは、「このブリッジは何型か」だけでなく、「その型では何を信頼しているのか」を見るのがおすすめです。
方式名は入口にすぎません。
実際には、検証方法、鍵管理、権限、停止時対応、アップグレード方法まで含めて見る必要があります。
5.11 この章のまとめ
この章では、送信元チェーンの出来事を宛先チェーンがどう検証するのかを整理しました。
ブリッジでは、宛先チェーンが送信元チェーンの状態をそのまま自動で読めるわけではありません。
そのため、メッセージ、証明、署名、アテステーション、Watcher、流動性提供者などを通じて、送信元チェーンで起きた出来事を確認します。
この章で押さえたいポイントは、次の通りです。
- 宛先チェーンは、送信元チェーンの状態をそのまま自動で読めるわけではない
- ブリッジでは、送信元チェーンで本当に何が起きたのかを検証する必要がある
- ライトクライアント型は、状態証明や合意を検証する方向の設計である
- 外部バリデータ・ガーディアン型では、検証者セットや署名閾値、鍵管理が重要になる
- 発行体アテステーション型では、発行体やアテステーションサービスへの信頼が重要になる
- Optimistic型では、Watcherやチャレンジ期間が機能することが重要になる
- 流動性ネットワーク型では、LP、フィラー、流動性、精算ルールが重要になる
- 検証モデルを見ることは、信頼モデルを見ることでもある
- 方式名だけで安全性を判断せず、何を誰が検証しているのかを確認することが大切である
次の章では、ここで整理した検証モデルを踏まえて、代表的なブリッジや相互運用プロトコルを、方式と信頼モデルの違いとして見ていきます。
L2のカノニカルブリッジ、Wormhole、Circle CCTP、Cosmos IBC、Chainlink CCIP、LayerZeroなどを、名前の暗記ではなく、方式や信頼モデルの違いとして整理します。
6. 代表的なブリッジ・相互運用プロトコルの考え方
この章では、代表的なブリッジや相互運用プロトコルの考え方を整理します。
ポイントは、名前を暗記することではなく、それぞれがどのような方式・検証モデル・信頼仮定を持っているのか を見ることです。
前の章では、送信元チェーンの出来事を宛先チェーンがどう検証するのかを整理しました。
ライトクライアント型、外部バリデータ・ガーディアン型、発行体アテステーション型、Optimistic型、流動性ネットワーク型など、いくつかの考え方がありました。
ここからは、その考え方をもとに、代表的なブリッジや相互運用プロトコルを見ていきます。
ただし、この章の目的は「どのブリッジが一番よいか」を単純に決めることではありません。
また、特定のブリッジの利用をすすめるものでもありません。
本記事で大切にしたいのは、次の見方です。
このプロトコルは、
何をつないでいるのか
何を送れるのか
誰が出来事を検証しているのか
どこに信頼仮定があるのか
失敗したとき何が起こり得るのか
ブリッジや相互運用プロトコルは、同じ「クロスチェーン」という言葉でまとめられがちです。
しかし、実際には対象も方式もかなり違います。
- L1とL2をつなぐ標準ブリッジ
- 複数チェーン間でメッセージを伝えるプロトコル
- ネイティブUSDCをBurn and Mintする仕組み
- ライトクライアントを使ってチェーン間通信するプロトコル
- 外部検証者やガーディアンが署名する仕組み
- 流動性提供者が先に支払うネットワーク
この章では、代表的なものを並べながら、方式の違いを見ていきます。
6.1 L2のカノニカルブリッジ
まず、L2のカノニカルブリッジから見ていきます。
カノニカルブリッジは、ざっくり言えば、そのL2の設計に組み込まれた標準的なブリッジです。
EthereumとL2の間でETHやERC-20トークンを移動する場面でよく出てきます。
たとえば、OptimismのStandard Bridgeは、OP Mainnetや標準的なOP Stackチェーンで使える基本的なトークンブリッジシステムとして説明されています。
公式ドキュメントでは、EthereumからOP Mainnetへの転送は通常1〜3分程度、OP MainnetからEthereumへの転送はwithdrawal challenge periodにより7日かかると説明されています。
参考: Optimism Docs: Using the Standard Bridge
また、Arbitrumでは、L1からL2へのメッセージングに retryable ticket という仕組みが使われます。
公式ドキュメントでは、retryable ticketは親チェーンから子チェーンへのメッセージ作成の標準的な仕組みとして説明されています。
参考: Arbitrum Docs: Bridging from a parent chain to a child chain
L2ブリッジのポイントは、単に「別チェーンへ資産を送る」だけではなく、L1とL2の状態や証明の関係があることです。
L2ブリッジを見るときは、次のような点を確認すると整理しやすいです。
| 観点 | 見るポイント |
|---|---|
| 何をつないでいるか | L1とL2 |
| 何を送るか | ETH、ERC-20、メッセージなど |
| 送信元と宛先 | L1→L2、L2→L1で流れが異なる場合がある |
| 検証の考え方 | L2の状態、withdrawal proof、challenge periodなど |
| 使いやすさ | 入金は短時間でも、引き出しには時間がかかる場合がある |
| 注意点 | 方向による待ち時間、対応トークン、手数料、手動claim、失敗時対応 |
身近なたとえで言うと、L2は「メインの記録場所とは別に、処理を効率よく行う場所」と考えると入りやすいです。
ただし、そこからメイン側へ戻すときには、確認期間や証明が必要になる場合があります。
💡 豆知識
L2ブリッジでは、「入るとき」と「出るとき」で体験が違うことがあります。
画面上は同じBridge操作に見えても、EthereumからL2へ移る場合と、L2からEthereumへ戻る場合では、裏側の確認方法や待ち時間が変わることがあります。
6.2 Wormholeのようなガーディアン型
次に、Wormholeのようなガーディアン型の考え方を見てみます。
Wormholeは、複数のブロックチェーン間でメッセージを伝えるためのプロトコルです。
公式ドキュメントでは、Guardian NetworkがWormholeの分散型オラクルとして機能し、クロスチェーン相互運用性を支える重要な要素として説明されています。
Wormholeでは、VAAs(Verified Action Approvals)が中核的なメッセージングの基本要素として説明されています。
公式ドキュメントでは、Guardiansがコントラクトから発行されたメッセージを検証し、3分の2以上のsupermajorityが有効と認めるとメッセージ本文のハッシュに署名すると説明されています。
かなり単純化すると、流れは次のようになります。
Wormholeのようなガーディアン型では、メッセージをどう運ぶかだけでなく、ガーディアンの署名をどう検証するか が重要になります。
| 観点 | 見るポイント |
|---|---|
| 何をつないでいるか | 複数のL1、L2、アプリケーション |
| 何を送るか | メッセージ、トークン転送に関係するデータなど |
| 検証の考え方 | ガーディアンがメッセージを観測・署名し、宛先側で署名を検証する |
| 信頼仮定 | ガーディアンセット、署名閾値、鍵管理 |
| 強み | 複数チェーンをまたぐ汎用的なメッセージングに向きやすい |
| 注意点 | ガーディアン鍵、署名閾値、監視、実装更新、メッセージ再利用防止 |
ここで気をつけたいのは、「ガーディアン型 = 危険」と単純化しないことです。
大切なのは、誰がガーディアンなのか、署名閾値はどうなっているのか、鍵管理はどうなっているのか、宛先側でどのようにVAAを検証するのかを見ることです。
6.3 Circle CCTPのような発行体アテステーション型
次に、Circle CCTPのような発行体アテステーション型を見てみます。
CCTPは、USDCを複数チェーン間でネイティブに転送するための仕組みです。
Circleの開発者向け資料では、CCTPは送信元ブロックチェーンでUSDCをバーンし、宛先ブロックチェーンでUSDCをミントすることで、従来型のブリッジ流動性プールやラップドトークンなしに1:1の転送を可能にする仕組みとして説明されています。
参考: Circle Developers: Cross-Chain Transfer Protocol
また、CCTPの技術ガイドでは、オンチェーンコンポーネントとCircleのオフチェーンAttestation Serviceの関係が、USDCのburn-and-mintの流れとして説明されています。
参考: Circle Developers: CCTP Technical Guide
単純化すると、流れは次のようになります。
CCTPの特徴は、ラップドトークンではなく、発行体が管理するネイティブUSDCのBurn and Mintに近い形で扱う点です。
| 観点 | 見るポイント |
|---|---|
| 何をつないでいるか | CCTP対応チェーン間のUSDC |
| 何を送るか | ネイティブUSDC |
| 検証の考え方 | Circleがburn eventを確認し、attestationを発行する |
| 信頼仮定 | Circle、Attestation Service、ミント権限 |
| 強み | ラップドトークンやブリッジ流動性プールに依存しない設計が可能 |
| 注意点 | 発行体依存、対応チェーン、サービス停止、権限管理 |
ここでのポイントは、CCTPが「発行体アテステーション型」のイメージをつかむうえで分かりやすい例であることです。
ただし、これも「完全に信頼不要」という意味ではありません。
Circleが発行体としてどのようにburn eventを確認し、attestationを発行し、宛先チェーンでミントを許可するのかが重要になります。
6.4 Cosmos IBCのようなプロトコル型
次に、Cosmos IBCのようなプロトコル型を見てみます。
IBCは、Inter-Blockchain Communicationの略で、ブロックチェーン同士が通信するためのプロトコルです。
Cosmos Docsでは、IBCはブロックチェーン同士が会話するためのプロトコルであり、token transfers、atomic swaps、multi-chain smart contracts、cross-chain account controlなどを可能にすると説明されています。
参考: Cosmos Docs: IBC-Go Documentation
IBCの特徴は、チェーン同士が相手チェーンの状態を検証するためにlight clientを使う点です。
また、relayerはパケットを運びますが、正しさはproof verificationによって確認されます。
ここで大切なのは、relayerが「信頼される管理者」として正しさを保証するわけではない点です。
relayerはパケットや証明を運びます。
受け取ったチェーン側は、保存している相手チェーンの状態に基づき、proofを検証します。
| 観点 | 見るポイント |
|---|---|
| 何をつないでいるか | IBC対応チェーン |
| 何を送るか | パケット、トークン転送、アプリケーションデータなど |
| 検証の考え方 | light clientとproof verification |
| 信頼仮定 | 相手チェーンの合意、light client実装、relayerの可用性 |
| 強み | プロトコルとしてチェーン間通信の仕組みが整理されている |
| 注意点 | light client更新、対応チェーン、relayer運用、実装の複雑さ |
IBCは、ライトクライアント型の考え方を理解するうえで重要な例です。
一方で、すべてのチェーンがそのままIBCに対応しているわけではなく、接続するチェーンの仕様や実装も重要になります。
6.5 Chainlink CCIPのようなクロスチェーン相互運用プロトコル
次に、Chainlink CCIPを見てみます。
Chainlink CCIPの公式ドキュメントでは、CCIPは開発者がトークン、メッセージ、またはその両方をチェーン間で転送できるアプリケーションを構築するためのブロックチェーン相互運用プロトコルとして説明されています。
また、CCIPのアーキテクチャ資料では、Burn-and-Mint、Lock-and-Mint、Lock-and-Unlockなど複数のトークン転送方式を共通インターフェースでサポートすることが説明されています。
参考: Chainlink Docs: CCIP Architecture Overview
CCIPの特徴は、単なるトークン転送だけでなく、メッセージとトークンを組み合わせた programmable token transfer のような使い方にも対応している点です。
| 観点 | 見るポイント |
|---|---|
| 何をつないでいるか | CCIP対応チェーン |
| 何を送るか | トークン、メッセージ、トークン+データ |
| 検証の考え方 | ChainlinkのネットワークやCCIPのセキュリティ設計 |
| 信頼仮定 | Oracle network、CCIPの構成要素、rate limit、運用設計など |
| 強み | トークン転送とメッセージングを組み合わせやすい |
| 注意点 | 宛先コントラクトの実装、防御的設計、実行失敗時の扱い |
CCIPのようなプロトコルを見るときは、「何を送れるか」だけでなく、宛先側のコントラクトがどのように受け取り、どのように失敗時対応を行うのかも重要です。
公式チュートリアルでも、programmable token transfersの防御的な例として、受信時のエラーに備えてトークンをロックし、必要に応じて回復・リダイレクトできる設計が説明されています。
参考: Chainlink Docs: Transfer Tokens with Data - Defensive Example
6.6 LayerZeroのようなメッセージング型
LayerZeroも、クロスチェーンメッセージングの代表例としてよく挙げられます。
LayerZeroの公式ドキュメントでは、各対応ブロックチェーンにEndpoint contractがあり、アプリケーションがEndpointを通じてメッセージを送受信する仕組みが説明されています。
また、LayerZero V2では、DVN(Decentralized Verifier Network)の検証閾値が満たされると、Message Packetがverified and committedになることが説明されています。
参考: LayerZero Docs: Protocol Overview
単純化すると、流れは次のようになります。
LayerZeroを見るときは、次のような観点が重要になります。
| 観点 | 見るポイント |
|---|---|
| 何をつないでいるか | LayerZero対応チェーン |
| 何を送るか | クロスチェーンメッセージ、アプリケーションデータなど |
| 検証の考え方 | DVNによる検証、Endpoint、Message Library |
| 信頼仮定 | アプリごとのSecurity Stack、DVN構成、Executor、設定 |
| 強み | アプリケーションがクロスチェーンメッセージングを構成しやすい |
| 注意点 | 設定、DVN選択、宛先実行、メッセージ順序、失敗時対応 |
LayerZeroのようなメッセージング型では、アプリケーションごとの設定も重要になります。
同じプロトコルを使っていても、どのDVNを使うのか、何個の検証を要求するのか、Executorをどう使うのかによって信頼モデルが変わる場合があります。
そのため、「LayerZeroを使っているから安全」「この方式だから危険」とは言えません。
具体的なアプリケーションの設定や運用まで見る必要があります。
6.7 代表例を表で比較する
ここまで見てきた代表例を、表で整理します。
| 代表例 | 大まかな分類 | 主に扱うもの | 検証・信頼モデルの見どころ | 注意したい点 |
|---|---|---|---|---|
| Optimism Standard Bridge | L2カノニカルブリッジ | ETH、ERC-20、L1/L2メッセージ | L2の状態、withdrawal proof、challenge period | 方向による待ち時間、対応トークン、引き出し時の確認 |
| Arbitrum retryable ticket | L1→L2メッセージング | L1からL2へのメッセージ | retryable ticket、再実行、L2側の実行 | ガス、実行失敗、手動redeem |
| Wormhole | ガーディアン型メッセージング | メッセージ、トークン転送関連データ | Guardian署名、VAA、署名閾値 | ガーディアン鍵、署名検証、実装更新 |
| Circle CCTP | 発行体アテステーション型 | ネイティブUSDC | CircleのAttestation Service、burn-and-mint | 発行体依存、対応チェーン、アテステーション停止 |
| Cosmos IBC | プロトコル型 / ライトクライアント型 | パケット、トークン、アプリデータ | light client、proof verification、relayer | light client更新、relayer可用性、対応チェーン |
| Chainlink CCIP | クロスチェーン相互運用プロトコル | トークン、メッセージ、トークン+データ | CCIPのセキュリティ設計、Oracle network、rate limitなど | 宛先コントラクト実装、失敗時対応 |
| LayerZero | メッセージング型 | クロスチェーンメッセージ | Endpoint、DVN、Security Stack | DVN設定、Executor、アプリごとの構成 |
この表は、プロトコルを優劣で並べるためのものではありません。
それぞれの方式がどのような信頼モデルを持つのかを整理するためのものです。
同じ「ブリッジ」や「クロスチェーン」と呼ばれていても、実際にはかなり違うことが分かります。
6.8 方式名だけで安全性を決めない
ここまで代表的なプロトコルを見てきましたが、最後に強調したいことがあります。
それは、方式名だけで安全性を決めない ということです。
たとえば、次のように考えてしまうと危険です。
| 短絡的な見方 | なぜ注意が必要か |
|---|---|
| カノニカルブリッジなら必ず安全 | 設計、待ち時間、アップグレード権限、対応資産を見る必要がある |
| ガーディアン型だから危険 | ガーディアン構成、署名閾値、鍵管理、監視体制によって変わる |
| ライトクライアント型なら完全に安全 | 実装バグ、検証コスト、クライアント更新の問題が残る |
| 発行体アテステーション型なら安心 | 発行体やAttestation Serviceへの依存がある |
| メッセージング型なら何でもできる | 宛先コントラクトの実装や失敗時対応が重要 |
| 速いブリッジほど優れている | 速度と信頼モデル、finality、流動性、手数料はトレードオフになり得る |
ブリッジを見るときは、次のような観点を組み合わせて確認することが大切です。
ここで出てくる「信頼仮定」は、少し固い言葉です。
簡単に言えば、その仕組みが正しく動くために、何を信じる必要があるのか です。
- 特定の発行体を信じるのか
- 検証者セットを信じるのか
- ライトクライアント実装を信じるのか
- Watcherが機能することを信じるのか
- LPやフィラーが精算することを信じるのか
- 管理者権限が適切に運用されることを信じるのか
こうした問いを立てることで、ブリッジをより正確に理解できます。
💡 豆知識
ブリッジや相互運用プロトコルを調べると、公式資料には「secure」「trust-minimized」「decentralized」「native」「permissionless」などの言葉が出てくることがあります。
これらは重要なキーワードですが、単語だけで判断せず、「具体的に何をどう検証しているのか」「どの権限が誰にあるのか」まで見ることが大切です。
6.9 小さなコードでプロトコルを観点別に分類してみる
ここで、代表的なプロトコルを「方式」「扱うもの」「主な信頼対象」で整理するための小さなPythonコードを見てみます。
このコードは、実在プロトコルの安全性を判定するものではありません。
あくまで、記事で整理した観点を表として扱いやすくするための学習用コードです。
# このコードは、代表的なブリッジ・相互運用プロトコルを
# 観点別に整理するための学習用コードです。
# 実在プロトコルの安全性評価や利用推奨を行うものではありません。
from dataclasses import dataclass
from typing import List
@dataclass
class InteropProtocol:
"""
ブリッジや相互運用プロトコルを、学習用に整理するためのデータクラスです。
name:
プロトコル名や代表例です。
category:
大まかな分類です。
transfers:
主に扱うものです。例: token, message, token+message
trust_points:
注意して見るべき信頼対象です。
notes:
補足説明です。
"""
name: str
category: str
transfers: List[str]
trust_points: List[str]
notes: str
protocols = [
InteropProtocol(
name="Optimism Standard Bridge",
category="L2 canonical bridge",
transfers=["token", "message"],
trust_points=["L2 state", "withdrawal proof", "challenge period"],
notes="L1とL2の方向によって待ち時間や確認方法が異なる場合がある。",
),
InteropProtocol(
name="Wormhole",
category="guardian-based messaging",
transfers=["message", "token-related data"],
trust_points=["guardian set", "signature threshold", "key management"],
notes="VAAやGuardian署名の検証が重要になる。",
),
InteropProtocol(
name="Circle CCTP",
category="issuer attestation",
transfers=["native USDC"],
trust_points=["issuer", "attestation service", "mint authority"],
notes="送信元でUSDCをバーンし、宛先でUSDCをミントする。",
),
InteropProtocol(
name="Cosmos IBC",
category="light-client-based protocol",
transfers=["packet", "token", "app data"],
trust_points=["light client", "proof verification", "relayer availability"],
notes="relayerは運ぶ役割で、正しさはproof verificationで確認する。",
),
InteropProtocol(
name="Chainlink CCIP",
category="cross-chain interoperability protocol",
transfers=["token", "message", "token+data"],
trust_points=["oracle network", "rate limits", "receiver contract design"],
notes="トークン転送とメッセージングを組み合わせられる。",
),
InteropProtocol(
name="LayerZero",
category="cross-chain messaging",
transfers=["message"],
trust_points=["DVN configuration", "Endpoint", "Executor"],
notes="アプリケーションごとのSecurity Stack設定が重要になる。",
),
]
def print_protocol_summary(protocols):
"""
プロトコル一覧を、確認しやすい形で表示します。
"""
for protocol in protocols:
print(f"Name: {protocol.name}")
print(f" Category: {protocol.category}")
print(f" Transfers: {', '.join(protocol.transfers)}")
print(f" Trust points: {', '.join(protocol.trust_points)}")
print(f" Notes: {protocol.notes}")
print()
print_protocol_summary(protocols)
このコードで見てほしいのは、プロトコルを次の観点で整理している点です。
- 大まかな分類
- 何を送れるか
- 主な信頼対象
- 注意点
実行結果の一部は、次のようなイメージになります。
Name: Wormhole
Category: guardian-based messaging
Transfers: message, token-related data
Trust points: guardian set, signature threshold, key management
Notes: VAAやGuardian署名の検証が重要になる.
このように整理すると、プロトコル名だけに引っ張られず、確認すべき観点を見やすくなります。
もちろん、実際にプロトコルを評価するには、この程度の分類だけでは不十分です。
公式ドキュメント、コントラクト、監査レポート、ガバナンス、運用状況、過去のインシデント、対応チェーン、TVLや流動性など、さらに多くの情報を確認する必要があります。
それでも、最初の整理としては、何を送れるのか、誰を信頼しているのか、失敗時に何が起こるのか を分けるだけでも、理解しやすくなります。
6.10 この章のまとめ
この章では、代表的なブリッジや相互運用プロトコルの考え方を整理しました。
同じ「ブリッジ」「クロスチェーン」「相互運用」と呼ばれていても、実際にはかなり違う設計があります。
L2カノニカルブリッジ、ガーディアン型、発行体アテステーション型、ライトクライアント型、クロスチェーンメッセージング型など、それぞれ見るべきポイントが違います。
この章で押さえたいポイントは、次の通りです。
- L2のカノニカルブリッジでは、L1とL2の状態やwithdrawal proof、challenge periodが重要になる
- Wormholeのようなガーディアン型では、Guardian署名、VAA、署名閾値、鍵管理が重要になる
- Circle CCTPのような発行体アテステーション型では、発行体、Attestation Service、ミント権限が重要になる
- Cosmos IBCのようなプロトコル型では、light client、proof verification、relayerの役割分担が重要になる
- Chainlink CCIPやLayerZeroのようなメッセージング型では、トークンだけでなくメッセージや宛先コントラクト実行も重要になる
- 方式名だけで安全性を判断せず、何を送れるのか、誰が検証するのか、どこに信頼仮定があるのかを見る必要がある
- 公式資料の言葉だけでなく、具体的な検証方法、権限、失敗時対応、運用体制を見ることが大切である
次の章では、ここまで整理した仕組みと信頼モデルをもとに、情報セキュリティの観点でブリッジのリスクを見ていきます。
スマートコントラクトリスク、署名者・検証者リスク、流動性・会計リスク、finality・リプレイ・順序リスク、アップグレード・UXリスクを分けて整理します。
7. 情報セキュリティの観点で見るリスク
この章では、ブリッジに特有のリスクを情報セキュリティの観点から整理します。
ポイントは、ブリッジが便利な一方で、チェーン本体とは別に スマートコントラクト、署名者、検証者、流動性、アップグレード権限、ユーザー操作 などの信頼点を追加することです。
前の章では、代表的なブリッジや相互運用プロトコルを見てきました。
L2のカノニカルブリッジ、Wormholeのようなガーディアン型、Circle CCTPのような発行体アテステーション型、Cosmos IBCのようなライトクライアント型、Chainlink CCIPやLayerZeroのようなメッセージング型など、同じ「クロスチェーン」と呼ばれていても、仕組みや信頼モデルはかなり違いました。
ここからは、情報セキュリティの観点でリスクを整理します。
ただし、この章で扱うのは攻撃手順ではありません。
「どのように攻撃するか」ではなく、どの部品が壊れると、どのような影響が出るのか を理解することが目的です。
Ethereum.orgの開発者向け資料では、ブリッジ利用にはスマートコントラクトリスク、システム的な金融リスク、trusted bridgeにおけるカウンターパーティリスクなどがあると説明されています。
また、Ethereum.orgのブリッジ紹介ページでも、スマートコントラクトリスク、技術リスク、trusted bridgeにおける検閲リスクやカストディリスクが説明されています。
参考: Ethereum.org: Introduction to blockchain bridges
本記事では、これらの観点を踏まえながら、初学者向けに次のように分類して見ていきます。
| リスク分類 | ざっくりした内容 |
|---|---|
| スマートコントラクトリスク | ロック、ミント、バーン、検証処理にバグがある |
| 署名者・検証者リスク | 検証者やガーディアンの秘密鍵、閾値、運用に問題がある |
| 流動性・会計リスク | ロック量と発行量、流動性、decimals、手数料などのつじつまが崩れる |
| finality・リプレイ・順序リスク | 巻き戻り、同じメッセージの再利用、順序不整合が起きる |
| アップグレード・ガバナンスリスク | 管理者権限、アップグレード、緊急停止の扱いに問題がある |
| ユーザーUXリスク | 偽サイト、誤チェーン、無制限Approve、ガス不足などが起きる |
| 複合リスク | 複数の小さな問題が組み合わさって大きな影響になる |
7.1 まずはリスクの地図を作る
ブリッジのリスクを考えるとき、いきなり個別の攻撃事例から入ると少し難しくなります。
まずは、処理の流れに沿って「どこにリスクがあるのか」を地図のように見てみます。
この図を見ると、ブリッジのリスクは一箇所だけにあるわけではないことが分かります。
スマートコントラクトだけを監査しても、署名者の鍵管理が弱ければ危険です。
検証者セットが強くても、ユーザーが偽サイトで無制限Approveをしてしまうと危険です。
ロックとミントの処理が正しくても、失敗時の復旧手段が分かりにくいとユーザー体験や運用上の問題になります。
つまり、ブリッジのリスクは 技術・運用・経済・UX が重なったものとして見る必要があります。
L2BEATの L2Bridge Risk Framework でも、ブリッジを評価する際の追加観点として、upgradability、permissioned actors、流動性、対応トークン・チェーンなどが挙げられています。
参考: L2BEAT Forum: L2Bridge Risk Framework
7.2 スマートコントラクトリスク
まず、スマートコントラクトリスクです。
ブリッジでは、送信元チェーンや宛先チェーンにスマートコントラクトが配置されることがあります。
このコントラクトが、資産のロック、バーン、ミント、アンロック、メッセージ検証、権限確認などを担当します。
スマートコントラクトにバグがあると、資産の不整合や不正な実行につながる可能性があります。
| リスク | 例 | 起こり得る影響 |
|---|---|---|
| ロック処理の不備 | 本来ロックすべき資産が正しくロックされない | 裏付けのないミントにつながる可能性 |
| ミント処理の不備 | 不正な条件でもミントできる | ラップド資産が過剰発行される可能性 |
| バーン処理の不備 | バーンされていないのにバーン済みとして扱う | 二重利用や不整合につながる可能性 |
| 署名検証の不備 | 不正な署名を受け入れる | 不正メッセージが実行される可能性 |
| nonce管理の不備 | 同じメッセージを複数回処理できる | 二重ミントや二重実行につながる可能性 |
| 権限チェックの不備 | 本来許可されていない人が管理操作できる | コントラクト設定や資産に影響する可能性 |
スマートコントラクトリスクで大切なのは、コードが公開されているかどうかだけではありません。
公開されていても、複雑な依存関係、アップグレード可能性、外部コントラクト呼び出し、設定値、権限設計によってリスクは変わります。
監査済みであることは重要です。
しかし、監査済みであっても、すべてのリスクがなくなるわけではありません。
- 監査後にコードが変更されているかもしれない
- 設定値が変更されているかもしれない
- 対応チェーンや対応トークンが増えているかもしれない
- 外部依存先が変わっているかもしれない
- 管理者権限やアップグレード権限が残っているかもしれない
そのため、ブリッジを見るときは、「監査済みか」だけでなく、何が監査され、いつ監査され、その後何が変わったのか も見る必要があります。
7.3 署名者・検証者・ガーディアンリスク
次に、署名者・検証者・ガーディアンに関するリスクです。
外部バリデータ型やガーディアン型では、送信元チェーンで起きた出来事を検証者セットが確認し、署名します。
宛先チェーン側では、その署名が十分に集まっているか、正しい署名者によるものかを確認して処理を進めます。
この方式では、検証者セットや署名鍵の管理がとても重要になります。
| リスク | 例 | 起こり得る影響 |
|---|---|---|
| 秘密鍵の侵害 | 署名者の鍵が窃取・悪用される | 不正メッセージに署名される可能性 |
| 閾値設定が弱い | 少数の署名だけで実行できる | 一部の署名者侵害で全体に影響する可能性 |
| 検証者の集中 | 検証者が少数組織に偏る | 共謀や運用停止の影響が大きくなる |
| 検証者の停止 | 署名が集まらない | メッセージ伝達や資産移動が止まる |
| 署名者セット更新の不備 | 古い署名者や不正な署名者を受け入れる | 不正実行につながる可能性 |
| 監視不足 | 異常な署名や大量処理に気づかない | 被害拡大につながる可能性 |
ここで大切なのは、署名があること自体が安全性を保証するわけではないという点です。
見るべきなのは、次のような点です。
- 誰が署名者なのか
- 何人中何人の署名が必要なのか
- 署名鍵はどのように管理されているのか
- 署名者セットはどのように更新されるのか
- 署名者が停止したときどうなるのか
- 署名者が侵害されたとき検知・停止できるのか
Wormholeの公式資料では、Guardian NetworkやVAAの説明において、Guardianがメッセージを検証・署名し、supermajorityの署名によって有効なVAAが作られる仕組みが説明されています。
参考: Wormhole Docs: Guardians
参考: Wormhole Docs: VAAs
💡 豆知識
「署名があるから安全」と考えたくなりますが、実際には「誰の署名か」「何人分必要か」「その鍵はどう守られているか」が重要です。
これは、紙の契約書でも、知らない人の印鑑が押されているだけでは信用できないのと似ています。
7.4 流動性・会計リスク
次に、流動性・会計リスクです。
ブリッジでは、ロック量、ミント量、バーン量、リリース量、流動性、手数料などのつじつまが合っている必要があります。
第3章で見たように、Lock and Mintでは、送信元チェーンでロックされた量と、宛先チェーンでミントされた量の対応が重要でした。
Lock and Releaseや流動性ネットワークでは、宛先側に十分な流動性があるかも重要になります。
| リスク | 例 | 起こり得る影響 |
|---|---|---|
| ロック量とミント量の不一致 | 100しかロックされていないのに150ミントされる | 裏付けのないラップド資産が生まれる |
| 流動性不足 | 宛先チェーン側のプール残高が足りない | ユーザーが受け取れない、遅延する |
| 手数料計算ミス | 手数料控除後の数量がずれる | ユーザー受取額や会計にズレが出る |
| decimals差 | チェーンやトークンごとに小数桁が違う | 丸め誤差や精度損失が起きる |
| 特殊トークン | fee-on-transfer、rebasingなど | accounting errorsにつながる可能性 |
| 異常な大量移動 | 短時間に大きな流出が起きる | 流動性やリスク上限に影響する |
ChainlinkのCCIP Token Poolsの資料では、チェーン間でtoken decimalsが異なる場合、精度損失が発生し得ることや、burn/mint poolsでは失われた精度が永久にバーンされ、lock/release poolsではソース側プールに蓄積されることが説明されています。
参考: Chainlink Docs: Cross-Chain Token Standard - Token Pools
また、OptimismのStandard Bridge資料では、fee-on-transfer tokensやrebasing tokensはaccounting errorsを引き起こす可能性があるため未対応であることが説明されています。
参考: Optimism Docs: Using the Standard Bridge
ここで重要なのは、ブリッジが単に「数量をコピーする」だけではないということです。
トークンの仕様、手数料、decimals、流動性、プール設計、rate limitなどが関係します。
7.5 finality・リプレイ・順序リスク
次に、finality、リプレイ、順序に関するリスクです。
ブリッジでは、送信元チェーンで起きた出来事を、宛先チェーンで使います。
そのため、送信元チェーン側の出来事が十分に確定しているかが重要になります。
finality は、ざっくり言うと、取引やブロックが巻き戻りにくくなった状態です。
チェーンによってfinalityの考え方や時間は異なります。
もし、finalityが十分でない段階で宛先チェーン側の処理を進めると、あとから送信元チェーン側の状態が変わり、宛先チェーン側と食い違う可能性があります。
| リスク | 内容 | 起こり得る影響 |
|---|---|---|
| finality不足 | 送信元チェーンの取引が十分に確定する前に処理する | 巻き戻りにより不整合が起きる可能性 |
| replay | 一度使ったメッセージを再利用する | 二重ミントや二重実行につながる |
| 順序不整合 | 複数メッセージが意図しない順番で実行される | アプリケーション状態が壊れる可能性 |
| nonce管理不備 | メッセージの一意性を確認できない | 重複処理を防げない |
| chain id確認不足 | 別チェーン向けのメッセージを受け入れる | 誤実行につながる可能性 |
たとえば、同じメッセージを2回使えてしまうと、同じロックイベントに対して2回ミントできるかもしれません。
これは、ポイント交換で同じ交換申請を2回処理してしまうようなものです。
このような仕組みにより、同じメッセージを二重に使わせないことが重要になります。
メッセージング型のプロトコルでは、順序も重要です。
たとえば、次のような2つのメッセージがあるとします。
message 1: ユーザーのポジションを作る
message 2: そのポジションを更新する
このとき、message 2がmessage 1より先に実行されると、宛先チェーン側のコントラクトが意図しない状態になるかもしれません。
そのため、ブリッジやメッセージングプロトコルでは、nonce、sequence、message id、chain id、sender、receiverなどを使って、メッセージの一意性や順序を管理します。
7.6 アップグレード・ガバナンスリスク
次に、アップグレード・ガバナンスリスクです。
ブリッジは、一度デプロイしたら終わりではありません。
新しいチェーンへの対応、バグ修正、手数料変更、検証者セット更新、緊急停止などのために、管理者権限やアップグレード機能を持つ場合があります。
これは便利です。
しかし、同時にリスクにもなります。
| リスク | 例 | 起こり得る影響 |
|---|---|---|
| 管理者鍵の侵害 | 管理者権限が奪われる | コントラクト設定や資産に影響する可能性 |
| 即時アップグレード | 変更がすぐ反映される | 利用者や監視者が確認する時間がない |
| 不適切な設定変更 | 閾値、アドレス、対応トークンを誤設定する | 検証不備や資産不整合につながる可能性 |
| emergency pauseの乱用・不備 | 停止できない、または過剰に停止される | 事故時対応や可用性に影響する |
| ガバナンスの集中 | 少数の主体が重要変更を行える | 利用者が受け入れる信頼仮定が大きくなる |
L2BEATのL2Bridge Risk Frameworkでも、upgradabilityやpermissioned actorsはブリッジを評価する際の追加観点として挙げられています。
参考: L2BEAT Forum: L2Bridge Risk Framework
アップグレード権限は悪いものとは限りません。
バグが見つかったときに修正できる。
異常が起きたときに一時停止できる。
新しいチェーンやトークンに対応できる。
こうしたメリットがあります。
一方で、その権限が強すぎたり、少数の鍵で即時に実行できたりすると、利用者にとって大きな信頼仮定になります。
ブリッジを見るときは、「アップグレード可能かどうか」だけでなく、次のような点を見ると整理しやすくなります。
- 誰がアップグレードできるのか
- 何人の承認が必要なのか
- timelockはあるのか
- 変更内容は公開されるのか
- 緊急停止権限は誰にあるのか
- 停止後の復旧手順はあるのか
7.7 ユーザーUXリスク
次に、ユーザーUXリスクです。
ブリッジのリスクというと、スマートコントラクトや検証者の話に目が行きがちです。
しかし、ユーザー操作も大きなリスクになります。
| リスク | 例 | 起こり得る影響 |
|---|---|---|
| 偽サイト | 検索広告やSNSから偽ブリッジへ誘導される | 資産や承認権限を失う可能性 |
| 誤チェーン選択 | 送信元・宛先チェーンを間違える | 意図しない場所へ送ってしまう |
| 誤アドレス | 宛先アドレスを間違える | 資産を回収できない可能性 |
| 無制限Approve | トークン使用権限を広く与えすぎる | 後から資産を抜かれる可能性 |
| ガス不足 | 宛先チェーンのガスが足りない | claimや実行ができない場合がある |
| 待ち時間の誤解 | すぐ届くと思っていたが時間がかかる | 不安や誤操作につながる |
| ラップド資産の誤解 | 元資産と完全に同じだと思う | 裏付けや流動性リスクを見落とす |
ユーザーから見える画面はシンプルでも、裏側は複雑です。
特に注意したいのが、トークンのApproveです。
トークンをブリッジコントラクトに渡すためには、コントラクトに一定の使用権限を与える必要がある場合があります。
このとき、必要以上に大きな権限を与えると、後でその権限が悪用されるリスクがあります。
もちろん、Approveの扱いはウォレットやUIによって異なります。
そのため、利用者は次の点を確認することが大切です。
- 公式URLか
- 接続しているウォレットは正しいか
- 送信元チェーンと宛先チェーンは正しいか
- トークンのコントラクトアドレスは正しいか
- Approveする数量は適切か
- 待ち時間や手数料は確認したか
- 失敗時にどうなるかを確認したか
💡 豆知識
ブリッジ利用時のリスクは、プロトコル側だけにあるわけではありません。
偽サイト、誤チェーン、無制限Approveなど、ユーザー操作に関係するリスクもあります。
「公式リンクから入る」「署名内容を確認する」「不要なApproveを残さない」といった基本動作も大切です。
7.8 リスクは単独ではなく組み合わさる
ここまで、リスクを分類して見てきました。
ただし、実際のインシデントでは、リスクが単独で起きるとは限りません。
複数の問題が重なって、大きな影響になることがあります。
たとえば、次のような組み合わせです。
| 組み合わせ | 起こり得ること |
|---|---|
| 署名鍵侵害 + 閾値設定が弱い | 少数の鍵侵害で不正メッセージが通る |
| コントラクトバグ + 監視不足 | 異常なミントに気づくのが遅れる |
| finality不足 + 高速処理 | 巻き戻りにより状態が食い違う |
| 流動性不足 + UX説明不足 | ユーザーが受け取れず混乱する |
| アップグレードミス + 即時反映 | 誤設定がすぐ本番に反映される |
| 偽サイト + 無制限Approve | ユーザー資産が広く危険にさらされる |
情報セキュリティでは、1つの弱点だけでなく、複数の弱点がつながることで大きな事故になることがあります。
ブリッジでも同じです。
SoK: Cross-Chain Bridging Architectural Design Flaws and Mitigations では、複数のブリッジやインシデントを分析し、ブリッジのアーキテクチャ構成要素と脆弱性・設計上の欠陥を関連づけています。
このような研究は、ブリッジのリスクを個別のバグだけでなく、設計・構成要素・運用の組み合わせとして見るうえで参考になります。
参考: SoK: Cross-Chain Bridging Architectural Design Flaws and Mitigations
7.9 小さなコードでリスク台帳を作ってみる
ここで、ブリッジのリスクを整理するための小さなPythonコードを見てみます。
このコードは、実在ブリッジの安全性を判定するものではありません。
目的は、リスクを「分類」「影響度」「発生しやすさ」「対策メモ」として整理する考え方を示すことです。
# このコードは、ブリッジのリスクを整理するための学習用コードです。
# 実在するブリッジの安全性評価、監査、利用推奨を行うものではありません。
from dataclasses import dataclass
from typing import List
@dataclass
class BridgeRisk:
"""
ブリッジに関するリスクを整理するためのデータクラスです。
category:
リスクの分類です。例: smart_contract, validator, liquidity
description:
リスクの内容です。
impact:
影響度です。1〜5で大きいほど影響が大きいとします。
likelihood:
起こりやすさです。1〜5で大きいほど起こりやすいとします。
mitigation:
考えられる対策や確認ポイントです。
"""
category: str
description: str
impact: int
likelihood: int
mitigation: str
def score(self):
"""
影響度と起こりやすさを掛け合わせて、簡単なリスクスコアを計算します。
注意:
これは学習用の単純な計算です。
実際のリスク評価では、資産規模、検出可能性、攻撃難易度、
運用体制、依存先なども考える必要があります。
"""
return self.impact * self.likelihood
def sort_risks_by_score(risks: List[BridgeRisk]):
"""
リスクスコアが高い順に並べ替えます。
"""
return sorted(risks, key=lambda risk: risk.score(), reverse=True)
risks = [
BridgeRisk(
category="smart_contract",
description="署名検証やnonce管理に不備がある",
impact=5,
likelihood=2,
mitigation="監査、形式検証、テスト、処理済みメッセージ管理を確認する",
),
BridgeRisk(
category="validator",
description="検証者やガーディアンの秘密鍵が侵害される",
impact=5,
likelihood=2,
mitigation="multi-sig、HSM、鍵ローテーション、監視、閾値設計を確認する",
),
BridgeRisk(
category="liquidity",
description="宛先チェーン側の流動性が不足する",
impact=3,
likelihood=3,
mitigation="流動性残高、rate limit、失敗時対応、手数料を確認する",
),
BridgeRisk(
category="ux",
description="ユーザーが偽サイトで無制限Approveを行う",
impact=4,
likelihood=3,
mitigation="公式URL確認、署名内容確認、不要なApprove解除を案内する",
),
BridgeRisk(
category="governance",
description="管理者権限で即時アップグレードが可能",
impact=4,
likelihood=2,
mitigation="timelock、multi-sig、変更履歴、監視体制を確認する",
),
]
for risk in sort_risks_by_score(risks):
print(f"[{risk.category}] score={risk.score()} {risk.description}")
print(f" mitigation: {risk.mitigation}")
このコードでは、リスクを次のように扱っています。
- リスクを分類する
- 影響度と起こりやすさを仮の数値で置く
- リスクスコアを計算する
- スコアが高い順に並べる
- 対策や確認ポイントをメモする
実行結果のイメージは次のようになります。
[ux] score=12 ユーザーが偽サイトで無制限Approveを行う
mitigation: 公式URL確認、署名内容確認、不要なApprove解除を案内する
[smart_contract] score=10 署名検証やnonce管理に不備がある
mitigation: 監査、形式検証、テスト、処理済みメッセージ管理を確認する
[validator] score=10 検証者やガーディアンの秘密鍵が侵害される
mitigation: multi-sig、HSM、鍵ローテーション、監視、閾値設計を確認する
ここで大切なのは、スコアの数値そのものではありません。
リスクを分類し、どこから確認すべきかを考えることです。
実際のリスク評価では、次のような要素も必要になります。
- 扱っている資産額
- 対応チェーン数
- 検証者セット
- 管理者権限
- 監査状況
- 過去のインシデント
- 監視・アラート
- rate limit
- emergency pause
- 失敗時対応
- 利用者への説明
このように、ブリッジのリスクは1つのスコアだけで決まるものではありません。
ただし、学習段階では、リスクを台帳のように整理するだけでも、見落としを減らしやすくなります。
7.10 この章のまとめ
この章では、ブリッジのリスクを情報セキュリティの観点から整理しました。
ブリッジは、異なるチェーンをつなぐ便利な仕組みです。
一方で、チェーン本体とは別に、スマートコントラクト、署名者、検証者、流動性、管理権限、ユーザー操作など、多くの信頼点を追加します。
この章で押さえたいポイントは、次の通りです。
- ブリッジのリスクは、スマートコントラクトだけでなく、検証者、鍵管理、流動性、UX、運用権限にも関係する
- スマートコントラクトリスクでは、ロック、ミント、署名検証、nonce管理、権限チェックが重要になる
- 署名者・検証者リスクでは、秘密鍵管理、署名閾値、検証者セットの分散性が重要になる
- 流動性・会計リスクでは、ロック量と発行量、decimals、特殊トークン、流動性不足に注意する
- finality・リプレイ・順序リスクでは、取引の確定、二重実行防止、メッセージ順序が重要になる
- アップグレード・ガバナンスリスクでは、管理者権限、timelock、multi-sig、緊急停止の設計を見る必要がある
- ユーザーUXリスクでは、偽サイト、誤チェーン、無制限Approve、待ち時間の誤解に注意する
- リスクは単独ではなく、複数の問題が組み合わさって大きな影響になる場合がある
- リスクを分類し、影響度や確認ポイントを整理すると、全体像をつかみやすくなる
次の章では、代表的なブリッジ関連インシデントから学べることを整理します。
Wormhole、Ronin Bridge、Nomad、BSC Token Hubなどを、攻撃手順ではなく、署名検証、鍵管理、設定・アップグレード、証明検証の重要性という観点から見ていきます。
8. 代表的なブリッジ関連インシデントから学ぶこと
この章では、過去の代表的なブリッジ関連インシデントを、設計・運用上の学びとして整理します。
ポイントは、攻撃手順を再現することではなく、どの信頼点・検証点・運用点が問題になったのか を見ることです。
前の章では、ブリッジのリスクを情報セキュリティの観点から整理しました。
スマートコントラクト、署名者・検証者、流動性、finality、アップグレード、ユーザーUXなど、ブリッジにはいくつものリスクが重なります。
この章では、そのリスクが実際のインシデントでどのような形で問題になったのかを見ていきます。
ただし、最初に大切な注意があります。
本章では、攻撃手順や悪用コードは扱いません。
扱うのは、あくまで次のような観点です。
- どの検証点が重要だったのか
- どの鍵管理・権限管理が重要だったのか
- アップグレードや設定変更で何に注意すべきだったのか
- 証明検証ロジックの重要性はどこにあったのか
- 監視や異常検知がなぜ必要なのか
- 同じようなリスクを避けるには、何を確認すべきか
つまり、インシデントを「怖い話」として終わらせるのではなく、ブリッジ設計・運用・監視の学び として整理します。
8.1 事例を見るときの注意
ブリッジ関連のインシデントを見るときは、いくつか注意が必要です。
まず、被害額は資料によって表記が異なる場合があります。
暗号資産の価格は変動するため、同じ事件でも「当時価格」「報道時点の価格」「回収後の損失額」などで数字が変わることがあります。
また、原因の説明も資料によって粒度が違います。
公式発表、セキュリティ企業の分析、報道、研究論文では、同じ事件でも強調される点が少しずつ異なります。
そのため、本記事では次の方針で扱います。
| 方針 | 内容 |
|---|---|
| 被害額は「約」「相当」などを付ける | 価格変動や集計方法の違いを考慮するため |
| 出典を明記する | どの資料に基づく説明かを分かるようにするため |
| 原因は断定しすぎない | 公開情報だけでは詳細に限界があるため |
| 攻撃手順には踏み込まない | 不正利用につながる可能性があるため |
| 学びを中心にする | 設計・運用・監視上の注意点を整理するため |
Chainalysisは、2022年時点でクロスチェーンブリッジへの攻撃が暗号資産セキュリティ上の大きなリスクとして浮上したことを指摘しています。
同記事では、2022年8月時点で13件のクロスチェーンブリッジ攻撃により、約20億ドル相当の暗号資産が不正に流出したと説明されています。
参考: Chainalysis: Cross-Chain Bridge Hacks Emerge as Top Security Risk
また、SoK: Cross-Chain Bridging Architectural Design Flaws and Mitigations では、2021年から2023年の複数のブリッジとインシデントを対象に、ブリッジのアーキテクチャ構成要素、設計上の欠陥、影響軽減策を整理しています。
参考: SoK: Cross-Chain Bridging Architectural Design Flaws and Mitigations
このような資料は、個別事件を単なるニュースとして見るのではなく、ブリッジ全体のリスク構造を理解するうえで参考になります。
8.2 Wormhole:署名検証と実装更新の重要性
まず、Wormholeの事例を見てみます。
Wormholeは、複数のブロックチェーン間でメッセージを伝えるプロトコルです。
第6章でも触れたように、WormholeではGuardiansがメッセージを検証・署名し、VAAという署名付きメッセージとして扱う仕組みが説明されています。
2022年2月、Wormholeのブリッジに関連する大規模なインシデントが発生しました。
CertiKの分析では、不正な主体がSolana上のWormhole bridgeにおけるverification processを迂回し、Wormhole ETHをミントしたと説明されています。
参考: CertiK: Wormhole Bridge Exploit Analysis
また、Merkle Scienceの分析では、このインシデントでWormholeは3億ドル超規模の損失を受け、Jump Cryptoが120,000 ETHを補填したと説明されています。
参考: Merkle Science: Analysis of the Wormhole Token Bridge Exploit
ここでは、細かい攻撃手順には入りません。
学びとして見たいのは、次の点です。
| 観点 | 学び |
|---|---|
| 署名検証 | 署名やVAAの検証ロジックは、ブリッジの中核である |
| 実装更新 | 修正やアップグレードの反映タイミングが重要になる |
| 検証済みメッセージ | 不正なメッセージを正しいものとして扱わない設計が必要 |
| 監視 | 異常なミントや大規模な資産移動を検知できる必要がある |
| 影響範囲 | ラップド資産の裏付けや信頼に大きく関係する |
Wormholeの事例から分かるのは、ブリッジでは 検証ロジックが少しでも崩れると、宛先チェーン側で本来発行されるべきでない資産が発行される可能性がある という点です。
この図で見てほしいのは、検証部分がブリッジの安全性に直結していることです。
8.3 Ronin Bridge:バリデータ鍵管理の重要性
次に、Ronin Bridgeの事例です。
Ronin Bridgeは、Axie Infinity関連のエコシステムで使われていたブリッジとして知られています。
2022年3月、Ronin Bridgeでは大規模なインシデントが報告されました。
Wiredの記事では、Roninのインシデントで173,600 ETHと25.5M USDCが不正に流出したと説明されています。
同記事では、この事件はソフトウェアの特定バグというより、ソーシャルエンジニアリングや鍵へのアクセス、セキュリティ設計上の問題が関係したものとして説明されています。
参考: WIRED: Blockchains Have a Bridge Problem, and Hackers Know It
また、SoK: A Review of Cross-Chain Bridge Hacks in 2023 でも、Ronin Bridgeでは、侵害された秘密鍵を用いて不正なwithdrawalが承認された事例として整理されています。
参考: SoK: A Review of Cross-Chain Bridge Hacks in 2023
この事例で学びたいのは、鍵管理と閾値設計 の重要性です。
| 観点 | 学び |
|---|---|
| バリデータ鍵 | 検証者や承認者の秘密鍵は極めて重要な資産である |
| 閾値設計 | 何人中何人の承認が必要かでリスクが変わる |
| 分散性 | 承認者が少数に偏ると、侵害時の影響が大きくなる |
| 監視 | 大規模な出金や異常操作を早期検知する仕組みが必要 |
| 権限棚卸し | 過去に一時的に与えた権限が残っていないか確認が必要 |
身近な例でいうと、金庫を開けるための鍵を複数人で管理しているようなものです。
本来は複数人の承認が必要でも、鍵の管理が甘かったり、承認者が少数に集中していたりすると、金庫全体が危険になります。
Ronin Bridgeの事例は、ブリッジのリスクがスマートコントラクトのバグだけではないことを示しています。
鍵管理、承認者設計、監視、権限の棚卸しも、ブリッジセキュリティの重要な要素です。
8.4 Nomad:設定・アップグレード管理の重要性
次に、Nomad Bridgeの事例です。
Nomad Bridgeでは、2022年8月に大規模なインシデントが発生しました。
Immunefiの分析では、Nomad Bridgeが2022年8月1日に攻撃され、約1.9億ドル相当のlocked fundsが流出したと説明されています。
参考: Immunefi: Hack Analysis - Nomad Bridge, August 2022
また、Google Cloud / Mandiantの分析では、Nomadのtoken bridgeに対する攻撃として、アップデート後の検証処理に関係する問題が説明されています。
参考: Google Cloud: Dissecting the Nomad Bridge Hack and Following the Money
ここでも、細かい攻撃手順には入りません。
学びとして重要なのは、設定変更やアップグレード後の検証 です。
| 観点 | 学び |
|---|---|
| アップグレード | コントラクト更新後の挙動確認が重要 |
| 初期化・設定 | 設定値の誤りが検証ロジックに大きく影響する可能性がある |
| レビュー | コードだけでなく、デプロイ手順や初期化手順も確認する必要がある |
| 監視 | 異常な連続出金や同様のトランザクションを検知する必要がある |
| 緊急停止 | 異常時に止められる仕組みと、その運用が重要 |
アップグレードは悪いものではありません。
バグ修正や機能追加のために必要です。
しかし、アップグレードや設定変更は、ブリッジのような資産を扱うシステムでは特に慎重に扱う必要があります。
Nomadの事例からは、スマートコントラクトのコードだけでなく、デプロイ・初期化・設定変更・監視 まで含めて考える必要があることが分かります。
8.5 BSC Token Hub:証明検証ロジックの重要性
次に、BSC Token Hubの事例です。
BNB Chainの公式ブログでは、2022年10月にBNB Beacon ChainとBNB Smart ChainをつなぐネイティブクロスチェーンブリッジであるBSC Token Hubに影響するexploitが発生したと説明されています。
同記事では、2 million BNBが引き出されたこと、BSC validatorsによってチェーンが停止されたことなどが説明されています。
参考: BNB Chain: BNB Chain Ecosystem Update
Immunefiの分析では、このインシデントはIAVL Merkle proof verification systemの欠陥により、不正な主体が2M BNB、当時約6億ドル相当を不正取得することにつながったと説明されています。
参考: Immunefi: Hack Analysis - Binance Bridge, October 2022
ここで学びたいのは、証明検証ロジックの重要性 です。
ブリッジでは、送信元チェーンで起きた出来事を証明として宛先側へ渡す場合があります。
この証明を検証するロジックに問題があると、本来正しくない証明を正しいものとして扱ってしまう可能性があります。
| 観点 | 学び |
|---|---|
| 証明検証 | Merkle proofなどの検証ロジックはブリッジの中核である |
| 低レベル実装 | ライブラリや低レベルな検証処理のバグが大きな影響につながる |
| 異常検知 | 大量ミントや異常な引き出しを検知する必要がある |
| 緊急停止 | 異常時にチェーンやブリッジを停止する判断が必要になる場合がある |
| 防御層 | rate limit、監視、権限分離など複数の防御が重要 |
この事例は、ブリッジにおいて「証明を使っているから安全」と単純には言えないことを示しています。
大切なのは、その証明を 正しく検証できているか です。
8.6 事例を表で整理する
ここまで見てきた事例を、表で整理します。
| 事例 | 主な論点 | 学べること | この記事での扱い方 |
|---|---|---|---|
| Wormhole | 署名・検証 | 検証ロジックと実装更新が重要 | 攻撃手順ではなく、署名検証の重要性として扱う |
| Ronin Bridge | 鍵管理 | バリデータ鍵、閾値設計、監視が重要 | 秘密鍵侵害の手順ではなく、鍵管理の重要性として扱う |
| Nomad | 設定・アップグレード | デプロイ、初期化、設定変更、監視が重要 | 悪用手順ではなく、アップグレード管理の重要性として扱う |
| BSC Token Hub | 証明検証 | Merkle proofなどの検証ロジックが重要 | 具体的悪用ではなく、証明検証の重要性として扱う |
この表を見ると、ブリッジのインシデントは一種類ではないことが分かります。
スマートコントラクトの検証ロジックが問題になる場合もあります。
鍵管理が問題になる場合もあります。
アップグレードや設定変更が問題になる場合もあります。
証明検証の実装が問題になる場合もあります。
つまり、ブリッジのセキュリティは、単に「コードを監査すれば終わり」ではありません。
鍵、設定、運用、監視、権限、緊急停止、会計、UXまで含めて考える必要があります。
8.7 共通して見えてくる教訓
代表的な事例から、共通して見えてくる教訓を整理します。
| 教訓 | 内容 |
|---|---|
| 検証ロジックは中核 | 不正なメッセージや証明を通さないことが重要 |
| 鍵管理は資産管理に直結する | 署名者・検証者の鍵が侵害されると大きな影響になる |
| アップグレードは慎重に扱う | コード変更だけでなく、初期化・設定・監視も重要 |
| 証明を使うだけでは十分ではない | 証明を正しく検証できているかが重要 |
| 監視と緊急停止は防御層になる | 異常なミントや大量移動を早期に検知する必要がある |
| 影響範囲はブリッジ外にも広がる | ラップド資産、DeFi、流動性プール、関連dAppに波及する可能性がある |
| 方式名だけでは安全性は分からない | 実装、運用、権限、監査、監視を合わせて見る必要がある |
この教訓は、第7章で整理したリスク分類とも対応しています。
| 第7章のリスク分類 | 関連する事例 |
|---|---|
| スマートコントラクトリスク | Wormhole、Nomad、BSC Token Hub |
| 署名者・検証者リスク | Ronin Bridge、Wormhole |
| 流動性・会計リスク | ラップド資産全般、ブリッジ停止時の影響 |
| finality・リプレイ・順序リスク | メッセージ処理系全般 |
| アップグレード・ガバナンスリスク | Nomad |
| ユーザーUXリスク | 偽サイト・Approveなど、利用者側の被害要因 |
ここで重要なのは、インシデントを「そのプロトコルだけの問題」として終わらせないことです。
別のプロトコルであっても、似た信頼点や検証点を持っていれば、似た種類の注意が必要になります。
8.8 小さなコードで事例から学びを整理する
ここで、事例を「攻撃手順」ではなく「学び」として整理するための小さなPythonコードを見てみます。
このコードは、実在インシデントの詳細分析や安全性評価を行うものではありません。
目的は、事例を 主な論点、リスク分類、学び、確認ポイント に分けて整理することです。
# このコードは、ブリッジ関連インシデントを学びとして整理するための学習用コードです。
# 攻撃手順、悪用コード、実在システムへの評価を行うものではありません。
from dataclasses import dataclass
from typing import List
@dataclass
class IncidentLesson:
"""
ブリッジ関連インシデントから得られる学びを整理するデータクラスです。
case_name:
事例名です。
main_topic:
主な論点です。例: signature verification, key management
risk_categories:
関係するリスク分類です。
lesson:
攻撃手順ではなく、設計・運用上の学びです。
check_points:
同様の観点で確認したいポイントです。
"""
case_name: str
main_topic: str
risk_categories: List[str]
lesson: str
check_points: List[str]
lessons = [
IncidentLesson(
case_name="Wormhole",
main_topic="signature verification",
risk_categories=["smart_contract", "validator", "message_verification"],
lesson="署名やメッセージ検証ロジックは、ブリッジの中核である。",
check_points=[
"署名検証が正しく実装されているか",
"検証済みメッセージだけが実行されるか",
"異常なミントを検知できるか",
],
),
IncidentLesson(
case_name="Ronin Bridge",
main_topic="validator key management",
risk_categories=["validator", "key_management", "monitoring"],
lesson="検証者鍵や閾値設計、監視体制は資産安全性に直結する。",
check_points=[
"秘密鍵が適切に管理されているか",
"署名閾値が十分か",
"大規模出金を早期検知できるか",
],
),
IncidentLesson(
case_name="Nomad",
main_topic="upgrade and configuration",
risk_categories=["upgrade", "configuration", "monitoring"],
lesson="アップグレードや初期化設定は、検証ロジックに大きく影響する。",
check_points=[
"アップグレード手順がレビューされているか",
"初期化値や設定変更が検証されているか",
"異常時に停止できるか",
],
),
IncidentLesson(
case_name="BSC Token Hub",
main_topic="proof verification",
risk_categories=["proof_verification", "smart_contract", "monitoring"],
lesson="証明を使うだけでなく、証明を正しく検証できているかが重要である。",
check_points=[
"proof verificationの実装が十分に検証されているか",
"異常なミントや引き出しを検知できるか",
"緊急時の対応手順があるか",
],
),
]
def print_lessons(lessons: List[IncidentLesson]):
"""
事例からの学びを一覧表示します。
"""
for item in lessons:
print(f"Case: {item.case_name}")
print(f" Topic: {item.main_topic}")
print(f" Risks: {', '.join(item.risk_categories)}")
print(f" Lesson: {item.lesson}")
print(" Check points:")
for point in item.check_points:
print(f" - {point}")
print()
print_lessons(lessons)
このコードで見てほしいのは、事例を次のように分解している点です。
- 事例名
- 主な論点
- 関係するリスク分類
- 設計・運用上の学び
- 確認ポイント
こうして整理すると、事例を単なる事件名として覚えるのではなく、今後ブリッジを調べるときの観点として再利用しやすくなります。
たとえば、ある新しいブリッジを見るときに、次のように確認できます。
- 署名検証はどのように行われているか
- 検証者鍵はどのように管理されているか
- アップグレードや設定変更はどう運用されているか
- 証明検証ロジックはどのようにテスト・監査されているか
- 異常なミントや出金を検知する仕組みはあるか
- 緊急停止や復旧手順はあるか
これは、攻撃手順を知ることではありません。
安全に設計・利用・調査するためのチェック観点を持つことです。
8.9 事例を学ぶときに避けたい見方
最後に、事例を学ぶときに避けたい見方も整理しておきます。
| 避けたい見方 | 理由 |
|---|---|
| 「このブリッジだけが悪かった」と考える | 同じ種類の信頼点を持つ別システムにも学びがあるため |
| 「監査済みなら大丈夫」と考える | 監査後の変更、設定、運用、鍵管理の問題は残り得るため |
| 「分散型なら安全」と考える | どの部分がどの程度分散しているかを見る必要があるため |
| 「大手だから安全」と考える | 組織規模だけで技術・運用リスクは判断できないため |
| 「攻撃手順を理解すれば十分」と考える | 実際に重要なのは、設計・運用・監視で再発を防ぐことだから |
| 「被害額だけで重要度を判断する」と考える | 被害額だけでなく、原因や影響範囲、再発可能性を見る必要があるため |
ブリッジのインシデントは、技術的にも金額的にも目立ちやすいです。
そのため、ニュースとして見ると「大きな事件だった」という印象で終わってしまいがちです。
しかし、技術記事として整理するなら、次のように見る方が学びになります。
何が起きたか
↓
どの信頼点が問題になったか
↓
どの設計・運用で防げた可能性があるか
↓
今後、同じ観点をどこで確認すべきか
この見方を持っておくと、次章で扱う「利用者・開発者が確認すべきポイント」に自然につながります。
💡 豆知識
セキュリティ事例は、「犯人が何をしたか」だけを見るより、「なぜそれが可能だったのか」「どの防御層があれば検知・停止できたのか」を見る方が学びになります。
ブリッジでも、攻撃の再現ではなく、検証、鍵管理、設定、監視、復旧の観点で整理することが大切です。
8.10 この章のまとめ
この章では、代表的なブリッジ関連インシデントから学べることを整理しました。
扱った事例は、Wormhole、Ronin Bridge、Nomad、BSC Token Hubです。
それぞれ細かい背景は異なりますが、ブリッジの信頼点や検証点が重要であることを示しています。
この章で押さえたいポイントは、次の通りです。
- ブリッジ関連インシデントを見るときは、被害額だけでなく、どの信頼点が問題になったのかを見る
- Wormholeの事例からは、署名検証や実装更新の重要性を学べる
- Ronin Bridgeの事例からは、バリデータ鍵管理、閾値設計、監視の重要性を学べる
- Nomadの事例からは、アップグレード、初期化、設定変更、監視の重要性を学べる
- BSC Token Hubの事例からは、Merkle proofなどの証明検証ロジックの重要性を学べる
- 攻撃事例は、攻撃手順ではなく、設計・運用・監視の学びとして扱う
- 事例を整理すると、利用者・開発者が確認すべきポイントが見えやすくなる
- ブリッジの安全性は、コード、鍵、検証、設定、監視、ガバナンス、UXの組み合わせで考える必要がある
次の章では、ここまでの仕組み・リスク・事例を踏まえて、利用者・開発者が確認すべきポイント を整理します。
公式URL、対応チェーン、ネイティブ資産かラップド資産か、待ち時間、手数料、承認権限、監査、失敗時対応などを、チェックリストとして見ていきます。
9. 利用者・開発者が確認すべきポイント
この章では、ここまで整理してきた仕組み・リスク・事例をもとに、ブリッジを使う人、開発する人、調査する人が確認したいポイントを整理します。
ポイントは、「有名だから大丈夫」「公式っぽいから大丈夫」「監査済みだから大丈夫」で止まらず、何をどこまで確認するかを分けて見ること です。
前の章では、Wormhole、Ronin Bridge、Nomad、BSC Token Hubなどの事例から、ブリッジにおける検証、鍵管理、設定変更、証明検証の重要性を見てきました。
この章では、その学びをもう少し実践的な確認ポイントに落とし込みます。
ただし、本記事は特定のブリッジの利用をすすめるものではありません。
また、投資判断や法律上の助言を行うものでもありません。
ここで扱うのは、あくまで技術理解とセキュリティ確認の観点です。
ブリッジを見るときは、大きく次の3つの立場に分けると整理しやすくなります。
| 立場 | 主に見ること |
|---|---|
| 利用者 | 公式URL、対応チェーン、対応トークン、手数料、待ち時間、Approve、失敗時対応 |
| 開発者 | メッセージ検証、nonce管理、replay対策、宛先実行、監視、緊急停止 |
| 調査・学習者 | 方式、信頼モデル、検証者、権限、過去事例、公式資料、監査レポート |
この章では、利用者向け、開発者向け、調査向けの順に確認ポイントを整理します。
9.1 まず確認したい全体像
ブリッジを使う前、作る前、調べる前に、まず次の5つの問いを置くと整理しやすくなります。
1. 何を送るのか
2. どこからどこへ送るのか
3. どの方式で表現されるのか
4. 誰が送信元チェーンの出来事を検証するのか
5. 失敗したらどうなるのか
図にすると、次のようになります。
この5つを確認するだけでも、「なんとなく便利そう」から一歩進んで、ブリッジの仕組みをより具体的に見られます。
特に重要なのは、資産の移動に見えるものが、実際にはどのような状態変更で表現されているのか を確認することです。
9.2 利用者が確認したいポイント
まず、利用者目線の確認ポイントです。
ブリッジを使うときは、画面上では「送信元チェーン」「宛先チェーン」「トークン」「数量」を選んでボタンを押すだけに見えるかもしれません。
しかし、裏側ではロック、バーン、ミント、リレイヤー、検証、待ち時間、手数料、Approveなどが関係します。
利用者として最低限確認したいポイントを表にすると、次のようになります。
| 確認項目 | 見る理由 |
|---|---|
| 公式URLか | 偽サイトやフィッシングを避けるため |
| 対応チェーンは正しいか | 誤ったネットワークへ送らないため |
| 対応トークンは正しいか | 偽トークンや未対応トークンを避けるため |
| ネイティブ資産かラップド資産か | 裏付けや信頼対象が変わるため |
| 待ち時間はどれくらいか | finality待ちやチャレンジ期間が関係するため |
| 手数料やガス代はどれくらいか | 送信元・宛先の両方で費用が必要な場合があるため |
| Approveする数量は適切か | 必要以上の権限を与えないため |
| 失敗時の対応はあるか | claim、再送、返金、サポートが必要になる場合があるため |
| 公式ドキュメントはあるか | 仕様や注意点を確認するため |
| 最近の障害・停止情報はないか | 一時停止や混雑中に利用しないため |
ここで特に大切なのは、公式URL と Approve です。
偽サイトにウォレットを接続してしまうと、ブリッジ以前の問題として資産を失うリスクがあります。
また、トークンのApproveで必要以上の権限を与えると、後からその権限が悪用される可能性があります。
この図は単純化したものですが、利用前の基本確認としては役立ちます。
💡 豆知識
ブリッジ利用時のミスは、必ずしもブリッジ本体の脆弱性だけで起きるわけではありません。
偽サイト、誤チェーン、誤トークン、無制限Approveなど、利用者側の操作に関係するリスクもあります。
技術的な仕組みを理解することと、実際に使う前の確認はセットで考えると安全に近づきます。
9.3 ネイティブ資産かラップド資産かを確認する
ブリッジで受け取る資産が、ネイティブ資産なのか、ラップド資産なのかは重要です。
たとえば、同じように USDC と表示されていても、チェーンやブリッジによって、ネイティブUSDCなのか、ブリッジ経由のラップド表現なのかが異なる場合があります。
この違いは、裏付け、流動性、DeFiでの扱い、引き出し経路に影響します。
| 種類 | ざっくりした説明 | 見るポイント |
|---|---|---|
| ネイティブ資産 | そのチェーン上で発行体やプロトコルが直接扱う資産 | 発行体、対応チェーン、mint/burn権限 |
| ラップド資産 | 元資産に対応する別チェーン上の表現 | ロック量、発行量、ブリッジへの信頼 |
| 流動性経由の資産 | 宛先側のプールやLPから支払われる資産 | 流動性、手数料、精算方法 |
| アプリ専用表現 | 特定アプリやプロトコル内で使う表現 | どこで使えるか、戻せるか |
Circle CCTPのように、送信元チェーンでUSDCをバーンし、宛先チェーンでUSDCをミントする方式では、発行体が大きな役割を持ちます。
参考: Circle Developers: Cross-Chain Transfer Protocol
一方、Lock and Mint型では、送信元チェーンでロックされた元資産に対して、宛先チェーンでラップド資産がミントされる場合があります。
この場合、ロック量と発行量の整合性、ブリッジコントラクト、検証モデルが重要になります。
確認するときは、次のような問いを置くとよいです。
この資産は、
元資産そのものなのか
ラップド資産なのか
どのブリッジを通って発行されたのか
どこで元資産に戻せるのか
どのDeFiや取引所で扱えるのか
特に、トークン名やシンボルだけで判断しないことが大切です。
同じような名前でも、コントラクトアドレスが違えば別の資産です。
9.4 待ち時間・手数料・失敗時対応を確認する
ブリッジでは、待ち時間や手数料も重要です。
特に、L2からL1へ戻す場合や、finality待ちがある場合、ユーザーが想像するより時間がかかることがあります。
Optimismの公式ドキュメントでは、EthereumからOP Mainnetへの転送は通常1〜3分程度、OP MainnetからEthereumへの転送はwithdrawal challenge periodにより7日かかると説明されています。
参考: Optimism Docs: Using the Standard Bridge
このように、同じブリッジでも方向によって待ち時間が異なる場合があります。
| 確認項目 | 例 |
|---|---|
| 送信元チェーンのガス代 | 送信元でロック・バーンするための費用 |
| 宛先チェーンのガス代 | claimや実行に必要な費用 |
| ブリッジ手数料 | プロトコルや流動性提供者に支払う費用 |
| 待ち時間 | finality待ち、チャレンジ期間、リレイヤー処理 |
| 手動操作 | claim、redeem、retryが必要か |
| 失敗時対応 | 返金、再送、サポート、手動復旧の有無 |
Arbitrumの公式ドキュメントでは、retryable ticketが親チェーンから子チェーンへのメッセージ作成の標準的な仕組みとして説明されています。
このように、L2関連のブリッジでは、単に「送る」だけでなく、メッセージの作成、実行、再実行、redeemなどが関係する場合があります。
参考: Arbitrum Docs: Bridging from a parent chain to a child chain
利用者としては、次の点を確認しておくと安心です。
- どのくらい待つ可能性があるか
- 手動claimが必要か
- 宛先チェーンのガス代が必要か
- 失敗した場合、どこで状態を確認できるか
- サポートや公式FAQがあるか
- トランザクションIDを控えておくべきか
9.5 開発者が確認したいポイント
次に、開発者目線の確認ポイントです。
クロスチェーンアプリケーションを作る場合、ブリッジやメッセージングプロトコルを使って、別チェーンのコントラクトを呼び出すことがあります。
このとき、単に「メッセージを受け取ったら実行する」だけでは危険です。
開発者として確認したいポイントは、次の通りです。
| 確認項目 | 見る理由 |
|---|---|
| 送信元チェーンを確認しているか | 想定外のチェーンからのメッセージを拒否するため |
| 送信元コントラクトを確認しているか | 偽の送信元からのメッセージを拒否するため |
| 宛先コントラクトを確認しているか | 意図しないコントラクトで実行されないようにするため |
| nonceやmessage idを管理しているか | 二重実行やreplayを防ぐため |
| メッセージ形式を検証しているか | 不正なpayloadや想定外データを拒否するため |
| 失敗時の処理を設計しているか | ガス不足や宛先実行失敗に対応するため |
| rate limitを設けているか | 異常な大量実行を抑制するため |
| emergency pauseがあるか | 異常時に止められるようにするため |
| 監視・アラートがあるか | 異常なミント、出金、メッセージ量を検知するため |
| アップグレード権限を管理しているか | 管理者権限が単一障害点にならないようにするため |
Chainlink CCIPの防御的なprogrammable token transferのチュートリアルでは、受信側でエラーが発生した場合にトークンをロックし、回復・リダイレクトできる設計例が説明されています。
参考: Chainlink Docs: Transfer Tokens with Data - Defensive Example
このように、クロスチェーンアプリケーションでは、宛先側での失敗時対応も重要です。
この図は単純化したものですが、開発者が意識したい基本形を表しています。
9.6 小さな疑似コードで受信側チェックを見てみる
ここで、クロスチェーンメッセージを受け取る側の基本チェックを、簡単なPythonコードで表してみます。
このコードは学習用です。
実在するブリッジ、スマートコントラクト、署名検証、メッセージングプロトコルを再現するものではありません。
目的は、受け取ったメッセージをそのまま実行するのではなく、送信元、重複、形式を確認してから処理する という考え方を理解することです。
# このコードは、クロスチェーンメッセージ受信時の確認観点を学ぶためのものです。
# 実在するブリッジやスマートコントラクトの実装ではありません。
from dataclasses import dataclass
@dataclass(frozen=True)
class IncomingMessage:
"""
宛先チェーン側で受け取るメッセージを表します。
source_chain:
メッセージの送信元チェーンです。
source_contract:
メッセージを送った送信元コントラクトです。
receiver:
宛先側で処理を受けるユーザーやコントラクトです。
amount:
反映したい数量です。
nonce:
メッセージを一意に識別する番号です。
payload:
宛先側で使う追加データです。
"""
source_chain: str
source_contract: str
receiver: str
amount: int
nonce: int
payload: dict
class SafeMessageReceiver:
"""
受信側コントラクトの確認処理を、学習用に単純化したクラスです。
"""
def __init__(self, allowed_source_chain, allowed_source_contract):
# 許可する送信元チェーンです。
self.allowed_source_chain = allowed_source_chain
# 許可する送信元コントラクトです。
self.allowed_source_contract = allowed_source_contract
# 処理済みnonceを記録します。
# 同じメッセージの二重実行を防ぐために使います。
self.processed_nonces = set()
# 宛先側の残高を表す簡単な辞書です。
self.balances = {}
def validate_message(self, message):
"""
メッセージを実行する前に、基本的な確認を行います。
"""
# 1. 送信元チェーンが想定通りか確認します。
if message.source_chain != self.allowed_source_chain:
raise ValueError("許可されていない送信元チェーンです")
# 2. 送信元コントラクトが想定通りか確認します。
if message.source_contract != self.allowed_source_contract:
raise ValueError("許可されていない送信元コントラクトです")
# 3. nonceがすでに処理済みでないか確認します。
if message.nonce in self.processed_nonces:
raise ValueError("このメッセージはすでに処理されています")
# 4. 数量が正の値か確認します。
if message.amount <= 0:
raise ValueError("amountは正の値である必要があります")
# 5. payloadに必要なフィールドがあるか確認します。
# 実際のアプリでは、型や値の範囲も確認する必要があります。
if "action" not in message.payload:
raise ValueError("payloadにactionがありません")
def execute_message(self, message):
"""
検証済みのメッセージを実行します。
"""
# 実行前に必ず検証します。
self.validate_message(message)
# ここでは例として、receiverの残高を増やします。
self.balances[message.receiver] = (
self.balances.get(message.receiver, 0) + message.amount
)
# 実行後にnonceを処理済みとして記録します。
self.processed_nonces.add(message.nonce)
return {
"status": "executed",
"receiver": message.receiver,
"amount": message.amount,
}
receiver = SafeMessageReceiver(
allowed_source_chain="Chain A",
allowed_source_contract="BridgeAppOnChainA",
)
message = IncomingMessage(
source_chain="Chain A",
source_contract="BridgeAppOnChainA",
receiver="alice",
amount=100,
nonce=1,
payload={"action": "credit"},
)
print(receiver.execute_message(message))
print(receiver.balances)
このコードでは、次のような確認をしています。
| コード上の確認 | 開発時の意味 |
|---|---|
source_chain |
想定したチェーンからのメッセージか |
source_contract |
想定した送信元コントラクトからのメッセージか |
nonce |
同じメッセージを二重に処理していないか |
amount |
数量が不正な値ではないか |
payload |
必要なデータ形式を満たしているか |
もちろん、実際のスマートコントラクトでは、これだけで十分ではありません。
署名検証、proof検証、protocol-specificな検証、ガス制御、再入防止、権限管理、エラー時対応なども必要になります。
それでも、学習段階では、受け取ったメッセージをそのまま信じない という考え方が重要です。
9.7 調査・学習者が見るとよい資料
ブリッジを調べるときは、公式資料と第三者資料を分けて見ると整理しやすくなります。
| 資料の種類 | 見る内容 |
|---|---|
| 公式ドキュメント | 仕様、対応チェーン、対応トークン、処理の流れ、制約 |
| 開発者向けドキュメント | コントラクト、メッセージ形式、SDK、エラー時対応 |
| 監査レポート | 発見されたリスク、修正状況、対象バージョン |
| ステータスページ | 障害、メンテナンス、停止状況 |
| ガバナンス資料 | 管理者権限、アップグレード、パラメータ変更 |
| ブロックエクスプローラ | コントラクトアドレス、取引履歴、イベント |
| セキュリティ分析記事 | 過去事例、リスクの整理 |
| リスクフレームワーク | 見落としやすい観点の確認 |
たとえば、L2BEATのL2Bridge Risk Frameworkは、ブリッジを評価する際の観点として、asset bridgeの種類、verification mode、upgradability、permissioned actors、volume、liquidity、対応トークン・チェーンなどを整理しています。
参考: L2BEAT Forum: L2Bridge Risk Framework
また、Ethereum.orgのブリッジ資料は、ブリッジの種類やリスクを初学者が把握するうえで参考になります。
調査するときは、次のような順番で見ると迷いにくいです。
注意したいのは、まとめ記事やSNSだけで判断しないことです。
それらは入口として便利ですが、最終的には公式資料や一次情報で確認する必要があります。
9.8 利用者向けチェックリスト
ここで、利用者向けの簡単なチェックリストをまとめます。
実際にブリッジを利用する前には、少なくとも次のような点を確認するとよいです。
| チェック | 確認内容 |
|---|---|
| 公式URL | 公式サイト、公式Docs、公式X/GitHubなどからたどったURLか |
| ウォレット接続 | 正しいサイトに接続しているか |
| 送信元チェーン | 意図したチェーンを選んでいるか |
| 宛先チェーン | 受け取りたいチェーンを選んでいるか |
| トークン | コントラクトアドレスや資産種別を確認したか |
| ネイティブ/ラップド | 受け取る資産が何の表現か理解しているか |
| 数量 | 少額テストが必要な場面か |
| 手数料 | 送信元・宛先のガス代やブリッジ手数料を確認したか |
| 待ち時間 | 何分、何時間、何日かかる可能性があるか |
| Approve | 必要以上の権限を与えていないか |
| 失敗時対応 | claim、redeem、返金、サポートの有無を確認したか |
| 状態確認 | トランザクションIDやブリッジのstatusページを確認できるか |
このチェックリストは、すべてのリスクをなくすものではありません。
しかし、基本的な確認漏れを減らすには役立ちます。
9.9 開発者向けチェックリスト
次に、開発者向けのチェックリストです。
クロスチェーンアプリケーションやブリッジ連携機能を作る場合、次のような観点を確認したいです。
| チェック | 確認内容 |
|---|---|
| 送信元制限 | 想定したチェーン・コントラクトからのメッセージだけを受け入れるか |
| 宛先制限 | 想定した宛先コントラクトだけで処理されるか |
| message id | メッセージを一意に識別できるか |
| nonce管理 | 同じメッセージの二重実行を防げるか |
| replay対策 | 別チェーン・別環境でメッセージが再利用されないか |
| payload検証 | 型、長さ、範囲、action種別を確認しているか |
| エラー処理 | 宛先実行失敗時に資産や状態がどうなるか |
| ガス設計 | 宛先実行に必要なガスを考慮しているか |
| rate limit | 異常な大量実行を抑制できるか |
| emergency pause | 異常時に停止できるか |
| 権限管理 | 管理者、アップグレード、ミント権限を適切に管理しているか |
| 監視 | 異常なミント、出金、メッセージ量、失敗率を検知できるか |
| テスト | 正常系、異常系、重複、順序違い、失敗時をテストしているか |
| 監査 | 対象バージョン、修正状況、未対応リスクを確認しているか |
開発者にとって特に重要なのは、失敗する前提で設計すること です。
クロスチェーン処理では、送信元では成功したが宛先では失敗した、メッセージは届いたが実行できなかった、ガス不足で止まった、同じメッセージが再送された、といった状態が起こり得ます。
そのため、正常系だけでなく、失敗時の設計が重要です。
9.10 小さなコードでチェックリストを扱ってみる
最後に、チェックリストをデータとして扱う簡単なPythonコードを見てみます。
このコードは、実在ブリッジの安全性を判定するものではありません。
目的は、確認項目を整理し、未確認の項目を見える化する考え方を示すことです。
# このコードは、ブリッジ利用・開発前のチェックリストを整理するための学習用コードです。
# 実在ブリッジの安全性評価、投資判断、利用推奨を行うものではありません。
from dataclasses import dataclass
from typing import List
@dataclass
class ChecklistItem:
"""
ブリッジ確認項目を表すデータクラスです。
name:
確認項目名です。
category:
user, developer, research などの分類です。
checked:
確認済みかどうかです。
note:
確認内容やメモです。
"""
name: str
category: str
checked: bool
note: str
def find_unchecked_items(items: List[ChecklistItem]):
"""
未確認の項目だけを取り出します。
"""
return [item for item in items if not item.checked]
items = [
ChecklistItem(
name="公式URL",
category="user",
checked=True,
note="公式Docsからリンクを確認した。",
),
ChecklistItem(
name="送信元チェーン",
category="user",
checked=True,
note="Chain Aから送る想定で確認済み。",
),
ChecklistItem(
name="受け取る資産の種類",
category="user",
checked=False,
note="ネイティブ資産かラップド資産か未確認。",
),
ChecklistItem(
name="nonce管理",
category="developer",
checked=False,
note="二重実行防止の設計を確認する必要がある。",
),
ChecklistItem(
name="失敗時対応",
category="developer",
checked=False,
note="宛先実行失敗時の再試行・返金設計を確認する。",
),
]
unchecked = find_unchecked_items(items)
print("未確認の項目:")
for item in unchecked:
print(f"- [{item.category}] {item.name}: {item.note}")
実行結果のイメージは次のようになります。
未確認の項目:
- [user] 受け取る資産の種類: ネイティブ資産かラップド資産か未確認。
- [developer] nonce管理: 二重実行防止の設計を確認する必要がある。
- [developer] 失敗時対応: 宛先実行失敗時の再試行・返金設計を確認する。
このように、チェックリストをデータとして扱うと、未確認の項目が見えやすくなります。
実務では、これに加えて、リスクの重要度、担当者、確認日、参照URL、証跡、対応状況などを管理すると、より現実的なリスク管理に近づきます。
9.11 この章のまとめ
この章では、利用者・開発者・調査者の視点から、ブリッジを見るときの確認ポイントを整理しました。
ブリッジは便利ですが、利用前・開発前に確認すべきことが多い仕組みです。
公式URL、対応チェーン、対応トークン、資産種別、待ち時間、手数料、Approve、失敗時対応など、利用者側で確認できることもあります。
一方、開発者側では、送信元確認、nonce管理、replay対策、payload検証、失敗時対応、監視、権限管理などが重要になります。
この章で押さえたいポイントは、次の通りです。
- ブリッジを見るときは、何を送るのか、どこからどこへ送るのか、誰が検証するのかを確認する
- 利用者は、公式URL、チェーン、トークン、ネイティブ/ラップド、手数料、待ち時間、Approve、失敗時対応を確認する
- トークン名やシンボルだけで判断せず、コントラクトアドレスや資産の種類を見る
- L2ブリッジでは、方向によって待ち時間や確認方法が異なる場合がある
- 開発者は、送信元チェーン、送信元コントラクト、message id、nonce、payload、replay対策を確認する
- クロスチェーンアプリケーションでは、宛先実行失敗やガス不足など、失敗時の設計が重要である
- 調査するときは、公式Docs、監査レポート、ステータスページ、ガバナンス資料、リスクフレームワークを分けて見る
- チェックリスト化すると、未確認項目を見落としにくくなる
次の章では、ブリッジについてよくある誤解を整理します。
「資産がそのまま移動している」「公式なら完全に安全」「Trustlessなら何も信頼しなくてよい」「監査済みなら攻撃されない」といった見方を、仕組みと信頼モデルの観点からやわらかく修正していきます。
10. よくある誤解
この章では、ブロックチェーンブリッジについてよくある誤解を整理します。
ポイントは、ブリッジを「便利だから安全」「危険だから使えない」のように単純化せず、仕組み・信頼モデル・リスクを分けて見ること です。
ここまでの章では、ブリッジの基本的な仕組み、資産の表現、検証モデル、代表的なプロトコル、リスク、攻撃事例、確認ポイントを整理してきました。
最後に、ブリッジについてよくある誤解をまとめておきます。
ブリッジは便利な仕組みです。
異なるチェーンの間で資産やメッセージを扱えるようになるため、DeFi、L2、マルチチェーンアプリケーションでは重要な役割を持ちます。
一方で、便利さだけを見ると、裏側にある信頼モデルやリスクを見落としやすくなります。
逆に、過去の攻撃事例だけを見ると、「ブリッジはすべて危険」と極端に捉えてしまうかもしれません。
そこでこの章では、次のような誤解を一つずつ整理します。
| よくある誤解 | より正確な見方 |
|---|---|
| 資産がそのまま別チェーンへ移動している | 多くの場合、ロック・バーン・ミントなどで別チェーン側に対応する状態を作る |
| 公式ブリッジなら完全に安全 | 公式性は重要だが、設計・権限・運用・待ち時間などの確認は必要 |
| Trustlessなら何も信頼しなくてよい | 特定主体への信頼を減らす設計でも、実装や基盤チェーンへの信頼は残る |
| 監査済みなら攻撃されない | 監査は重要だが、未知のバグ、設定変更、運用ミスは残り得る |
| ブリッジ攻撃はチェーン本体の問題である | ブリッジ層、検証者、鍵管理、証明検証、設定が問題になる場合もある |
| 速くて安いブリッジほど優れている | 速度・手数料・安全性・流動性・失敗時対応を合わせて見る必要がある |
| ブリッジを通ると必ず追跡できなくなる | チェーンをまたぐと難しくなるが、必ず追跡不能とは限らない |
| トークン名が同じなら同じ資産である | コントラクトアドレス、発行元、裏付け、ブリッジ経路を確認する必要がある |
10.1 誤解1:資産がそのまま別チェーンへ移動している
まず、一番よくある誤解です。
ブリッジ画面では、「Ethereumから別チェーンへ送る」「Chain AからChain Bへ移動する」のように表示されることがあります。
この表現は直感的で分かりやすいです。
ただし、技術的には、資産そのものが物理的に別チェーンへ移動しているわけではありません。
第3章で見たように、多くの場合は次のような処理で実現されます。
たとえば、Lock and Mintでは、送信元チェーンで資産をロックし、宛先チェーンで対応するラップドトークンをミントします。
Burn and Mintでは、送信元チェーンで資産をバーンし、宛先チェーンで同量をミントします。
つまり、「移動」というよりも、送信元チェーンと宛先チェーンで対応する状態を作っている と見る方が正確です。
| 誤解 | より正確な見方 |
|---|---|
| トークンが橋を渡って移動する | 送信元でロック・バーンし、宛先で対応する表現を作ることが多い |
| 宛先のトークンは元資産そのもの | ラップド資産や別チェーン上の表現である場合がある |
| 送信元の処理が終わればすぐ完了 | 宛先側でのメッセージ検証や実行も必要 |
この誤解を避けるには、「資産がどこでロックされ、どこでミントされているのか」を見ることが大切です。
10.2 誤解2:公式ブリッジなら完全に安全
次の誤解は、公式ブリッジに関するものです。
公式ブリッジは重要です。
偽サイトや詐欺的なブリッジを避けるためにも、公式URLや公式ドキュメントから確認することはとても大切です。
しかし、公式ブリッジだからといって、すべてのリスクが消えるわけではありません。
たとえば、次のような点は引き続き確認が必要です。
| 確認項目 | なぜ必要か |
|---|---|
| 待ち時間 | L2からL1へ戻すときなど、時間がかかる場合がある |
| 対応トークン | すべてのトークンが対応しているとは限らない |
| ネイティブ/ラップド | 受け取る資産の性質が変わる場合がある |
| 失敗時対応 | claim、redeem、再送、サポートが必要になる場合がある |
| アップグレード権限 | 管理者権限やtimelockの有無を見る必要がある |
| 停止時対応 | メンテナンスや緊急停止時にどうなるかを確認する必要がある |
OptimismのStandard Bridgeのように、公式ドキュメントで待ち時間や方向ごとの違いが説明されている場合もあります。
参考: Optimism Docs: Using the Standard Bridge
公式であることは、確認すべき大切な入口です。
ただし、公式であることと、すべてのリスクがないことは同じではありません。
💡 豆知識
「公式」はとても重要な確認ポイントです。
ただし、公式サービスでも、待ち時間、対応資産、権限、停止時対応は確認する必要があります。
公式URLを確認したうえで、仕様も確認する、という二段階で考えると安全に近づきます。
10.3 誤解3:Trustlessなら何も信頼しなくてよい
ブリッジを調べていると、trustless という言葉が出てくることがあります。
この言葉は直訳すると「信頼がない」「信頼しない」のように見えるため、少し誤解しやすいです。
Ethereum.orgでは、ブリッジを trusted bridge と trustless bridge に分けて説明しています。
trusted bridgeは中央の主体やシステムに依存するもの、trustless bridgeはスマートコントラクトやアルゴリズムを用いて、追加の信頼仮定をできるだけ小さくするものとして説明されています。
参考: Ethereum.org: Introduction to blockchain bridges
ここで大切なのは、trustlessを 何も信頼しなくてよい と読まないことです。
より正確には、次のように考えると分かりやすいです。
| 言葉 | 誤解 | より正確な見方 |
|---|---|---|
| trusted | 危険なブリッジ | 特定の主体や検証者への信頼が大きい方式 |
| trustless | 完全に信頼不要 | 特定主体への信頼を減らし、コードや暗号学的検証に寄せる方式 |
| trust-minimized | 安全が保証されている | 信頼仮定を小さくしようとする設計だが、実装や運用の確認は必要 |
trustlessな設計でも、次のようなものへの信頼は残ります。
- 基盤チェーンの合意
- スマートコントラクト実装
- 暗号技術
- ライトクライアント実装
- アップグレード権限
- 監査後の変更管理
- UIやウォレットの安全性
つまり、trustlessは「信頼ゼロ」ではなく、何を信頼するかを変えている と見る方が自然です。
10.4 誤解4:監査済みなら攻撃されない
次の誤解は、監査済みという言葉に関するものです。
スマートコントラクト監査はとても重要です。
第三者がコードをレビューし、脆弱性や設計上の問題を見つけることは、ブリッジの安全性を高めるうえで大切です。
ただし、監査済みだからといって、攻撃されないことを保証するわけではありません。
理由はいくつかあります。
| 理由 | 内容 |
|---|---|
| 監査対象が限定される | すべてのコード、設定、運用が対象とは限らない |
| 監査後に変更される | アップグレードや設定変更で状態が変わる |
| 未知の脆弱性が残る | 監査で全バグを見つけられるとは限らない |
| 運用ミスが起こり得る | 鍵管理、権限設定、監視不足などは別問題 |
| 外部依存が変化する | 他コントラクト、オラクル、チェーン仕様が変わる場合がある |
監査済みという情報を見るときは、次の点を確認するとよいです。
いつ監査されたのか
どのバージョンが監査対象なのか
どの範囲が対象だったのか
発見事項は修正済みなのか
監査後に変更はあったのか
現在デプロイされているコントラクトと一致しているのか
これは、健康診断に少し似ています。
健康診断を受けることは大切ですが、過去に健康診断を受けたからといって、今後ずっと健康が保証されるわけではありません。
ブリッジでも、監査は重要な防御層ですが、それだけで十分とは言えません。
10.5 誤解5:ブリッジ攻撃はチェーン本体の問題である
ブリッジ攻撃のニュースを見ると、「このチェーンが攻撃された」と受け取ってしまうことがあります。
しかし、ブリッジ関連のインシデントでは、チェーン本体の合意や基盤そのものが破られたのではなく、ブリッジ層や外部検証、鍵管理、証明検証、設定変更が問題になっている場合があります。
| 影響を受ける場所 | 例 |
|---|---|
| チェーン本体 | 合意アルゴリズム、ブロック生成、基盤プロトコル |
| ブリッジ層 | ロック、ミント、メッセージ検証、証明検証 |
| 外部検証者 | ガーディアン、バリデータ、署名者セット |
| 運用 | 鍵管理、アップグレード、監視、緊急停止 |
| アプリ層 | DeFi、ラップド資産、流動性プール |
もちろん、利用者から見ると「そのチェーンで資産が動いた」「そのチェーン上のトークンが影響を受けた」ように見えるかもしれません。
しかし、原因を整理するときは、チェーン本体とブリッジ層を分けて見ることが大切です。
この分け方をすると、再発防止策も見えやすくなります。
チェーン本体の問題なのか。
ブリッジコントラクトの問題なのか。
署名者鍵の問題なのか。
設定やアップグレードの問題なのか。
ユーザー操作の問題なのか。
原因が違えば、必要な対策も変わります。
10.6 誤解6:速くて安いブリッジほど優れている
ブリッジを使うとき、速さや手数料はとても気になります。
待ち時間が短い。
手数料が安い。
UIが分かりやすい。
これらは重要です。
しかし、速くて安いからといって、必ずしも総合的に優れているとは限りません。
ブリッジでは、速度、コスト、安全性、流動性、失敗時対応がトレードオフになる場合があります。
| 観点 | 見るポイント |
|---|---|
| 速度 | finality待ち、チャレンジ期間、リレイヤー処理 |
| 手数料 | ガス代、ブリッジ手数料、LP手数料 |
| 安全性 | 検証モデル、署名者、証明検証、監査 |
| 流動性 | 宛先側のプール残高、rate limit |
| 失敗時対応 | claim、再送、返金、サポート |
| 対応資産 | ネイティブ資産かラップド資産か |
たとえば、流動性ネットワーク型では、ユーザーが速く受け取れる場合があります。
一方で、LP、フィラー、手数料、精算、流動性不足といった観点も見る必要があります。
L2ブリッジでは、L1からL2へ入るときは比較的早くても、L2からL1へ戻すときにチャレンジ期間が必要な場合があります。
つまり、ブリッジを比較するときは、単に「何分で届くか」「いくら安いか」だけでなく、なぜその速度・手数料になっているのか を見ることが大切です。
10.7 誤解7:ブリッジを通ると必ず追跡できなくなる
ブリッジはチェーンをまたぐため、取引の追跡を難しくする場合があります。
しかし、「ブリッジを通れば必ず追跡できなくなる」と考えるのは正確ではありません。
ブロックチェーン上の取引は、多くの場合、公開台帳に記録されています。
ブリッジでは、送信元チェーンのロック・バーンイベント、宛先チェーンのミント・アンロックイベント、メッセージID、VAA、attestation、sequence、nonceなどが手がかりになる場合があります。
| 追跡の手がかり | 例 |
|---|---|
| 送信元チェーンのイベント | lock、burn、depositなど |
| 宛先チェーンのイベント | mint、release、claimなど |
| メッセージID | nonce、sequence、hashなど |
| 時間情報 | 送信元・宛先の発生時刻 |
| 金額情報 | 数量、手数料、decimals |
| アドレス情報 | 送信元、宛先、ブリッジコントラクト |
| プロトコル固有データ | VAA、attestation、packet、message idなど |
もちろん、チェーンをまたぐことで調査は難しくなる場合があります。
複数チェーンのエクスプローラを確認する必要があり、トークンの表現も変わるかもしれません。
しかし、必ず追跡不能になるとは限りません。
この点は、暗号資産AMLや取引解析の観点でも重要です。
ブリッジは追跡を難しくする要素になり得ますが、同時に、ブリッジ固有のイベントやメッセージが手がかりになる場合もあります。
10.8 誤解8:トークン名が同じなら同じ資産である
次の誤解は、トークン名やシンボルに関するものです。
同じ USDC、ETH、BTC、TEST のように表示されていても、チェーンやコントラクトアドレスが違えば、実際には別の資産表現である場合があります。
| 見た目 | 注意点 |
|---|---|
| 同じトークン名 | 別コントラクトの可能性がある |
| 同じシンボル | 偽トークンやラップド資産の可能性がある |
| 同じロゴ | UI上の表示だけでは判断できない |
| 同じ価格に見える | 流動性や裏付けが違う可能性がある |
| 同じようにDeFiで使える | 担保価値や対応プロトコルが違う可能性がある |
確認するときは、次の点を見る必要があります。
- コントラクトアドレス
- 発行元
- 対応チェーン
- ブリッジ経路
- ネイティブ資産かラップド資産か
- どのプロトコルで扱えるか
- 公式資料で案内されている資産か
トークン名だけで判断すると、誤った資産を受け取ったり、流動性の低い資産を持ってしまったりする可能性があります。
ブリッジでは、同じ名前に見える資産でも、裏側の信頼モデルが違う場合がある と覚えておくとよいです。
10.9 誤解を整理する小さなコード
ここで、よくある誤解を「誤解」「より正確な見方」「確認ポイント」に分けて整理する小さなPythonコードを見てみます。
このコードは学習用です。
実在ブリッジの安全性を評価したり、利用判断を行ったりするものではありません。
目的は、誤解を見つけたときに、どの確認ポイントへ戻ればよいかを整理することです。
# このコードは、ブリッジに関する誤解を整理するための学習用コードです。
# 実在するブリッジの安全性評価や利用推奨を行うものではありません。
from dataclasses import dataclass
from typing import List
@dataclass
class Misconception:
"""
ブリッジに関する誤解を整理するためのデータクラスです。
wrong_view:
よくある誤解です。
better_view:
より正確な見方です。
check_points:
その誤解を避けるために確認したいポイントです。
"""
wrong_view: str
better_view: str
check_points: List[str]
misconceptions = [
Misconception(
wrong_view="資産がそのまま別チェーンへ移動している",
better_view="多くの場合、送信元でロック・バーンし、宛先で対応する状態を作っている",
check_points=[
"Lock and Mintか、Burn and Mintか",
"ネイティブ資産かラップド資産か",
"ロック量と発行量の整合性はどう確認されるか",
],
),
Misconception(
wrong_view="Trustlessなら何も信頼しなくてよい",
better_view="特定主体への信頼を減らす設計でも、実装や基盤チェーンへの信頼は残る",
check_points=[
"何をオンチェーンで検証しているか",
"アップグレード権限は誰にあるか",
"ライトクライアントやコントラクト実装はどう管理されるか",
],
),
Misconception(
wrong_view="監査済みなら攻撃されない",
better_view="監査は重要だが、未知のバグ、設定変更、運用ミスは残り得る",
check_points=[
"監査対象バージョンは何か",
"監査後に変更はあったか",
"未修正の指摘事項はないか",
],
),
]
def print_misconceptions(items: List[Misconception]):
"""
誤解と確認ポイントを一覧表示します。
"""
for item in items:
print(f"誤解: {item.wrong_view}")
print(f"より正確には: {item.better_view}")
print("確認ポイント:")
for point in item.check_points:
print(f" - {point}")
print()
print_misconceptions(misconceptions)
このコードでは、誤解をただ否定するのではなく、確認ポイントに変換しています。
たとえば、「Trustlessなら何も信頼しなくてよい」という誤解は、次の確認に変えられます。
何をオンチェーンで検証しているか
アップグレード権限は誰にあるか
ライトクライアントやコントラクト実装はどう管理されるか
このように、誤解を確認ポイントへ変換すると、ブリッジの理解がかなり実務的になります。
10.10 誤解を避けるための見方
最後に、ブリッジの誤解を避けるための見方をまとめます。
ブリッジを見るときは、次の順番で考えると整理しやすいです。
この流れは、記事全体で繰り返してきた考え方です。
- 何を渡しているのか
- 資産はどう表現されているのか
- 誰が送信元チェーンの出来事を検証しているのか
- どこに信頼仮定があるのか
- 失敗したとき何が起こるのか
ブリッジを理解するときは、この5つを何度も確認することが大切です。
「便利そう」「有名そう」「安全そう」「危険そう」といった印象だけで判断するのではなく、仕組みのどこを見ているのかを分けて考えると、誤解を減らせます。
10.11 この章のまとめ
この章では、ブロックチェーンブリッジについてよくある誤解を整理しました。
ブリッジは、異なるチェーンをつなぐ便利な仕組みです。
しかし、便利な見た目の裏側には、ロック、バーン、ミント、メッセージ検証、署名、証明、流動性、ガバナンス、UXなど、さまざまな要素があります。
この章で押さえたいポイントは、次の通りです。
- 資産が物理的に別チェーンへ移動しているわけではない
- 公式ブリッジでも、待ち時間、対応資産、権限、失敗時対応は確認する必要がある
- trustlessは「何も信頼しなくてよい」という意味ではない
- 監査済みであっても、未知のバグ、設定変更、運用ミスは残り得る
- ブリッジ攻撃は、チェーン本体ではなくブリッジ層や鍵管理、証明検証が問題になる場合もある
- 速くて安いブリッジが常に優れているとは限らない
- ブリッジを通っても、必ず追跡不能になるわけではない
- トークン名やシンボルが同じでも、同じ資産とは限らない
- 誤解を避けるには、何を送るのか、誰が検証するのか、どこに信頼仮定があるのかを見ることが大切である
次の章では、記事全体をまとめます。
身近な残高移動から始めた話を振り返りながら、ブリッジを 便利さ・仕組み・信頼モデル・リスクのバランス で理解する視点に整理します。
11. まとめ
最後に、本記事で整理したブロックチェーンブリッジの全体像を振り返ります。
ブリッジを用語として覚えるのではなく、別々の台帳をどうつなぎ、誰が何を検証し、どこに信頼仮定があるのかという視点で整理します。
ここまで、ブロックチェーンブリッジについて、身近な残高移動から順番に整理してきました。
最初は、銀行振込、ポイント交換、両替、電子マネー、ゲーム内アイテムのような例から考えました。
これらに共通していたのは、価値の記録が別々の仕組みに分かれている場合、そのまま別の場所で使えるわけではない ということです。
ブロックチェーンでも同じです。
Ethereum、Solana、Cosmos系チェーンのようなL1や、各種L2は、それぞれ別の台帳、別のルール、別の状態を持っています。
そのため、あるチェーン上の資産やメッセージを別のチェーンで扱えるようにするには、間をつなぐ仕組みが必要になります。
それが、ブロックチェーンブリッジです。
11.1 本記事で整理したこと
本記事では、ブリッジを「異なるチェーンの間で、資産やメッセージを扱えるようにする仕組み」として整理しました。
ただし、ブリッジを単なる「送金機能」として見るのではなく、次のような状態変更の組み合わせとして見てきました。
- 送信元チェーンで資産をロックする
- 送信元チェーンで資産をバーンする
- 送信元チェーンで発生したイベントを観測する
- メッセージや証明を宛先チェーンへ伝える
- 宛先チェーンでメッセージや証明を検証する
- 宛先チェーンでトークンをミントする
- 宛先チェーン側の流動性から支払う
- 別チェーンのスマートコントラクトを実行する
図にすると、次のような流れです。
資産の表現方法としては、次のような方式を扱いました。
| 方式 | ざっくりした説明 | 見るポイント |
|---|---|---|
| Lock and Mint | 送信元で資産をロックし、宛先で対応するトークンをミントする | ロック量とミント量の整合性 |
| Burn and Mint | 送信元で資産をバーンし、宛先で同量をミントする | バーン証明とミント権限 |
| Lock and Release | 送信元で資産をロックし、宛先側の既存資産をリリースする | 宛先側の流動性 |
| Liquidity Network | LPやフィラーが先に支払い、あとで精算する | 流動性、手数料、精算 |
この整理から分かるのは、トークンが物理的に別チェーンへ移動しているわけではない、ということです。
多くの場合、送信元チェーンで使えない状態にし、宛先チェーンで対応する表現を作ります。
11.2 ブリッジを便利さとリスクの二択にしない
ブリッジは便利です。
異なるチェーン間で資産を動かしたり、メッセージを渡したりできるため、DeFi、L2、マルチチェーンアプリケーションでは重要な役割を持ちます。
一方で、ブリッジは便利なだけではありません。
別々の台帳をつなぐということは、そこに新しい信頼点、検証点、失敗点が生まれるということでもあります。
本記事では、ブリッジのリスクを次のように整理しました。
| リスク分類 | 内容 |
|---|---|
| スマートコントラクトリスク | ロック、ミント、バーン、検証、nonce管理の不備 |
| 署名者・検証者リスク | 秘密鍵侵害、閾値設計、検証者セットの集中 |
| 流動性・会計リスク | ロック量と発行量の不一致、流動性不足、decimals差 |
| finality・リプレイ・順序リスク | 巻き戻り、二重実行、順序不整合 |
| アップグレード・ガバナンスリスク | 管理者権限、即時アップグレード、設定ミス |
| ユーザーUXリスク | 偽サイト、誤チェーン、無制限Approve、待ち時間の誤解 |
過去のインシデントからも、ブリッジの問題は一種類ではないことが分かります。
- Wormholeの事例からは、署名・検証ロジックの重要性が見えました
- Ronin Bridgeの事例からは、バリデータ鍵管理と閾値設計の重要性が見えました
- Nomadの事例からは、アップグレードや設定変更の重要性が見えました
- BSC Token Hubの事例からは、証明検証ロジックの重要性が見えました
これらは、攻撃手順ではなく、設計・運用・監視上の学びとして見ることが大切です。
ブリッジを「便利だから安全」「過去に攻撃されたから全部危険」と二択で見るのではなく、どの仕組みでつながっていて、どこに信頼仮定があり、何が壊れるとどのような影響が出るのかを分けて見る必要があります。
11.3 ブリッジを学ぶときに意識したいこと
この記事全体を通して、何度も似た問いが出てきました。
最後に、それを5つにまとめます。
| 問い | 具体的に見ること |
|---|---|
| 何を渡しているのか | トークン、メッセージ、任意データ、コントラクト呼び出し |
| 資産はどう表現されているのか | Lock and Mint、Burn and Mint、ラップド資産、流動性 |
| 誰が検証しているのか | ライトクライアント、ガーディアン、発行体、Watcher、LP |
| どこに信頼仮定があるのか | 鍵管理、署名閾値、権限、実装、監視、発行体 |
| 失敗したとき何が起こるのか | 遅延、claim、返金、停止、二重実行、不整合 |
ブリッジを見たときに、この5つを順番に確認できるようになると、表面的な説明だけでなく、仕組みの奥にある設計思想やリスクも見えやすくなります。
また、利用者・開発者の立場では、次のような確認も重要です。
| 立場 | 確認したいこと |
|---|---|
| 利用者 | 公式URL、送信元・宛先チェーン、トークン、ネイティブ/ラップド、手数料、待ち時間、Approve、失敗時対応 |
| 開発者 | 送信元チェーン、送信元コントラクト、message id、nonce、payload、replay対策、監視、権限管理 |
| 調査者 | 方式、信頼モデル、検証者、権限、過去事例、公式資料、監査レポート |
「便利そう」「有名そう」「安全そう」「危険そう」といった印象だけで判断するのではなく、確認観点を持つことが大切です。
11.4 今後深掘りしたいテーマ
ブリッジは、他のブロックチェーン関連テーマともつながっています。
今後さらに学ぶなら、次のようなテーマに広げると理解しやすくなります。
| 次に学ぶテーマ | ブリッジとの関係 |
|---|---|
| Layer 2とRollup | L1/L2ブリッジ、withdrawal、challenge period |
| クロスチェーンメッセージング | トークン以外のデータや命令の伝達 |
| ステーブルコイン | CCTPのようなBurn and Mint、発行体アテステーション |
| ブロックチェーンの匿名性と追跡可能性 | ブリッジをまたいだ資金移動の追跡 |
| 暗号資産AML | ブリッジ利用を含む取引解析 |
| スマートコントラクトセキュリティ | ブリッジコントラクト、検証ロジック、権限管理 |
| 鍵管理 | ガーディアン、バリデータ、管理者権限 |
特に、ブリッジは暗号資産AMLやオンチェーン分析とも関係します。
チェーンをまたぐと取引の追跡は難しくなる場合がありますが、ブリッジ固有のイベント、メッセージID、バーン・ミント、ロック・アンロックなどが手がかりになる場合もあります。
そのため、ブリッジを学ぶことは、単にDeFiやマルチチェーン利用のためだけでなく、セキュリティや取引解析を考えるうえでも役立ちます。
11.5 最後に
ブロックチェーンブリッジは、マルチチェーンの世界を支える重要な仕組みです。
異なるチェーンの資産やメッセージをつなげることで、ユーザーは複数のチェーンをまたいでアプリケーションを使えるようになります。
開発者は、複数チェーンにまたがるアプリケーションを設計できるようになります。
エコシステム全体としても、チェーンごとの強みを組み合わせやすくなります。
一方で、ブリッジは「使えるようになるもの」が増えるぶん、確認すべきことも増えます。
便利さだけを見ると、検証モデルや信頼仮定を見落としやすくなります。
反対に、過去のインシデントだけを見ると、ブリッジ全体を必要以上に怖がってしまうかもしれません。
だからこそ、ブリッジを理解するときは、次の姿勢が大切です。
便利さだけを見ない
危険性だけを見ない
方式名だけで判断しない
公式・監査済みという言葉だけで安心しない
誰が何を検証しているのかを見る
失敗したとき何が起こるのかを見る
身近な残高移動から考えると、ブリッジは決して突然出てきた特殊な仕組みではありません。
別々の記録をどう対応させるか。
片方で減らし、もう片方で増やすとき、つじつまをどう合わせるか。
その出来事を誰が正しいと確認するか。
このような問題の延長に、ブロックチェーンブリッジがあります。
ブリッジを理解するコツは、「橋」という言葉に引っ張られすぎないことです。
実際には、別々の台帳の間で、出来事・証明・署名・状態変更を対応させています。
「どこからどこへ渡ったか」だけでなく、「誰が何を確認して渡したことにしているのか」を見ると、ブリッジの理解が一段深くなります。
ここまで読んでくださり、ありがとうございました。
この記事が、ブロックチェーンブリッジを学び始めるためのきっかけになればうれしいです。