---
id: 16
title: EVM 互換とは実際に何を意味するのか：バイトコード、プリコンパイル、JSON-RPC、ツールチェーン
slug: evm-compatibility-explained
date: 2026/09/03
summary: 「EVM 互換」はしばしばマーケティングの一文に平坦化されます。実際に移行コストを決めるのは、バイトコードのセマンティクス、プリコンパイル集合、JSON-RPC の挙動、そして Foundry／Hardhat がそのまま動くかどうかです。本稿はそれら四つの層を分離し、並列化がなぜ互換性の維持を難しくするかを説明します。
keywords: EVM互換性,バイトコード,プリコンパイル,JSON-RPC,Foundry,Hardhat
heroImage: /images/community-bg.png
---

ほとんどすべての新しいチェーンのホームページに「完全な EVM 互換」と書かれています。その言葉は技術的な保証のように響き、実際には追加の質問を要する主張として振る舞います。コントラクトはバイトコードを変えずにデプロイできるのか。ウォレットやエクスプローラは RPC エンドポイントを切り替えるだけでよいのか。それとも「互換」とは単に「Solidity が書ける」という意味なのか。これらは三つの大きく異なるエンジニアリング上の約束であり、マーケティングは日常的に一文に圧縮します。

実行を並列性のために再設計しつつ EVM 互換性を保つチェーンにとって、これは修辞ではなく日々の制約です。スケジュールを並べ替え、コンフリクト検出とマルチエンジン実行を加えた後、重要なのはコントラクト作者に見える挙動が依然としてイーサリアムと一致するかどうかです。[Bitroot のポジショニング](/ja/blog/bitroot-positioning)では、Bitroot がなぜ完全な EVM 互換性を貫くのかを説明しました。本稿は「完全」を四つの検証可能な層に分解します。

## バイトコード：互換性の最小単位はオペコードであり、構文ではない

EVM は Solidity のソースを実行しません。コンパイルされたオペコード——スタック、メモリ、ストレージを中心に構成された命令セット——と、各アドレスが nonce、残高、コードハッシュ、独自のストレージツリーを持つアカウントモデルを実行します。厳格な互換性とは、オペコードのセマンティクス、ガス計量、スタック深さの制限、アカウントの読み書き規則が、対象のイーサリアム・ハードフォークと一致することを意味します。その水準では、再コンパイルされていないバイトコードは原理的に別のチェーンでも同じ状態遷移を生むはずです。

この基準が移行コストの下限を定めます。バイトコードレベルの互換性とは、監査済みのコントラクトが構文レイヤーの静かなずれのために全面再監査を必要としないこと、CREATE2 のアドレス導出や特定のオペコードのガスコストに依存した再入防御が、内部で価格が変わったせいで誤動作しないことを意味します。チェーンが「Solidity でコントラクトを書ける」だけをサポートするなら、開発者は構文の親しみを得る代わりに、珍しいオペコードやガスの仮定に触れた瞬間にずれを経験します。

ハードフォークへの整合も確認してください。有効なオペコード集合は Shanghai、Cancun 以降のアップグレードで同一ではありません。互換性の主張は、漠然とした「EVM」ではなく、追跡しているイーサリアムのアップグレードを明記すべきです。移行するチームはメインネットのランタイムバイトコードを再デプロイし、コードハッシュと重要な呼び出しパスの戻り値を比較できます。

並列実行は圧力を加えます。楽観的並列は同時に投機し、後にロールバックすることがありますが、コントラクト作者にとってコミットされた状態遷移は、依然としてある確定した直列順序（通常はブロック内のトランザクション順序）と等価でなければなりません。スケジューリングが見える最終状態を変えるなら、それは互換性ではなく、別の仮想マシンです。正しさの境界と直列化可能性については[楽観的並行制御（OCC）入門](/ja/blog/optimistic-concurrency-control-intro)を参照してください。並列性をより広いスケーリングの地図に置くには、[ブロックチェーン・スケーリングの地図](/ja/blog/blockchain-scaling-map)と [EVM 単一スレッドのボトルネック](/ja/blog/evm-single-thread-bottleneck)を比較してください。互換性が保つべきは、コントラクト作者が依拠する決定的なセマンティクスであり、単一スレッドのインタプリタそのものではありません。

## プリコンパイル：同じアドレスで違う実装は非互換

イーサリアムは高価な操作を `0x01`〜`0x0a` のような固定アドレスのプリコンパイル済みコントラクトとして実装します。楕円曲線ペアリング、冪剰余、ハッシュなどです。アプリケーションとライブラリはそれらのアドレスとガスコストをハードコードします。チェーンがプリコンパイル集合、アドレスの対応、戻り値のセマンティクスを変えれば、Solidity はコンパイルできても互換性はすでに壊れています。監査済みのライブラリがオンチェーンで失敗したり、誤った結果を返したりし得ます。

よくある「偽の互換性」のパターンには、人気のプリコンパイルだけを実装すること、予約されたイーサリアムのアドレスに独自のプリコンパイルを追加すること、文書化せずにガスを変えることが含まれます。移行するチームはホワイトペーパーの「EVM 互換」の一行を信用せず、対象フォークのプリコンパイル表と差分を取るべきです。同じ入力と calldata で、メインネットと対象チェーンで戻り値とガスが同じかどうか。ペアリングと modexp のパスは、高価でブリッジ、証明検証、暗号ライブラリが依存することが多いため、特にカバーすべきです。

並列 EVM はプリコンパイルのセマンティクスを変えることを要求しません。本当のリスクは「速度のために」特殊化したい誘惑です。スループットのためのプリコンパイルの変更は、互換性の物語に紛れ込ませるのではなく、明示的なプロトコルの差分であるべきです。チームが特殊な計算のために独自のプリコンパイルを追加するなら、明確に未予約のアドレス空間を使い、差分を文書化してイーサリアム予約アドレスに触れないようにすべきです。

## JSON-RPC：ツールチェーンはスローガンではなくインターフェースで生き死にする

デプロイできるコントラクトは、使えるエコシステムと同じではありません。ウォレット、エクスプローラ、インデクサ、モニタは JSON-RPC に依存します。`eth_call`、`eth_getLogs`、`eth_estimateGas`、`eth_getTransactionReceipt` などです。フィールドの意味、エラーコード、ログのインデックス、pending と latest のセマンティクスがイーサリアムのクライアントの習慣とずれれば、フロントエンドとインフラはアダプタを必要とし、移行コストは「RPC を差し替える」から「運用パスを作り直す」へ膨らみます。

`eth_estimateGas` とトレース系 API は特に注意に値します。並列実行の下では、最終的な直列セマンティクスをシミュレートしないガス見積もりが体系的に低すぎたり高すぎたりし得ます。メインネットと同型のトレースがなければ、Foundry のフォークテストとインシデントのフォレンジックが難しくなります。したがって JSON-RPC の互換性は「MetaMask が接続できる」ことではなく、日常の開発と運用のパスが再利用可能かどうかです。フィルタ購読、`eth_feeHistory`、EIP-1559 関連のフィールドが、既存の SDK がほぼ設定変更だけで稼働できるかを決めることがよくあります。

インデクサとエクスプローラは、安定したログの順序とレシートのフィールドも必要とします。並列実行が中間状態の可視性のタイミングを変えても、最終的なレシートがメインネットと同型であれば、アプリケーションは通常対処できます。レシートのフィールドが欠けていたり、エラーコードが独自仕様であれば、エコシステムのツールはフォークした保守を必要とします。互換性の受け入れは、「読み取り呼び出し＋送信＋ログ取得＋ガス見積もり」を一つの閉ループとして扱うべきで、デプロイの成功だけではありません。

## ツールチェーン：Foundry と Hardhat が最終審

ほとんどのチームにとって、互換性はローカルで判定されます。`forge test`、Hardhat のスクリプト、OpenZeppelin のコントラクト、一般的な検証プラグインが、対象の RPC に対してほとんど、あるいはまったく変更なしに動くかどうかです。Foundry（Forge／Cast／Anvil）は多くの新規プロジェクトの既定のテストスタックであり、Hardhat は依然として大きな導入基盤を抱えています。どちらもコンパイラの出力、オンチェーンのプリコンパイル、RPC の挙動がイーサリアムに十分近いことを前提とします。

短く反復可能な受け入れチェックリストです。

1. 同じ Solidity バージョンとオプティマイザ設定でコンパイルし、デプロイされたバイトコードのハッシュがメインネットのデプロイと一致するか（あるいは説明可能な immutable の分だけ異なるか）を確認する。
2. 重要なプリコンパイルを差分比較する。
3. Anvil／Hardhat Network で対象チェーンの状態をフォークし、既存の統合テストを走らせる。
4. ウォレットで chainId と RPC だけを変え、署名 → 送信 → レシートを完了する。
5. 中核コントラクトで不変条件テストを走らせる。残高の保存、アクセス制御、再入防御が対象チェーンでも成り立つこと。

どれかが失敗すれば、「互換」にはまだ隙間があります。Bitroot は複雑さをランタイムの並列スケジューリングに置き、開発者に Solidity の書き直しやツールチェーンの切り替えを求めないため、上記のパスはそのまま維持できます。[Bitroot の並列化 EVM 解説](/ja/blog/bitrootevm-)と[マルチエンジン並列実行設計](/ja/blog/bitroot-evm)も参照してください。[並列実行の三つのアプローチ](/ja/blog/parallel-execution-approaches)と比べると、バイトコード互換性を貫くことは、新しいアカウントモデルで得られる並列性の上限の一部を諦め、開発者エコシステムの移行半径の広さと引き換えにしています。

## 「EVM 互換」という主張の読み方

マーケティングの一文を四つの yes/no の問いに変えてください。バイトコードのセマンティクスは対象のハードフォークと一致するか。プリコンパイル表は同一か。JSON-RPC は一般的なメインネットのメソッドを同型のセマンティクスでカバーするか。既存の Foundry／Hardhat プロジェクトはほとんど、あるいはまったく変更なしに動くか。四つが yes なら厳格な互換性に近づきます。どれかが no なら、スローガンの背後に隠すのではなく、明示的な差分文書であるべきです。

並列性はコンフリクト下でのスループットとレイテンシを変え得ますが、コントラクト作者が依拠する決定的なセマンティクスを書き換えるべきではありません。ホットなワークロード下でのユーザーに見えるリトライとレイテンシの変動は性能とワークロードの問いであり、「セマンティクスは互換か」とは別です。後の[コンフリクトのホットスポットとワークロード](/ja/blog/parallel-evm-workload-hotspots)と[性能指標の用語集](/ja/blog/performance-metrics-glossary)を参照してください。より速いベンチマークを買う代わりにツールチェーンとバイトコードの挙動を予測不能にするチェーンは、短期的なポスターのために長期的なエコシステムの資本を費やします。そして EVM 路線のネットワーク効果こそ、そのポスターが買おうとしているものです。

次の記事は、すでに公開済みの記事だけを指す役割別の読書パスを示し、異なる背景が誰も読み切れない一つの記事に詰め込まれないようにします。

## 関連記事

- 前：[Bitroot のポジショニング：楽観的並列 EVM の上に築かれた高性能 Layer 1](/ja/blog/bitroot-positioning)
- 次：[誰が並列 EVM を読むべきか：コントラクト開発者、クライアントエンジニア、研究者の三つのパス](/ja/blog/who-should-read-parallel-evm)
- 関連：[EVM 単一スレッドのボトルネック](/ja/blog/evm-single-thread-bottleneck)、[楽観的並行制御（OCC）入門](/ja/blog/optimistic-concurrency-control-intro)
