Skip to content

The EVM — Ethereum's Virtual Machine

Up to now this book has treated Ethereum as a ledger: a world state of accounts, a state root that commits to all of it in 32 bytes, and a transition function that moves value from one account to another. That is already a remarkable thing for untrusting strangers to agree on. But it is not yet a computer. A ledger can answer “who owns what”; it cannot answer “run this program and let everyone agree on the result.”

This part builds the piece that closes that gap: the Ethereum Virtual Machine (EVM). The EVM is the engine that runs code stored inside an account, one instruction at a time, and produces a result every honest node computes identically. It is what upgrades “a shared ledger” into “a shared world computer” — a machine anyone on Earth can deploy arbitrary code to, that everyone else will faithfully execute. By the end of the part you will have built a small but real one, and you will be able to point at every design decision and say which threat it defends against.

The book’s throughline is how do untrusting strangers agree on the state of a shared world computer — and what does it cost to run one? The EVM is where both halves of that question get sharp at the same time.

  • Agreement. If the machine is a computer, then “agree on the state” now means agree on the output of a computation — including computations written by adversaries you have never met. The EVM must be deterministic: given the same code, inputs, and starting state, every node must reach the same result, or the network forks.
  • Cost. A computer that anyone can submit code to has an obvious problem: what stops someone submitting a program that never halts, or one that quietly asks every node on Earth to store a gigabyte forever? The answer is gas — a price on every single operation, paid up front, that turns “might run forever” into “runs for at most N steps, then halts.”

Hold those two words — deterministic and metered — in view for the whole part. Almost every design choice in the EVM exists to serve one of them.

a shared LEDGER a shared WORLD COMPUTER
┌──────────────────┐ ┌──────────────────────────┐
│ accounts, balances│ + the EVM │ accounts hold CODE │
│ transfer value │ ──────────▶ │ transactions RUN code │
│ agree on "who owns"│ │ agree on "what it computed"│
└──────────────────┘ └──────────────────────────┘
deterministic + gas-metered

The EVM is small enough to build from first principles, but its pieces only make sense in a certain order — each page uses the machinery of the one before it. Here is the shape before the detail:

  1. The stack machine and its opcodes. The EVM has no registers. Operands live on a last-in-first-out stack of 256-bit words, and each instruction pops its inputs and pushes its output. First we build the computational model itself: the opcodes, the assembler from opcodes to bytecode, and the decode-and-execute loop.
  2. Where data lives. A running contract can put data in four distinct places — the stack, memory, storage, and calldata — and they differ in lifetime, cost, and who can write them. Getting these four straight is the single biggest source of confusion for new EVM programmers, so it gets its own page.
  3. Gas. Every opcode has a price, and the ratios between those prices encode an economic truth: an addition touches a CPU register and vanishes, but a storage write burdens every full node forever. Gas is how the machine charges you for the cost you impose on everyone else.
  4. Execution context and the CALL family. A single transaction rarely runs one contract in isolation — contracts call other contracts. That means each execution runs inside a context (who called me, how much value came with the call, whose storage am I touching), and the CALL family is how one contract invokes another while keeping their state properly separated.
  5. Determinism. Finally we make explicit the property everything else quietly depended on: why every node computes the same result. This is where we see what the EVM had to forbid — no clocks, no random numbers, no floating point, no threads — to guarantee that agreement.

Read these in order. Each page forces one idea and grounds it in a real piece of our companion crate, ethmini (rust/ethmini/src/vm.rs for the machine, state.rs for the world it runs against).

#PageThe idea it forcesGrounded in
2A Stack Machine of 256-Bit WordsComputation with no registers: opcodes, an assembler to bytecode, and a decode-and-execute loop that never mis-reads immediate data.vm.rsOp, assemble, Op::decode, run
3Stack, Memory, Storage, and CalldataFour data locations with four lifetimes and four cost profiles — which survive the call, which are free, which touch every node forever.vm.rs stack + Execution.storage; state.rs account storage
4Gas — A Price on Every OpcodeMetering as the defence against unbounded work: charge before you act, and an out-of-gas halt reverts everything.vm.rsOp::gas_cost, the charge closure
5Execution Context and the CALL FamilyContracts calling contracts: caller, callee, value, and gas, with each contract’s storage kept separate.state.rsTxKind::Call, execute running vm::run
6Why Every Node Computes the Same ResultDeterminism as a hard requirement: what the machine forbids so consensus is possible at all.vm.rs run purity; state.rs snapshot/revert
900Revision · The EVMA one-page recap of the whole part, ready for self-testing.

Our ethmini EVM is a teaching model. It is faithful in shape and deliberately simplified in scale, and it is important to know exactly where the pedagogy departs from the real machine so you are never surprised later:

  • Words are 64-bit, not 256-bit. Real EVM operates on 256-bit words (chosen so a word can hold a Keccak-256 hash or an address without splitting). We use 64-bit u64 words, which fit in a Rust register and keep the arithmetic readable. Every mechanism — push, pop, wrapping overflow — is identical; only the width shrinks.
  • ~12 opcodes, not ~140. We implement about a dozen instructions — enough for arithmetic, storage, jumps, and halting. Real EVM has on the order of 140. The interpreter loop that runs ours is identical in shape to the one that runs all 140; we just left out the long tail.
  • Flat gas costs. Our SSTORE costs a flat 200 gas. Real EVM’s storage pricing is far larger and far more intricate — different costs for a zero→nonzero write versus a nonzero→nonzero write, plus refunds, plus “warm” versus “cold” access. We keep the ordering of the incentives (arithmetic cheap, storage dearest) and drop the exact schedule.
  • The opcode numbers are real. One thing we did not simplify: assemble encodes each op to the same byte value real Ethereum uses (ADD is 0x01, SSTORE is 0x55, RETURN is 0xf3). The bytecode you build here would be recognisable to anyone who has read the Ethereum yellow paper.

Whenever a page relies on one of these simplifications, it says so in place. The rule of the book holds: we simplify the scale to expose the idea, and we never lie about which is which.

  • Why does it exist? Because a ledger that can only transfer value is not programmable. The EVM exists to let untrusting strangers agree not just on who owns what, but on the result of running arbitrary code — turning a shared database into a shared computer that anyone can deploy to without permission.
  • What problem does it solve? Executing untrusted code safely on a network of mutually distrustful machines. It must run adversarial programs (including infinite loops and resource bombs) without letting them harm the network, and it must produce a result every honest node agrees on. Gas solves the first; determinism solves the second.
  • What are the trade-offs? Determinism forbids everything a normal computer takes for granted — no clocks, no OS calls, no randomness, no floating point, no concurrency. Gas metering makes every operation cost real money, so computation on-chain is thousands of times more expensive than off-chain. You buy global agreement by giving up speed, cheapness, and most of a normal runtime.
  • When should I avoid it? Whenever you do not need trustless global agreement on a computation. Heavy computation, private data, low-latency work, and anything that needs real-world time or randomness belong off-chain; the EVM should hold only the small amount of logic that genuinely must be verifiable by everyone.
  • What breaks if I remove it? Ethereum collapses back into a plain payments ledger. Every smart contract, token, exchange, and application disappears, because the very definition of “programmable money” is that the network runs code — and the EVM is that code-running machine.

Tie it back to the book’s one question. This part is where “agree on the state” stops meaning “agree on a list of balances” and starts meaning “agree on the output of a program written by a stranger.” That is a much harder thing to agree on, and the EVM earns it with two disciplines: it is deterministic, so every node walking the same bytecode reaches the same word, and it is metered, so no program — however hostile — can run forever or impose unbounded cost without paying for it step by step. The cost half of the question is not an afterthought here; it is baked into the instruction set itself, one gas price at a time. Keep asking, on every page: what threat does this design defend against, and what does it cost the person who runs the machine?

Start with the machine itself: A Stack Machine of 256-Bit Words →

  1. In one sentence each, explain the difference between “a shared ledger” and “a shared world computer,” and name the component that turns the first into the second.
  2. The part asks you to hold two words in view for every page: deterministic and metered. Which half of the book’s throughline does each word serve, and what specific failure does each one prevent?
  3. The roadmap builds five ideas in a fixed dependency order. Why must “the stack machine and opcodes” come before “gas,” and why must “where data lives” come before “the CALL family”?
  4. Our ethmini EVM uses 64-bit words, about a dozen opcodes, and flat gas costs. For each of those three simplifications, name the real-EVM figure it stands in for — and state the one thing about the opcodes we did not simplify.
  5. Using the architect’s lens, answer in your own words: if you removed the EVM from Ethereum but kept everything else, what exactly would you be left with, and what would be gone?
Show answers
  1. A shared ledger lets strangers agree on who owns what (balances and transfers); a shared world computer lets them agree on the result of running arbitrary code. The component that turns the first into the second is the EVM, which runs code stored inside accounts and produces a result every honest node computes identically.
  2. Deterministic serves the agreement half — it prevents the network from forking, because every node running the same code on the same state must reach the same result. Metered (gas) serves the cost half — it prevents a submitted program from running forever or imposing unbounded work on every node, by charging for each operation up front and halting when the budget is exhausted.
  3. Gas is a price on each opcode, so you must first have opcodes and a machine that executes them before you can meter them — the stack machine defines what is being charged for. Likewise, the CALL family is about how one contract touches another contract’s data while keeping state separate, which is meaningless until you understand the four data locations and, in particular, that storage is the per-account, persistent one that calls must not cross-contaminate.
  4. 64-bit words stand in for real EVM’s 256-bit words; ~12 opcodes stand in for the real ~140; flat gas costs stand in for the real, far larger and more intricate schedule (zero-vs-nonzero writes, refunds, warm/cold access). The thing we did not simplify is the opcode byte numbersADD is 0x01, SSTORE is 0x55, RETURN is 0xf3, exactly as in real Ethereum.
  5. You would be left with a plain payments ledger: accounts, balances, nonces, a state root, and value transfers between externally owned accounts — everything the earlier parts built. Gone would be everything that makes Ethereum programmable: contracts, tokens, exchanges, and every on-chain application, because those all exist only by virtue of the network running code, which is precisely what the EVM does.