L1からL2への移行手順|「EVM互換」でも本番で崩れる6つの違いと切り戻し
約14分で読めます
約14分
目次(タップで折りたたみ)
Ethereum L1で動いているアプリを、手数料の安いL2へ移す。候補のL2は「EVM互換」とうたっていて、テストネットでも問題なく動いた。ところが本番に切り替えると、崩れます。費用が見積もりと合わない。送金先のアドレスが違っていた。L1とL2の間の処理が、片側だけ成功したまま止まっている。
「EVM互換」という表示だけで、同じ動きをすると考えるのは危険です。移行では、コードだけでなく次のものを確かめます。
- 実行の違い、アドレス
- 残高などの状態、資産
- L1とL2の間のメッセージ
確かめた結果と、切り替えの条件を満たしたのを見てから、書き込み先を移します。
以下では、ロールアップ型のL2へ移す計画を、互換性の確認、状態の移し方、段階的な切り替え、本番前の試験、監視、切り戻しの順に組み立てます。どのL2が優れているかではなく、候補ごとの違いを同じ証拠で比べる方法です。L2そのものの全体像はL2(Layer 2)完全マップ2026で整理しています。
この記事で使う言葉
- ロールアップ(L2):取引をまとめて処理し、データをL1に預ける別の処理の場
- シーケンサー:L2で取引を受け付け、順番を決める役
- 公式ブリッジ:L1とL2の間で資産を移す正式な通り道
- 強制取引:シーケンサーを通さず、L1から直接L2へ取引を入れる手段
- opcode/precompile:EVMの命令/あらかじめ組み込まれた計算機能
「EVM互換」を6つに分けて確かめる
「互換」の一語で移せるかを判定すると、冒頭の例のように、本番で費用・アドレス・非同期の処理が崩れます。最低でも次の6つを台帳にします。各項目には「同一」「差分あり」「不明」の判定と、根拠のURL、検証のコード、責任者を付けます。
| 互換性 | 確認対象 | 見落とした場合 |
|---|---|---|
| 実行 | opcode、precompile、ガス計算、ブロック情報、コンパイラ、プロキシ | 特定の関数だけrevertする、想定外のガス不足 |
| アドレス | CREATE/CREATE2、デプロイ用アカウントのnonce、外部の許可リスト | 別アドレスへ送金、署名ドメインや権限参照の破損 |
| 状態 | 残高、所有者、ロール、nonce、ポジション、処理中の操作、履歴 | 二重計上、取りこぼし、再実行 |
| 資産 | 公式ブリッジ(canonical bridge)、トークンの表現、decimals、発行・焼却の権限、流動性 | 異なるトークンを同一視、資産のロック |
| 通信 | 入金、出金、確定性(finality)、再送・再生、順序、失敗時の補償 | 片側だけ成功、二重実行、長時間の保留 |
| 運用 | シーケンサー、RPC、強制取引(forced transaction)、アップグレード、監視、鍵、エクスプローラー | 停止時に状態確認も退出もできない |
それぞれの合格の証拠は、後半の「実装する人向けの詳細」にまとめています。
Optimistic rollupはEVM互換で、既存のツールを使いやすい方式です。一方で、L1とL2の資産の移動は、ブリッジのコントラクトと非同期のメッセージを通ります。Ethereum.orgのOptimistic rollup解説も、入金ではL1側の資産をロックし、L2側で対応する資産を発行する構造だと説明しています。シーケンサーを通らない送信の道も説明しています。「コントラクトが動く」と「業務全体が同じように動く」は、別の合格条件です。
何をL2へ移し、何をL1に残すか
L2と相性がよいのは、頻繁な注文、ゲームの操作、少額の決済など、安く何度も処理したいものです。一方で、次のものまで無条件に移すと、障害のときに立て直す道を失います。
- L2が止まっても必要な、退出する権利
- 最終的な決済の根拠
- L2から参照される発行の権限
同じ画面の中にも、L2に向く処理と、L1に残すべき権限が混ざることがあります。そのため移す範囲は、画面の単位では決めません。どのシステムの記録を正とするか(状態の正本)と、失敗したときの責任で分けます。
置き場所の候補と判断の基準は、次のとおりです。
| 機能・状態 | 置き場所の候補 | 判断基準 |
|---|---|---|
| 高頻度の業務処理 | L2 | 遅延、処理量、手数料の目標をL2が満たすか |
| 資産の発行・最終保全 | L1または明示したL2 | ブリッジ、アップグレード、退出の信頼の前提を利用者へ説明できるか |
| 緊急停止・アップグレード権限 | 責任主体ごとに分離 | L2の障害中にも実行でき、単一の鍵に集中しないか |
| 検索・分析用データ | オフチェーンのインデクサー | 作り直しができ、正本と誤認されないか |
| L1との連携 | 非同期のメッセージ処理 | 重複、順序の逆転、期限切れ、再送を状態機械で扱えるか |
「全部L2」か「全部L1」かの二択にする必要はありません。ただし、同じ残高や権限を両方で書き換えられる期間は短くします。どちらが正本かは、区切りの期間(epoch)か切り替えのブロックで、1つに決めます。
L1の古いコントラクトを止められない場合は、注意が要ります。画面を切り替えるだけでは、古い道から書き込みが続くからです。古い状態を凍結するか、両方の更新を調整する設計が必要です。
移行は5つのステップで少しずつ進める
- 基準になる状態を確定する:対象のコントラクト、プロキシの実装、code hash、chain ID、ブロック番号とhash、残高・ロール・処理中の操作を保存します。ブロック番号だけでは、チェーンの巻き戻り(再編)の後に同じ状態を特定できません。
- L2に再現する:コントラクト、設定、権限をデプロイし、スナップショットを決まった手順で取り込みます。分けた塊ごとに件数・範囲・hashを付け、途中から再開しても二重に反映しないようにします。
- 読み取りを並行で突き合わせる(shadow read):利用者への応答はL1のまま返します。同じ問い合わせをL2にも流し、結果の違いを記録します。時刻やブロックに依存する値は、比べる前にそろえます。
- 書き込みを限定して始める(canary write):社内のアカウント、少額、限られた機能から、L2への書き込みを始めます。成功率だけでなく、event、インデクサー、会計、L1との連携、問い合わせ対応まで追います。
- 切り替えて、様子を見る期間を終える:事前に決めたサービス目標(SLO)と、常に成り立つべき条件(不変条件)を満たしたら、対象を広げます。古いL1の道はすぐには消しません。立て直しに必要な期間だけ、読み取りと緊急操作を残します。廃止の条件も決めておきます。
各ステップの判定は、1つの記録(移行マニフェスト)にまとめます。例は後半に載せています。
スナップショットのブロックを決めた後もL1への書き込みを許すなら、選び方は2つです。その差分を記録(journal)としてL2へ適用するか、短い書き込み停止の時間を設けるか。止まる時間をゼロにしたいなら、その代わりに実装の費用がかかります。二重書き込みの順番、片側だけの失敗、再送、埋め合わせの処理です。
コントラクトと状態は、別々に確かめる
同じSolidityのソースがコンパイルできても、L2の上で同じように動くとは限りません。コンパイルできるのは、入り口にすぎません。コンパイラ、最適化の設定、ライブラリのアドレスを固定してbytecodeを再現し、L1とL2で関数ごとの結果を比べます。確かめ方の細部は後半にまとめています。
移し方にも2通りあります。Ethereum.orgのコントラクトのアップグレード解説が示すように、古いインスタンスから新しいインスタンスへ状態を移す方式と、プロキシの中身(ロジック)を差し替える方式です。責任も、失敗の条件も違います。
L2どうしでも、互換の範囲は同じではありません。たとえばZKsyncのEVM Bytecode Interpreterは、標準のEVM bytecodeと、普段使うFoundry・Hardhatを使えます。一方で、公式資料は違いをはっきり書いています(概要、Ethereumとの差分)。
- 取引に署名するガスの値は、EVMではなくEraVMのガスとして扱われる。そのため、事前に署名しておいた取引が通らない場合がある
CALLCODE・SELFDESTRUCT・BLOBHASH・BLOBBASEFEEが使えない- RIPEMD-160やblake2fなど、一部のprecompileが使えない
- EVMとEraVMのコントラクトの間の
DELEGATECALLがrevertする
デバッグの手段の違いも含め、候補のL2の最新版で実際に動かして確かめます。使うopcode、precompile、factory、署名済みの取引、ガスの上限です。
状態の突き合わせは、行数が一致するだけでは足りません。少なくとも次のものを、それぞれ独立に計算し直します。
- 総供給量、利用者ごとの残高、所有権、ロールの集合
- ポジションの合計、処理が終わっていないメッセージ
- 会計上の総資産・総負債
巨大な状態は、全件を出力したhashだけで済ませません。検査し直せる塊ごとのrootと、例外の一覧を残します。個人情報や業務上の秘密を、そのままチェーン上へ写してはいけません。必要性と公開の範囲を見直します。
L1とL2の間のメッセージを、普通の関数呼び出しとして扱わない
L1とL2の通信では、送る側の取引が成功したことと、受け取る側で実行が成功したことは、同時には起きません。そこで、メッセージごとに状態を記録します。同じメッセージが二度届いても結果が増えないようにし、送った取引のhashだけで完了とはしません。受け取る側のeventと、業務上の状態まで突き合わせます。状態の移り方は後半にまとめています。
出金には待ち時間があります。Optimistic rollupからL1への通常の出金は、不正の証明(fault proof)のための待機が関わり、最終化の条件もL2ごとに違います。
高速ブリッジや流動性の提供者を使えば、利用者の待ち時間は短くできます。ただし、公式ブリッジでの決済とは別に、流動性と取引相手のリスクが加わります。入出金のサービス目標は、次の4つに分けて表示・監視します。
- 画面で受け付けた
- L2で実行した
- L1で最終化した
- 使える残高へ反映した
利用者への見せ方はL2出金の待ち時間とUX設計で詳しく扱っています。
障害の試験では、RPCのタイムアウトだけでは足りません。シーケンサーの停止、L1の混雑、メッセージの重複・順番の逆転・期限切れ、L1の再編、中継者(relayer)の停止も起こします。
Ethereum Foundationは2026年3月23日のL1とL2の関係に関する記事で、「walkaway test」を示しています。悪意ある運営者や、セキュリティカウンシル(緊急時に権限を持つ委員会)に障害があっても、利用者が安全にL1へ退出できるか、という試験です。信頼をできるだけ小さくする方向のL2に、これを求めています。
採用する候補について、普段の画面が使えない状態から必要なデータを取り、L1経由の強制操作を実際にできるかを練習します。シーケンサーが止まったときの縮退と強制取引の待機条件はシーケンサー停止時のサービス継続設計、データ可用性の障害時に状態を作り直して退出する条件はロールアップのデータ可用性障害で扱っています。
切り替えてよいかを、何で判定するか
「全テスト成功」だけでは、テストに書かなかった会計上の違いを見つけられません。移行の前に、常に成り立つべき条件(不変条件)と、許せる差を、業務の責任者と合意しておきます。
- L1で凍結した総供給量と、L2へ割り当てた残高・未移行の残高・焼却済みの残高の合計が一致する。
- 各メッセージは業務上の効果を最大1回だけ生み、失敗中のメッセージを一覧にできる。
- 管理ロール、アップグレード権限、一時停止(pause)の権限を持つ主体とタイムロックが、デプロイの記録(manifest)と一致する。
- 代表的な取引のp50、p95、p99の費用と確定までの時間が目標内で、混雑時の上限を超えない。
- RPCかシーケンサーが止まったとき、誤って「成功」と表示せず、復旧後に安全に追いつける。
費用にも注意が要ります。L2では、実行の費用と、L1へデータを公開する費用が、別々の理由で動きます。そのため、L1のガス価格を一定の比率で割っただけの見積もりは使えません。
費用の試験は、平均値ではなく、代表的な操作ごとに行います。calldataの量、ストレージへの書き込み、コントラクトのデプロイ、L1データ手数料(L1 data fee)を含めます。費用のモデルと流量の制限は、本番に近い取引の分布で測ります。移行後の費用の分け方と監視はL2取引コストの可視化と予算管理を参照してください。
切り戻せる範囲を、切り替えの前に決める
画面や接続先は元に戻せても、L2で一度確定した取引は消せません。だから「切り戻す」と言っても、中身は3種類に分かれます。
- 道を戻す:L2への新しい書き込みを止め、通信をL1か、安全な読み取り専用の状態へ戻す。
- 状態を埋め合わせる:切り替え後にL2で成立した操作を記録から集計し、合意したルールでL1か次のL2へ反映する。取引を消すのではありません。
- 資産を引き揚げる:公式ブリッジか強制退出の道を使い、待ち時間とガスを含めて利用者の資産を取り戻す。
始める前に、手順書にしておくことがあります。誰が停止を宣言するか。どの鍵でどの機能を止めるか。処理中のメッセージをどう扱うか。利用者へ何を知らせるか。
再開するのは、原因と影響の範囲が分かり、L1とL2の状態の突き合わせが済み、再発防止策が入ってからです。同じ障害を隠すための再起動はしません。いきなり全開にせず、少しずつ戻します。運用設計の詳細はスマートコントラクト本番運用で整理しています。
本番切り替え前の受入チェックリスト
- 候補L2の公式差分表を、使うopcode、precompile、開発ツール、ガス、アドレス生成へ対応付けた。
- 移行元・移行先のchain ID、コントラクトアドレス、code hash、ブロック番号・hash、設定、ロールをマニフェストへ保存した。
- 同じ略称やチェーンの表示名だけで資産を識別せず、chain IDとコントラクトアドレスで識別している。
- スナップショット、差分の記録、取込スクリプトが冪等で、中断後の再開と件数・rootの照合ができる。
- 読み取りの並行照合と書き込みの限定開始で、機能、event、インデクサー、会計、サポート対応を確認した。
- 入金・出金の重複、遅延、失敗、再送、再編を試験した。
- シーケンサー、RPC、中継者、インデクサー、Oracleの停止を検知し、代替経路または安全な停止を実行した。
- 切替・停止・補償・再開の権限者と二者承認、連絡先、証拠の保管先を決めた。
- 旧L1経路の読み取り、書き込み停止、廃止日時と利用者への案内を決めた。
- 本番と同等の負荷・資産上限で不変条件を監視し、観察期間を通過した。
移行を見送るのは、どんなときか
移行しない条件も、先に決めておきます。次のような場合は、L1での最適化や、別のL2と比べます。
- 必要なopcodeやprecompileに対応していない
- 強制退出を運用できない
- 流動性が分かれてしまい、事業の要件を満たさない
- 既存の連携先が、チェーンを見分けられない
- 管理権限の信頼の前提を受け入れられない
手数料が安いというだけで、立て直せない移行を正当化しません。
実装する人向けの詳細
ここからは、移行の仕組みを実際に作る設計者向けに、合格の証拠、マニフェスト、確かめ方の細部をまとめます。
互換性ごとの合格の証拠
- 実行:同じテストベクトルで戻り値・event・ストレージの差分が許容内
- アドレス:予定アドレスと実際のデプロイ先、参照設定の一致
- 状態:基準ブロックのスナップショットとL2取込後の集計・Merkle root(データ全体から計算する要約値)の照合
- 資産:L1の預け入れ残高とL2の供給量をメッセージ単位で照合
- 通信:重複・遅延・再編・失敗を注入した端から端までの試験
- 運用:障害演習と承認済みの手順書、代替経路の実行記録
移行マニフェストの例
関門ごとの判定を1つの記録にまとめる例です。
{
"migration_id": "l1-l2-2026-01",
"source": {
"chain_id": 1,
"block_number": 0,
"block_hash": "0x..."
},
"target": {
"chain_id": 0,
"deploy_manifest_hash": "0x..."
},
"state_root": "0x...",
"counts": {
"accounts": 0,
"positions": 0,
"pending_msgs": 0
},
"gates": {
"execution": "PASS",
"state": "PASS",
"operations": "PENDING"
}
}
コントラクトの比べ方
L1とL2で、関数ごとの戻り値、revert、event、ストレージのスロットを比べます。プロキシを使う場合は、実装コントラクトだけでなく、管理者、beacon、初期化済みフラグ、ストレージの配置も対象です。
メッセージの状態
メッセージIDごとに CREATED → RELAYABLE → RELAYED、または FAILED → RETRY/REFUND の状態を保存し、同じメッセージが二度届いても結果が増えない冪等性を持たせます。
XTELAができること
XTELAは、L1で動いているアプリの互換性台帳づくりから、候補L2での再現と差分試験、スナップショットの取込と照合の仕組み、読み取りの並行照合・書き込みの限定開始の実装、障害演習と切り戻し手順の設計までを行います。貴社の移行を「動いた」ではなく不変条件で判定できる状態にするのが私たちの仕事です。L2への移行について相談する
参考資料
- Ethereum.org: オプティミスティック・ロールアップ(EVM互換、L1/L2の通信、資産移動、シーケンサー障害時の経路)
- Ethereum.org: ゼロ知識ロールアップ(validity proof、状態更新、zkEVM)
- Ethereum.org: スマートコントラクトのアップグレード(状態移行とプロキシの方式)
- ZKsync Docs: EVM Bytecode Interpreter overview(開発ツールの互換と制約、2026年9月24日確認)
- ZKsync Docs: Differences from Ethereum(ガス、opcode、precompile、取引の差分、2026年9月24日確認)
- Ethereum Foundation: How L1 and L2s can build the strongest possible Ethereum(2026年3月23日、退出できることと信頼の前提、2026年9月24日確認)
資料の確認日と注意
公式仕様の主要な資料は2026年9月24日に再確認しました(ZKsyncの差分も2026年9月24日確認)。最終確認日は2026年9月24日です。採用時は対象チェーンの最新仕様、アップグレード権限、障害情報、監査結果、利用規約をあらためて確かめてください。