EVMとは?イーサリアム上でコードを動かす仮想マシン
EVMは「Ethereum Virtual Machine(イーサリアム仮想マシン)」の略で、イーサリアムのネットワーク上でプログラムを動かすための仕組みです。
この記事では、EVMの役割、イーサリアムを「状態マシン」と捉える考え方、内部のデータの扱い、実装の種類を順に整理します。売買の方法や特定のチェーン・トークンの比較は扱いません。
なお、プロジェクト管理の手法として知られる「EVM(アーンドバリューマネジメント)」や、医薬品名の略称としてのEVMは、この記事の内容とは別の用語です。
EVMの正式名称と役割
EVMは、イーサリアムに参加するすべてのノード(ネットワークを支えるコンピューター)で、同じようにコードを実行するための分散型の仮想環境と説明されています(ethereum.org「イーサリアム仮想マシン (EVM)」)。
EVMは、すべてのノード間で一貫して安全にコードを実行する環境です(ethereum.org)。
スマート・コントラクトとガスとの関係
ノードはEVMを動かすことで、スマート・コントラクトを実行します(ethereum.org)。スマート・コントラクトとは、イーサリアム上に置かれ、決められた条件で動くプログラムのことです。
実行する処理の量は「ガス」という単位で測られます(ethereum.org)。計算量を測ることで、資源の割り当てとネットワークの保護につなげていると説明されています(ethereum.org)。
「分散型台帳」から「状態マシン」へ:EVMが決めるルール

ビットコインのようなブロックチェーンは、「分散型台帳」という例えで説明されることが多いとされています(ethereum.org)。台帳には、誰が何をできるかを定めたルールに沿った活動の記録が残ります。
一例として、ビットコインのアドレスは、受け取った分より多くを支払えないというルールがあります(ethereum.org)。
イーサリアムにも似たルールを持つ独自の暗号資産(イーサ)がありますが、それに加えてスマート・コントラクトも動かせます。この機能を説明するため、イーサリアムは分散型の「状態マシン」と表現されています(ethereum.org)。
ブロックごとに状態を変えるための具体的なルールを定めているのが、EVMです(ethereum.org)。
状態遷移関数Y(S, T)=S’とは
EVMは数学の関数のように、同じ入力に対して決まった出力を返す(決定論的)と説明されています(ethereum.org)。そのため、イーサリアムには状態遷移関数があると形式的に表せます。
| 記号 | 意味 |
|---|---|
| S | 有効な古い状態 |
| T | 有効なトランザクションの新しい集まり |
| S’ | 新しく生まれる有効な状態 |
| Y | 状態遷移関数 |
つまりY(S, T)=S’は、古い状態に新しい取引を適用すると、新しい状態が決まるという式です(ethereum.org)。
「状態」と「トランザクション」の意味
イーサリアムでいう「状態」は、「変更されたマークル・パトリシア・トライ」という大きなデータ構造とされています。すべてのアカウントがハッシュで結ばれ、ブロックチェーンに記録された1つのルートハッシュにまとめられる仕組みです(ethereum.org)。
状態には、アカウントと残高のほか、機械語のコードを実行できる「マシン状態」も含まれます(ethereum.org)。
トランザクションは、アカウントが暗号技術で署名した命令です。種類は、メッセージ・コールを起こすものと、コントラクトの作成を起こすものの2つです(ethereum.org)。
コントラクトの作成では、コンパイル済みのバイトコードを持つ新しいコントラクト・アカウントができます。他のアカウントがそこへメッセージ・コールを送るたびに、そのバイトコードが実行されます(ethereum.org)。
EVMの中身:スタック・メモリ・ストレージ・オペコード

ここからはEVMの内部で、データがどう扱われるかを見ていきます。ethereum.orgでは、理解の前提としてバイト・メモリ・スタックといった基本的なコンピューター用語の知識が挙げられています。
コンパイルされたスマート・コントラクトのバイトコードは、たくさんの「オペコード」(命令の単位)として実行されます(ethereum.org)。
オペコードには、XOR、AND、ADD、SUBといった一般的なスタック操作が含まれます。さらに、ADDRESS、BALANCE、BLOCKHASHのようにブロックチェーン特有の操作も用意されています(ethereum.org)。
256ビットのワードを扱うスタックマシン
EVMは、深さ1024個分のスタックマシンとして動作します。スタックの各要素は256ビットの「ワード」です(ethereum.org)。
256ビットが選ばれたのは、ケチャック・256ハッシュやsecp256k1署名といった256ビット前提の暗号技術と相性がよいためと説明されています(ethereum.org)。
スタックとは、積み重ねたデータを上から出し入れする形式のデータ置き場です。
メモリ・一時ストレージ・ストレージの違い
データの置き場所は3種類あり、保たれる期間が異なります(ethereum.org)。
| 種類 | 特徴 |
|---|---|
| メモリ | 実行中に使う一時的なバイト配列。ワード単位で番地を指定し、トランザクションをまたいで残らない |
| 一時ストレージ | TSTOREとTLOADで使う、トランザクションごとのキーバリューストア。トランザクション中の内部呼び出し全体で共有され、終了時に消える |
| ストレージ | コントラクトのアカウントに結びつく永続的な領域。グローバルな状態の一部 |
一時ストレージは、メモリと違って実行フレームではなくEVMの状態の一部として扱われます。ただし、グローバルな状態には書き込まれません(ethereum.org)。
一時ストレージを使うと、内部呼び出し同士でガス効率よく一時的な状態を共有できるとされています(ethereum.org)。
ストレージだけが永続的で、メモリと一時ストレージはトランザクションの範囲内で消えるという違いがあります。
EVMの実装

EVMにはいくつもの実装があり、どれもイーサリアムのイエロー・ペーパーに記された仕様に従う必要があります(ethereum.org)。
イーサリアムの10年の歴史の中で、EVMは何度か改訂されてきたとされています(ethereum.org)。
イーサリアムの実行クライアントにもEVMの実装が含まれています(ethereum.org)。
言語ごとに存在するEVMの実装
実行クライアントとは別に、単独で使える実装も複数あり、プログラミング言語ごとに存在します(ethereum.org)。
| 実装 | 言語 |
|---|---|
| Py-EVM | Python |
| evmone | C++ |
| ethereumjs-vm | JavaScript |
| revm | Rust |
