イーサリアム仮想マシン(Ethereum Virtual Machine)は、イーサリアムブロックチェーン上でスマートコントラクトを実行するための分散型かつサンドボックス化されたランタイム環境である。この仮想マシンは、ハードウェアやオペレーティングシステムに依存せずに、すべてのノード上で一貫してコードを実行するグローバルな「準チューリング完全」な仮想コンピュータとして機能し、分散型アプリケーション(dApps)、ERC-20やERC-721などのトークン規格、分散型金融(DeFi)、非代替性トークン(NFT)、および分散型自律組織(DAO)の基盤を支えている [1]。EVMは、ノードが取引を検証し、スマートコントラクトのバイトコード(SolidityやVyperなどの高レベル言語からコンパイルされた低レベル命令)を処理する上で中心的な役割を果たす。すべてのノードが同一の結果に合意できるようにするために、EVMはスタックベースのアーキテクチャを採用しており、各命令(EVMオペコード)には事前に定義されたガス消費量が割り当てられている。このガスシステムは、無限ループやサービス拒否攻撃(DoS攻撃)を防ぎ、ネットワークの安定性を確保する [2]。EVMの設計は、Gavin Wood博士によって作成されたイーサリアムイエローペーパーで正式に定義されており、決定論的実行を保証することで、分散型ネットワークにおける信頼できる合意を可能にしている。最近のアップデートには、コードの明確化と将来の拡張性を目的としたEVMオブジェクトフォーマット(EOF)の導入や、Vitalik Buterin氏が提唱するアカウント抽象化の改善を含む「スプラージュ」ロードマップが含まれる [3][4]

アーキテクチャと実行モデル

イーサリアム仮想マシン(EVM)は、イーサリアムブロックチェーン上でスマートコントラクトを実行するための分散型かつサンドボックス化されたランタイム環境であり、スタックベースのアーキテクチャとガスメータリングを特徴とする。この設計により、EVMはノード間での決定論的実行を保証し、ハードウェアやオペレーティングシステムに依存せずに一貫した結果を得られる。EVMは準チューリング完全(quasi-Turing complete)とされ、理論的には任意の計算が可能だが、実行時間やリソースを制限するガスシステムにより無限ループを防いでいる [5]

スタックベースのアーキテクチャ

EVMはスタックベースの仮想マシンとして設計されており、演算の際、値を一時的に保持するスタック(stack)を主なデータ構造として使用する。スタックはLIFO(後入れ先出し)方式で動作し、最大1024個の256ビット幅のアイテムを保持できる [2]。各EVMオペコード(opcode)は、スタックから値をポップして演算を行い、結果を再びプッシュする。例えば、ADDオペコードはスタックの上位2つの値を加算し、その結果をスタックに積む。この設計は命令の解釈を簡素化し、実行の一貫性を高める [7]

スタック操作には、PUSHPOPDUPSWAPといった基本的なオペコードが含まれる。しかし、スタックの深さ制限により、関数に多くのローカル変数やパラメータを定義すると「スタックが深すぎる(stack too deep)」というコンパイルエラーが発生する。この問題を回避するため、開発者は関数の分割や、Solidityの構造体(struct)によるデータのパッキングなどの最適化手法を用いる [8]

256ビットワードサイズの意義と課題

EVMのワードサイズは256ビット(32バイト)に固定されており、これはイーサリアムの暗号処理に最適化されている。アドレス、ハッシュ関数(Keccak-256)、楕円曲線署名(secp256k1)など、256ビット値を扱う基本的な演算を効率的に実行できるため、暗号操作に特化した設計と言える [9]。しかし、このサイズは汎用的な計算(例:カウンター、タイムスタンプ)には過剰であり、メモリやストレージの無駄を招く。特にストレージでは、uint128のような小さな型であっても32バイトのスロットを占有するため、ガスコストが高くなる [10]。この点について、イーサリアムの共同創設者であるVitalik Buterin氏は、256ビットワードサイズを「最大の後悔の一つ」と述べており、特にゼロ知識証明システムにおいて回路が肥大化する問題を指摘している [11]

実行中のデータ領域

EVMは実行中に複数のデータ領域を管理しており、それぞれの用途と特性が異なる。

  • スタック:一時的な演算用データを保持。最大1024アイテムまで。
  • メモリ(memory):一時的かつ線形のバイト配列。関数実行中に使用され、呼び出しごとにリセットされる。メモリの拡張には二次的なガスコストが発生する [12]
  • ストレージ(storage):永続的なキー・バリュー型のデータストア。スマートコントラクトの状態がブロックチェーン上に保存される。SSTORE(書き込み)とSLOAD(読み取り)は高コストな操作である [13]
  • コールデータ(calldata):トランザクションに含まれる読み取り専用の入力データ。関数の引数や呼び出し先の関数セレクタを含む [14]

決定論的実行とガスメータリング

EVMの実行モデルの核心は決定論的実行にある。同一の初期状態と入力に対して、すべてのノードが同一の結果に到達するため、分散合意が可能になる。この決定性は、固定精度の256ビット算術や、ガスによるリソース制限によって保証される。特にガスシステムは、EVMの安全性と経済的持続可能性を支える重要なメカニズムである。各オペコードには事前に定義されたガス消費量が割り当てられており、ユーザーはそのガスをイーサ(ETH)で支払う [15]。ガスが尽きると実行は中止され、状態変更はすべてロールバックされるが、消費したガスは返却されない。これにより、無限ループやサービス拒否(DoS)攻撃が防がれる [2]

オペコードと実行フロー

EVMは約140のオペコードから構成され、算術演算(ADD, MUL)、制御フロー(JUMP, JUMPI)、データ操作(MSTORE, SLOAD)などを実行する [17]。関数呼び出しは、コールデータの先頭4バイト(関数シグネチャのハッシュ)を解析することで決定される [14]。外部コール(CALL)は、別のアドレスのコードを実行するが、呼び出し元のコンテキストと分離されている。しかし、この分離が不十分な場合、再入(reentrancy)攻撃のリスクが生じる。そのため、セキュリティベストプラクティスとして「チェック→効果→相互作用」(checks-effects-interactions)パターンが推奨されている [19]

アーキテクチャの制約と将来の進化

EVMのスタックベースアーキテクチャはシンプルさと決定性を提供する一方で、パフォーマンスや開発者の使いやすさに課題を残している。スタック操作の頻度が高く、複雑な制御フローではSWAPDUPが多用され、バイトコードが肥大化する。また、逐次実行のため、トランザクションの並列処理ができない。これにより、スループットが制限され、ネットワークの混雑時にガス価格が高騰する [20]

これらの課題に対処するため、複数のイーサリアム改善提案(EIP)が進行中である。EIP-5450(EOF – スタック検証)は、デプロイ時にスタックの深さを静的に検証することで、スタックアンダーフロー/オーバーフローを防止する [21]EIP-7937(EVM64)は、64ビット算術オペコードを導入し、暗号処理以外の演算の効率を向上させる [22]。さらに、EIP-7979は、安全な呼び出し/リターンオペコードを追加し、動的なジャンプに伴うリスクを軽減する [23]。これらのアップデートは、EVMをより安全で効率的な実行環境に進化させるための継続的な取り組みの一環である。

ガスシステムとリソース管理

イーサリアム仮想マシン(EVM)におけるガスシステムは、ネットワークのセキュリティ、安定性、および経済的持続可能性を確保するための中心的なメカニズムである。このシステムは、スマートコントラクトの実行に伴う計算資源の使用を計測し、無限ループやサービス拒否(DoS攻撃)攻撃などの悪意ある行為を防ぐ役割を果たす。すべてのトランザクションは、実行に必要な計算量に応じて「ガス」と呼ばれる単位で料金を支払う必要があり、このガスはイーサリアムのネイティブ通貨であるイーサ(ETH)で支払われる [15]

ガスの概念は、EVMが「準チューリング完全」であるという性質と深く関連している。EVMは理論上は任意の計算を実行できるが、実際にはガスの制約により、計算は有限のリソース内でしか行えない。このため、EVMは無限に実行される可能性のあるプログラムを停止させることができ、分散型ネットワークにおける決定論的実行を保証する。トランザクションが指定されたガスリミットを超えると、実行は中止され、状態の変更はすべて元に戻されるが、消費されたガスは没収される [5]。この仕組みにより、ネットワークはリソースの濫用から保護される。

オペコードとガスコスト

EVMは約140のEVMオペコードから構成されており、それぞれのオペコードには実行に必要なガス量が事前に定義されている。これらのコストは、計算の複雑さやリソースの消費量に基づいて設定されている。たとえば、ADDSUBなどの基本的な算術演算は3ガス単位を消費するのに対し、MULは5ガス、EXP(べき乗)は計算量に応じて動的に変動するガスコストがかかる [17]。状態にアクセスする操作、特にストレージへの読み書きを行うSLOADSSTOREは、データベースの読み書きを伴うため、非常に高コストである。

時間の経過とともに、これらのガスコストは、ハードウェアの進化やネットワークの状況に合わせて調整されてきた。たとえば、EIP-2929(2020年)では、SLOADBALANCEEXTCODEHASHなどの状態アクセスオペコードのガスコストが引き上げられ、初回アクセス(「cold access」)と再アクセス(「warm access」)の区別が導入された。これは、実際のストレージ遅延や状態の拡大を反映したものである [13]。さらに、EIP-8038(2025年)では、GAS_COLD_SLOADGAS_COLD_ACCOUNT_ACCESSなどのコストがさらに引き上げられ、Ethereumの状態の拡大に伴う経済的バランスを維持する目的がある [28]

EIP-1559とロンドンハードフォークによるトランザクションコストの予測可能性

2021年8月5日に実施されたロンドンハードフォークは、Ethereumのガス市場に革命をもたらした。このアップデートにより、EIP-1559が導入され、トランザクションの料金体系が根本的に変更された。それ以前は、ユーザーがブロックに自分のトランザクションを含めるためにガス価格を入札する「第一価格オークション」モデルが採用されていたが、これはネットワークの混雑時に料金が極端に高騰し、予測不能な状況を引き起こしていた。

EIP-1559は、このモデルを二重料金構造に置き換えた。この構造は以下の2つの要素から成る。

  1. ベースフィー:ネットワークが決定するガス単価であり、ブロックごとにネットワークの需要に応じて自動調整される。このベースフィーは、マイナーやバリデータに支払われるのではなく、バーン(永久に供給から削除される)される [29]
  2. プライオリティフィー(チップ):ブロック作成者に支払われるオプションの追加料金で、トランザクションの優先順位を高めるために使用される。

ベースフィーは、ブロックの利用率に基づいてアルゴリズム的に調整される。ブロックが目標サイズ(1500万ガス)を超えると、最大12.5%まで増加し、利用率が低い場合は減少する。このフィードバックループにより、ネットワークの混雑が安定化され、料金の予測可能性が大幅に向上した [30]。ユーザーは、より正確に料金を推定できるようになり、過剰な入札による損失が減少した。報告によると、EIP-1559の導入により、ユーザーはベースフィーの払い戻しや過剰入札の削減を通じて、約8億4400万ドルのトランザクション料金を節約した [31]。さらに、ベースフィーのバーンはETHにdeflationary pressure(通貨供給量の減少圧力)をかけ、経済モデルの持続可能性に貢献している [32]

トランザクションとブロックのガス制限

リソース管理の観点から、EVMはトランザクションとブロックの両方にガスの上限を設けている。トランザクションの送信者は、自分のトランザクションが消費できる最大ガス量を「ガスリミット」として指定する。一方、各ブロックにはネットワーク全体の「ブロックガスリミット」が存在し、これにより1ブロックに含まれるトランザクションの合計ガス量が制限される。

個々のトランザクションが非常に大きなガス量を消費すると、ネットワークの安定性を脅かす可能性がある。このリスクに対処するために、EIP-7825はトランザクションごとのガスリミットを16,777,216(2^24)にハードキャップすることを提案している [33]。この制限は、極めて大規模なトランザクションがブロックスペースを独占したり、ノードリソースを過度に消費するのを防ぎ、ネットワーク全体の予測可能性と分散性を向上させる。

ガス最適化とセキュリティのトレードオフ

開発者にとって、ガスコストの最適化はdAppのユーザーエクスペリエンスと経済的実現可能性に直結する重要な課題である。しかし、過度な最適化はセキュリティ上のリスクを引き起こす可能性がある。たとえば、無制限のループは、配列が成長するにつれてガス消費量がブロックガスリミットを超える可能性があり、結果としてトランザクションが失敗し、プロトコルの機能が「凍結」するというサービス拒否(DoS)攻撃につながる [34]。これを防ぐには、ページネーションやバッチ処理、オフチェーン計算の導入が有効である。

また、uncheckedブロックの使用も、ガスを節約できるが、整数のオーバーフロー/アンダーフローのチェックを無効にするため、深刻な脆弱性を引き起こす可能性がある [35]uncheckedは、オーバーフローが数学的にあり得ないことが証明できる場合にのみ使用すべきであり、その使用は徹底した監査の対象となるべきである。

開発者ツールによるガス管理

ガスコストを可視化・管理するためのツールが多数存在する。Hardhat Gas Reporterは、テスト実行中に各関数のガス消費量を詳細にレポートし、EtherscanのAPIと連携して実際の料金をフィアット通貨で表示できる [36]Foundryforge test --gas-reportコマンドも同様の機能を提供し、snapshotGasチートコードを用いて特定のコードブロックのガスを測定できる [37]。さらに、Tenderlyのガスプロファイラは、インタラクティブなフレームチャートでガス消費量を可視化し、特定のオペコードレベルでの分析を可能にする [38]。これらのツールをCI/CDパイプラインに統合することで、ガス消費量のレグレッションを防ぎ、生産環境での高コストな非効率を未然に防ぐことができる。

スマートコントラクトの開発とプログラミング言語

イーサリアム仮想マシン(EVM)上でスマートコントラクトを開発する際、開発者は主に高レベルのプログラミング言語を使用し、それらをEVMが実行可能なバイトコードにコンパイルする。このプロセスは、分散型アプリケーション(dApps)の構築における中心的な要素であり、Solidity、Vyper、Yulなどの言語が広く採用されている。これらの言語はそれぞれ設計思想やセキュリティのトレードオフが異なり、開発者の目的やアプリケーションの性質に応じて選択される。

主要なスマートコントラクト言語

Solidity

Solidityは、EVM向けに最も広く使用されているスマートコントラクト言語である。構文はJavaScriptに似ており、オブジェクト指向の特徴(継承、インターフェース、ライブラリなど)をサポートしているため、複雑なdAppsの開発が可能となっている [39]。Solidityは、OpenZeppelinなどのセキュアなコンポーネントライブラリと密接に連携しており、ERC-20やERC-721といった標準規格の実装を容易にしている。また、HardhatやFoundry、Remixといった豊富な開発ツールチェーンが存在し、テスト、デバッグ、デプロイのワークフローを効率化している [40]

Vyper

Vyperは、Python風の構文を持つ代替言語であり、簡潔さ、安全性、可読性を重視している。Solidityとは異なり、継承や関数のオーバーロードといった複雑な機能を意図的に排除しており、バグや脆弱性のリスクを低減することを目的としている [41]。そのため、金融取引やセキュリティが重要なアプリケーションの開発に適しているとされる。Vyperは、コードの検証(auditability)を重視するチームや、最小限の機能で安全なコントラクトを実装したい開発者に支持されている [42]

Yul

Yulは、Solidityツールチェーン内で使用される中間言語であり、EVMバイトコードに近い形で記述できる。開発者は、特定の用途に最適化された効率的なコードを手動で記述する際にYulを利用できる。また、Solidity内にインラインアセンブリとしてYulコードを埋め込むことも可能で、低レベルの操作に対する細かい制御を提供する [43]。拡張版のYul+は、高度な最適化を目的として実験的に使用されている [42]

新興言語と将来の動向

新しい言語の開発も進行中であり、Feは、Vyperの安全性とSolidityの表現力を組み合わせることを目指している [42]。このような言語の進化は、EVMエコシステムにおける開発者体験、セキュリティ、パフォーマンスの向上に貢献している。また、EVMオブジェクトフォーマット(EOF)やVia-IRコンパイルパイプラインなどの進化により、言語やツールの将来の拡張性と最適化が強化されている [46]

開発ツールとワークフロー

スマートコントラクトの開発は、単に言語の選択にとどまらず、包括的なツールチェーンに依存している。HardhatやFoundryなどのフレームワークは、ローカルネットワークの起動、テスト、デプロイ、ガス分析を統合的に提供する。特にFoundryはRustで構築されており、高速なテスト実行とSolidityネイティブのテスト記述が特徴である [47]。また、SlitherやEchidnaといったセキュリティ分析ツールは、ソースコードやバイトコードレベルで脆弱性を検出するのに不可欠であり、リエントランシー攻撃や整数オーバーフローといったEVM特有のリスクを特定できる [48]

セキュリティと最適化の実践

ガス最適化は、スマートコントラクト開発の重要な側面であるが、過度な最適化はセキュリティリスクを引き起こす可能性がある。例えば、無制限のループはブロックガス制限を超え、サービス拒否(DoS攻撃)を引き起こす。また、インラインアセンブリの不適切な使用は、メモリ破損や意図しない振る舞いを引き起こす。Solidity 0.8以降では、算術演算にデフォルトでオーバーフロー/アンダーフローのチェックが導入され、SafeMathライブラリの必要性が大幅に減少した [49]。しかし、uncheckedブロックの誤用は再び脆弱性を生むため、注意が必要である。開発者は、チェック-効果-インタラクションパターンやリエントランシーガードといったベストプラクティスを採用し、安全と効率のバランスを取る必要がある [19]

バイトコードとコンパイルプロセス

イーサリアム仮想マシン(Ethereum Virtual Machine)上でスマートコントラクトを実行するには、高レベルのプログラミング言語で記述されたコードを、EVMが直接解釈できる低レベルの形式に変換する必要がある。この変換プロセスの最終出力がEVMバイトコードであり、ブロックチェーン上に保存され、すべてのノードで実行される。バイトコードは、EVMのオペコード(EVMオペコード)と呼ばれる命令のシーケンスから構成され、スタック、メモリ、ストレージ、およびガス消費を通じて契約の状態を操作する [2]

EVMバイトコードの構造と特徴

EVMバイトコードは、16進数で表現される生のバイト列であり、各バイトが特定のオペコードまたはそのオペランド(引数)を表す [52]。たとえば、PUSH1オペコード(0x60)の後に1バイトの値が続くことで、その値がスタックにプッシュされる。バイトコードは人間にとって読みやすいものではなく、機械が直接実行するための最適化された形式である。このため、開発者は通常、SolidityやVyperのような高レベル言語でコードを記述し、それを後でコンパイルする。

EVMのバイトコードは、サンドボックス化された環境で決定論的に実行される。つまり、同じ初期状態と入力が与えられれば、ネットワーク内のすべてのノードが完全に同じ結果に到達する。この決定論的実行は、分散型ネットワークにおける合意を保証するために不可欠である [1]。また、各オペコードには事前に定義されたガス消費量が割り当てられており、無限ループやサービス拒否(DoS攻撃)攻撃を防ぐ [17]

高レベル言語との違い

高レベルのスマートコントクトコード(スマートコントラクト)は、関数、変数、ループ、条件分岐などの抽象化を用いて人間が読み書きしやすい形で記述される。Solidityの構文はJavaScriptに似ており、VyperはPythonを模倣しているため、多くの開発者にとって親しみやすい [55]。一方、EVMバイトコードは、スタック操作(PUSHPOPSWAP)、算術演算(ADDMUL)、ストレージアクセス(SSTORESLOAD)といった低レベルの命令の羅列である。

たとえば、Solidityのx = a + b;という単純な代入文は、コンパイル後にはPUSH命令でabをスタックに積み、ADD命令でそれらを加算し、STORE命令で結果をストレージに保存する一連のオペコードに変換される。このように、高レベルの抽象化は、実行時にはスタックベースのマシンが理解できる命令に分解される。

コンパイルプロセスの流れ

スマートコントラクトのコンパイルプロセスは、高レベル言語からEVMバイトコードへの変換を体系的に行う。このプロセスの中心となるツールはSolidityの公式コンパイラsolcであり、ソースコードを解析し、最適化を施した上で実行可能なバイトコードを生成する [56]

コンパイルプロセスは、単なる翻訳ではなく、最適化の機会でもある。たとえば、現代のコンパイラパイプラインでは、中間言語であるYulを経由することが多い。Yulは、EVMバイトコードに近いが人間が読める中間表現であり、この段階でガス消費を削減する高度な最適化(例:定数畳み込み、不要なコードの削除)が行われる [57]。その後、最適化されたYulコードが最終的にEVMバイトコードに変換される。この多段階のコンパイルアプローチにより、開発者は効率的でガスコストの低いコントラクトを構築できる。

EVMオブジェクトフォーマット(EOF)の進化

従来のEVMバイトコードは、構造がなく、メタデータを含まないため、静的解析や正式な検証が困難だった。この問題を解決するために提案されたのがEVMオブジェクトフォーマット(EVMオブジェクトフォーマット、EOF)である。EOFは、EIP-3540およびEIP-7692で定義されており、バイトコードにバージョン情報、セクションヘッダー、検証情報などの構造を導入する [58]。これにより、デプロイ時にバイトコードの正当性を検証でき、コードの分析や拡張性が向上する。

EOFの導入は、スマートコントラクトのセキュリティと開発者体験に大きな影響を与える。たとえば、EOFは複数のコードセクションをサポートし、将来のEVMの拡張性を確保する。また、zkEVMやクロスチェーンシステムとの互換性も高まる [58]。これにより、バイトコードは単なる実行可能ファイルから、より洗練された、検証可能なソフトウェアアーティファクトへと進化する。

その他のEVMバイトコードの進化

EVMバイトコードの進化はEOFにとどまらない。2024年のアップデートでは、SELFDESTRUCTオペコードの使用を制限するEIP-6780や、契約のコードタイプを照会できるEXTCODETYPEオペコードを追加するEIP-7761などが導入された [60][61]。これらの変更は、スマートコントラクトのセキュリティと機能性を向上させる。

さらに、EIP-5450(EOF – スタック検証)は、デプロイ時にスタックの深さが実行中にオーバーフローまたはアンダーフローしないことを保証する静的分析を導入し、スタック操作に起因する脆弱性を排除する [21]。同様に、EIP-7979は、より安全な制御フローを実現するための新しい呼び出し・リターンオペコードを提案している [23]。これらのアップデートは、EVMのアーキテクチャが進化し、より安全で効率的な実行環境へと移行していることを示している。

セキュリティの課題と脆弱性

イーサリアム仮想マシン(Ethereum Virtual Machine)は、スマートコントラクトの決定論的実行を保証する一方で、その設計上の特性がセキュリティの課題や脆弱性の原因となる。特に、スタックベースのアーキテクチャ、ガスメータリング、およびチューリング完全性に起因するリスクが顕在化しており、これらは再入(reentrancy)攻撃やガス枯渇によるサービス拒否(DoS攻撃)などの深刻な脅威につながる [1]

再入攻撃とスタックアーキテクチャの関係

EVMのスタックベースのアーキテクチャは、外部コールの実行中に呼び出し元のコンテキストをスタック上に保持するため、再入攻撃の根本的な原因となる。再入攻撃は、悪意のあるコントラクトが、送金処理後に状態更新が行われる前に、同じ関数を繰り返し呼び出すことで発生する。有名なDAOハックでは、このパターンにより、バランスが更新される前に資金が繰り返し引き出された [65]

スタックの最大深さは1024に制限されているが、これは無限の再帰を防ぐものの、安全な深さ内での攻撃を防ぐものではない [7]。このリスクを軽減するためには、Checks-Effects-Interactionsパターンを採用し、状態の更新を外部コールの前に行うことが推奨される。また、OpenZeppelinが提供するReentrancyGuardなどの再入ガードを用いることで、再入をブロックできる [67]

ガス枯渇によるサービス拒否攻撃

EVMのガスメータリングは、無限ループを防ぐための重要な仕組みであるが、逆にガス枯渇(gas exhaustion)によるDoS攻撃の温床にもなる。この攻撃では、攻撃者が動的配列やマッピングを無制限に繰り返す関数を強制的に実行させ、ブロックのガスリミットを超えてトランザクションを失敗させる [68]。例えば、報酬分配関数が参加者リストをループ処理する場合、攻撃者は多数のアドレスを登録することで、関数の実行を事実上不可能にする。

この問題を緩和するためには、ループに境界を設ける、ページネーションを実装する、またはオフチェーン計算を活用するなどの対策が必要である。また、プッシュ型ではなくプル型の支払いモデル(pull-over-push)を採用することで、ユーザー自身が資金を引き出すタイミングを制御できるようになり、ガス関連のDoSリスクを低減できる [34]

整数のオーバーフローとアンダーフロー

EVMの固定サイズ整数型(例えばuint256)は、算術演算の結果がその範囲を超えると、値がラップアラウンド(巻き戻り)する。これにより、オーバーフロー(最大値を超えた加算)やアンダーフロー(ゼロ未満の減算)が発生し、トークン残高の改ざんやアクセス制御のバイパスにつながる可能性がある [70]。2018年のBeautyChainトークンのハックでは、この脆弱性により無限トークンが生成され、大きな損失を出した。

この問題は、Solidityバージョン0.8.0以降で劇的に改善された。このバージョン以降、すべての算術演算にオーバーフロー・アンダーフローのチェックが組み込まれ、条件を満たさない演算はトランザクションをリバートする [49]。これにより、OpenZeppelinのSafeMathライブラリのような外部ライブラリの必要性が大幅に減少した [72]。ただし、uncheckedブロック内でチェックを無効にできるため、不適切な使用は再び脆弱性を生む可能性がある [35]

ガスグリーフィングと経済的DoS

ガスグリーフィング(gas griefing)は、攻撃者がガスコストを操作してコントラクトの機能を妨害する攻撃である。例えば、ユーザーにガスを払い戻すプロトコルでは、攻撃者が高コストなパスを繰り返し実行することで、払い戻しプールを枯渇させたり、他のユーザーのコストを引き上げたりできる [74]。2024年のSepoliaネットワークのインシデントでは、メッセージサイズの制限やRPCの脆弱性を悪用した投機的なDoS攻撃が発生し、ノードのパフォーマンスに悪影響を及ぼした [75]。このようなリスクに対処するため、EIP-7825はトランザクションごとのガスリミットを2^24(16,777,216)に制限することで、悪意のある大規模な操作の影響を軽減しようとしている [33]

ツールによる脆弱性の検出

開発者は、SlitherやEchidnaといったツールを活用することで、ソースコードレベルでは見えにくい脆弱性を検出できる。Slitherは、SolidityコードをEVMセマンティクスを反映した中間表現(SlithIR)に変換し、データフローや汚染分析を通じて再入やタイムスタンプ依存性などの脆弱性を検出する [77]。一方、Echidnaは、hevmというシンボリックEVMエンジンを統合しており、シンボリック実行により、特定の状態条件下で整数オーバーフローが発生するようなエッジケースの脆弱性を発見できる [78]。これらのツールは、EVMのバイトコードと実行セマンティクスを深く理解することで、より強力な検出能力を実現している。

正式検証の課題

EVMの決定論的実行モデルは、KEVMやhevmといった形式的検証の基盤を提供する [79]。しかし、実際の適用には課題がある。ガス制限により、無限ループや再帰的なコールは理論的には検証不可能であり、ツールはループ回数やコール深度に人工的な制限を設けなければならない [80]。また、コンパイラ最適化やインラインアセンブリの存在により、検証対象のソースコードと実際に展開されるバイトコードの間の対応関係が崩れる可能性があり、形式的証明の信頼性を損なう。そのため、形式的検証は重要なコンポーネントに限定され、静的解析やファジング、手動監査と組み合わせたハイブリッドなアプローチが現実的である [81]

ハードフォークによる進化とEIPの影響

イーサリアム仮想マシン(EVM)の進化は、主要なハードフォークとEthereum Improvement Proposal(EIP)によって推進されてきた。これらのアップデートは、EVMのセキュリティ、効率性、スケーラビリティを向上させるために導入され、ネットワークの安定性と開発者体験の向上に貢献している。特に、Constantinople、Istanbul、Londonの各ハードフォークは、EVMの動作に直接的な変更を加える重要なマイルストーンとなった。

主要なハードフォークによるEVMの変更

Constantinople:計算とストレージの最適化

2019年2月28日に実施されたConstantinopleハードフォークは、EVMの効率性と機能性を高める複数のEIPを導入した [82]。主な変更点として、ビット単位のシフト操作を効率化するSHLSHRSARというネイティブなオペコードが追加された(EIP-145)。これにより、暗号処理やデータパッキングにおけるガス消費量が最大で300ガス/操作まで削減された [83]

また、CREATE2オペコード(EIP-1014)の導入により、ソルト値と初期化コードのハッシュに基づいて、事前に決定可能なアドレスにスマートコントラクトをデプロイできるようになった [84]。この機能は、ステートチャネルやオフチェーンでのコントラクト作成において、オンチェーン展開を予測可能にするため、スケーラビリティソリューションに貢献している。

さらに、EXTCODEHASHオペコード(EIP-1052)が導入され、コントラクトのバイトコードのkeccak256ハッシュを返すことが可能になった。これにより、他のコントラクトのコードを完全に読み込むことなく検証できるため、プロキシパターンや検証システムにおける効率的なコントラクトの自己検証が可能となった [85]

Istanbul:セキュリティと相互運用性の強化

2019年12月8日に実施されたIstanbulハードフォークは、セキュリティ、相互運用性、ガスコストの正確性を向上させることを目的とした [86]。EIP-1344により、CHAINIDオペコードが導入され、現在のチェーンの固有の識別子を取得できるようになった。これにより、コントラクトはメインネットとテストネットなど、異なるイーサリアムネットワークを区別できるようになり、リプレイ攻撃を防止し、クロスチェーンの互換性を向上させた [87]

また、EIP-152では、Zcashのzk-SNARK証明に最適化されたBLAKE2bハッシュ関数のプリコンパイルコントラクトが追加された。このプリコンパイルは、ソフトウェア実装よりも大幅に高速であり、イーサリアムとZcash間の信頼できるブリッジやクロスチェーンのプライバシー応用を可能にした [88]

EIP-1884では、SLOADのガスコストが200から800に引き上げられ、SELFBALANCEBALANCE(address(this))の代わりに安価な選択肢として導入された。また、EXTCODESIZEのガスコストも再評価され、ネットワークの状態の成長に伴う計算負荷をより適切に反映するようになった。これらの変更は、低コストのオペコードを悪用してノードの実行を遅延させる可能性のあるサービス拒否(DoS)攻撃を軽減する [89]

London:ガス経済とフィーモデルの改革

2021年8月5日に実施されたLondonハードフォークは、イーサリアムのトランザクション価格メカニズムとガス会計に画期的な変更をもたらした [90]。EIP-1559により、動的に調整されるベースフィーが導入され、これはマイナーに支払われるのではなく、ネットワークによって「バーン」(循環から永久に削除)される。この変更により、第一価格オークションモデルが廃止され、トランザクションフィーの予測可能性が向上し、ボラティリティが減少した [30]

EIP-3198では、BASEFEEオペコードが導入され、コントラクトが現在のブロックのベースフィーを読み取れるようになった。これにより、ネットワークの需要に応じて動的なフィー推定、ガス効率の高いバッチ処理、オンチェーンの裁定取引戦略などが可能になった [92]

さらに、EIP-3529では、最大ガス還元率が50%から20%に削減され、SELFDESTRUCTオペコードの還元が廃止された。この変更は、還元メカニズムを悪用したDoS攻撃を防ぎ、ガス会計モデルを簡素化することを目的としている [93]

EIPを通じたEVMの継続的改善

EVMの進化は、主要なハードフォークに限らず、継続的なEIPの導入によって推進されている。例えば、EIP-2929(2020年)は、SLOADBALANCEEXTCODEHASHなどの状態アクセスオペコードのガスコストを引き上げ、トランザクション内で初めてアクセスされる状態(「冷たい」アクセス)と、再びアクセスされる状態(「温かい」アクセス)を区別することで、実際のストレージ遅延と状態成長を反映した [13]

EIP-7825は、1トランザクションあたりの最大ガス使用量を16,777,216(2^24)に制限するプロトコルレベルの上限を導入し、極端に大きなトランザクションがブロックスペースを独占し、ノードリソースを圧迫するリスクを軽減している [33]。これにより、ネットワークの安定性と分散性が向上した。

さらに、EVMのバイトコードフォーマットの構造化を目指すEVM Object Format(EOF)がEIP-3540で導入され、EIP-7692でさらに洗練された [58][3]。EOFは、バージョン管理、セクションヘッダー、より良いエラー検出を可能にし、バイトコードをよりモジュール化し、安全にする。これは、zkEVMやクロスチェーンシステムとの互換性を高める [98]

セキュリティ強化のためのEIP

EVMのセキュリティを強化するためのEIPも多数存在する。EIP-5450(EOF – スタック検証)は、コントラクトのデプロイ時にスタックの高さが実行中常に範囲内にあることを保証する静的分析を導入し、スタックアンダーフローとオーバーフローによるランタイムの脆弱性を排除する [21]

また、EIP-6780は、同一トランザクション内で作成されたコントラクトにのみSELFDESTRUCTオペコードの使用を制限し、意図しない状態のクリアを防いでいる [60]。EIP-7761は、EXTCODETYPEオペコードを追加し、コントラクトの自己検証能力を向上させた [61]

これらのEIPは、EVMのアーキテクチャの制約(スタックベースの設計、256ビットワードサイズ)に起因する課題に対処するものであり、開発者の生産性とユーザーの安全性の両立を目指している。継続的なアップデートを通じて、EVMはより安全で効率的、かつ開発者に優しい実行環境へと進化し続けている。

正式仕様と検証手法

イーサリアム仮想マシン(Ethereum Virtual Machine)の設計は、その信頼性と一貫性を保証するために、厳密な形式的仕様と検証手法に基づいている。これらの仕様と手法は、分散型ネットワークにおける決定論的実行を可能にし、スマートコントラクトのセキュリティと正確性を確保する上で不可欠である。EVMの形式的仕様は、実装の曖昧さを排除し、すべてのノードが同一の結果に到達することを保証する。同時に、形式的検証や静的解析などの手法は、コードに潜む脆弱性を事前に発見し、重大なバグや資金損失のリスクを軽減する。

正式仕様の基盤:イエローペーパーと形式的意味論

EVMの設計は、Gavin Wood博士によって作成されたイーサリアムイエローペーパーで正式に定義されている。この文書は、EVMのアーキテクチャ、実行モデル、および操作ルールを数学的かつ技術的に記述しており、開発者や研究者のための基盤的なリファレンスとなっている [102]。イエローペーパーは、状態遷移関数 Υ(σ, τ) → σ' を定義し、現在の状態 σ と一連の取引 τ がどのようにして新しい状態 σ' に変化するかを形式的に説明している。これにより、ネットワーク全体で合意が可能となる決定論的実行が保証される。

しかし、イエローペーパーは理論的な枠組みを提供するものの、特定の動作の詳細が曖昧な場合がある。この課題を解決するために、KEVM、Lean、Dafnyといった形式的意味論が開発されている。KEVMは、Kフレームワークを使用してEVMの完全な形式的意味論を提供し、到達可能性論理を用いてEVMバイトコードの性質を証明する。これにより、ERC-20トークンやMakerDAOコンポーネントのような高信頼性のスマートコントラクトの検証が可能になる [79]。一方、Lean 4を用いたNethermindのモデルは、公式のイーサリアム実行テストの99.99%をパスする高いテストカバレッジを誇り、機械チェックされた証明により論理的な一貫性を保証している [104]。さらに、Dafnyを用いた実行可能な意味論は、事前条件と事後条件を組み込んだ高レベルな記述を可能にし、自動証明器によって不変性や機能的正しさを検証できる [105]

検証手法:静的解析、シンボリック実行、形式的検証

EVMスマートコントラクトの検証には、複数の手法が用いられる。静的解析ツールのSlitherは、Solidityソースコードを「SlithIR」という中間表現に変換し、データフローと汚染分析を行う。この中間表現はEVMの意味論を忠実にモデル化しており、再入、タイムスタンプ依存、整数オーバーフローなどの脆弱性を、ソースコードレベルでは見えにくい形で検出できる [77]。一方、Echidnaはプロパティベースのファジングツールであり、hevmというシンボリックEVMエンジンと統合することで、シンボリック実行を実現している [78]。Echidnaは、特定の不変条件を破る入力を自動的に生成し、整数オーバーフロー、不正な状態変更、再入などのエッジケースの脆弱性を発見する。特に、verif-yの検証モードでは、特定のプロパティが常に成り立つことを数学的に証明するか、反例を見つけることができる。

形式的検証は、これらの手法の最高峰である。MythXはシンボリック実行を用いてより深いパスを探索するが、計算コストが高くなる。Slitherは高速でCI/CDに適しているが、複雑な時間的性質を証明できない。そのため、実際の開発では、形式的検証を高信頼性コンポーネントに限定し、静的解析やファジングと組み合わせたハイブリッドアプローチが有効である [81]

検証の実践的課題と将来の展望

形式的検証の実用化には、いくつかの課題が存在する。まず、ガス制限と有界実行の問題がある。EVMはガスにより計算量を制限するが、これは終了の予測不能性をもたらす。検証ツールはループ回数や呼び出し深さに人工的な上限を設ける必要があり、その結果、検証は部分的になり、特定のガス制限内でのみ有効となる [80]。次に、ソースコードとバイトコードの対応関係の問題がある。コンパイラの最適化やインラインアセンブリにより、検証対象のソースコードと実際に展開されるバイトコードが一致しない場合、証明が無効になる。KEVMやDafnyEVMはバイトコードを直接検証することでこの問題を回避するが、高度な工学的課題が残る。

さらに、実際のスマートコントラクトは、プロキシベースのアップグレードやダイヤモンドパターン、クロスチェーン相互作用といった複雑なパターンを用いることが多く、これらは検証の難易度を大幅に高める。また、ゼロ知識証明(zk)アプリケーションやzkEVMの登場により、暗号学的証明とEVMの意味論を統合する新たな複雑性が生じている [110]

将来的には、EVMの設計自体が検証しやすくなる方向に進化している。例えば、EIP-3779は異常なハルトや動的なジャンプを制限することで、制御フローを安全にし、EIP-7825は取引ガス制限をキャップすることで、実行の予測可能性を高め、検証の難易度を下げる [111]。これらの改善により、形式的検証はより実用的かつ包括的なものとなり、分散型アプリケーションのセキュリティと信頼性を支える基盤となるだろう。

スケーラビリティの課題と将来の展望

イーサリアム仮想マシン(EVM)は、分散型アプリケーション(dApps)やスマートコントラクトの実行を可能にする基盤技術であるが、ネットワークの成長に伴い、スケーラビリティの課題が顕在化している。これらの課題は、トランザクションの処理速度、ガスコストの高騰、状態の肥大化(state bloat)などに起因しており、イーサリアムの長期的な持続可能性と分散性に影響を及ぼす。これらの問題に対処するため、プロトコルレベルのアップデートや理論的枠組みが提案されており、将来の展望は多層的なアプローチに依存している。

状態肥大化とノードの分散性への影響

EVMのアカウントベースモデルは、すべてのアカウントの残高、ストレージ、およびコントラクトコードを永続的に保持するグローバルな状態を維持する [112]。この設計により、スマートコントラクトの開発が直感的になり、複雑な状態管理が可能になる一方で、状態の肥大化という重大なスケーラビリティ課題を引き起こしている。2025年時点で、イーサリアムのアクティブな状態は35GBを超え、継続的に増加している [113]。すべての完全ノードがこの状態を保存・検証する必要があるため、ハードウェア要件が上昇し、検証者(バリデーター)の数が減少するリスクが生じ、結果としてネットワークの中央集権化が進行する可能性がある。

この問題に対処するため、イーサリアムは「状態期限切れ(state expiry)」という概念を導入しようとしている。Vitalik Buterin氏が提唱するこのアプローチでは、一定期間アクセスされない状態データ(例:1年間アクセスされていない)はアクティブな状態から削除され、「アーカイブ」状態として扱われる [114]。ユーザーがそのデータにアクセスする必要が生じた場合、外部の証明(witness)を提供することで状態を「復活」させる必要がある。これにより、アクティブな状態サイズを20–50GB程度に抑制できると予想されており、ノードの負担を軽減する [114]。関連するEIPとして、EIP-7736(Verkleツリーにおけるリーフレベルの状態期限切れ)やEIP-7748(Verkleツリーへの状態変換)が挙げられる [114]

実行レイヤーの結合と検証のボトルネック

現在のイーサリアムアーキテクチャでは、トランザクションの実行、状態アクセス、およびコンセンサスが密接に結合されている。この「実行レイヤーの結合」は、すべてのバリデーターがすべてのトランザクションを再実行してブロックの妥当性を検証しなければならないという検証ボトルネックを生み出す [117]。レイヤ2(L2)ロールアップがこの問題の一部を緩和しているが、レイヤ1(L1)のバリデーターは依然としてすべてのトランザクションを処理する必要があるため、根本的な解決にはなっていない。

この課題を克服するために、「実行レイヤーの抽象化(execution layer abstraction)」という理論的枠組みが提案されている。これは、トランザクションの検証と実行を分離し、L1を主にデータ可用性と決済レイヤーとして機能させるというビジョンである。EIP-7701(ネイティブなアカウント抽象化)は、アカウントが自身の検証ロジックをEVMコードで定義できるようにすることで、スマートコントラクトウォレットをネイティブに統合する。また、EIP-8141(フレームトランザクション)は、検証、実行、ガス支払いのロジックをモジュール化した新しいトランザクションタイプを提案している [118]。これらのアップデートにより、イーサリアムはより柔軟で構成可能な「オンチェーン計算のプラットフォーム」へと進化することが期待されている [119]

ステートレスクライアントとVerkleツリー

状態肥大化と実行レイヤーの結合を解決する最も革新的なアプローチの一つが「ステートレスクライアント(stateless client)」モデルである。このモデルでは、バリデーターはグローバルな状態を保存せずにブロックを検証する。代わりに、各トランザクションには、特定の状態位置への読み書きの正当性を証明する「暗号的証明(cryptographic witness)」が付随する [120]。バリデーターはこの証明を検証するだけでよく、ローカルの状態にアクセスする必要はない。これにより、検証に必要なストレージ要件はギガバイトからキロバイト単位にまで削減される。

このモデルの実現には、効率的な証明生成が不可欠であり、その鍵となるのが「Verkleツリー」である。現在のイーサリアムが使用するMerkle Patriciaトライに代わるこのデータ構造は、ベクトルコミットメントを使用することで、大規模な状態セットに対しても定数サイズ(通常1KB未満)の証明を生成できる [121]。EIP-6800は、統一されたVerkleツリーを導入することで、完全なステートレス検証の基盤を築くことを目指している [122]。また、EIP-2035は、SLOADSSTORE操作のガス価格を証明の包含に応じて再価格付けすることで、効率的な状態アクセスを経済的にインセンティブ化する [123]。ステートレスクライアントは完全に実現するには課題(証明生成の遅延、量子耐性など)があるが、Ressのようなプロトタイプの実験では、14GBのディスク空間で完全な検証が可能であることが示されている [124]

並列実行と代替実行環境

EVMのシングルスレッド、逐次実行モデルは、スループットを制限する大きな要因である。ベースレイヤーでのトランザクション処理速度(TPS)は通常15–30程度にとどまる [125]。研究では、イーサリアムのトランザクションの64.85%が競合せず、並列処理が可能であることが示されている。これにより、Sei v2やNeon EVMなどの「並列EVM」が開発され、依存関係分析を用いて独立したトランザクションを同時に実行している [126][127]

一方、根本的なアーキテクチャの変更として、EVMの代替実行環境の採用が検討されている。SolanaのSealevelは、アカウントの読み書きを事前に宣言することで数千のトランザクションを並列処理でき、50,000 TPS以上のスループットを達成する [128]。また、Polkadotは、レジスタベースのWebAssembly(WASM)を実行環境として採用しており、C++やRustなどの言語をサポートし、EVMに比べて10–100倍の高速な実行が可能である [20]。これらの環境は、性能とスケーラビリティを優先するが、EVMの持つ高い相互運用性や成熟したツールチェーンを犠牲にしている。イーサリアムの将来の方向性は、EVMの置き換えではなく、ArbitrumがWASMサポートを導入するように、パフォーマンス向上のためのハイブリッド実行モデルへの進化が示唆されている [130]

参考文献