What is the Ethereum Virtual Machine (EVM)?

Disclaimer: Crypto is a high-risk asset class. This article is provided for informational purposes and does not constitute investment advice. You could lose all of your capital.

The Ethereum Virtual Machine (EVM) is the computation engine that powers the Ethereum blockchain. Every smart contract on Ethereum runs inside the EVM. Every transaction that changes the state of the network is processed by the EVM. When a developer deploys a smart contract to Ethereum, it is stored as EVM bytecode and executed by every node in the network, each one arriving at the same result independently. The full technical specification is maintained at ethereum.org.

What is the Ethereum Virtual Machine

From ledger to state machine: what the EVM actually is

Most blockchains are described as distributed ledgers. Bitcoin fits that description well: it tracks which address holds which amount of bitcoin and records transfers between them. Ethereum is something different. Ethereum is a distributed state machine.

Every account balance, every smart contract, and every piece of data stored on the network forms part of the Ethereum state. A transaction does not just move value from one address to another. It triggers the EVM to execute code that may read from that state, write to it, deploy new contracts, or call existing ones. The result is a new version of the global state. The EVM is the engine that performs every one of those state transitions. Ethereum is a state machine because every block represents a new state, and the EVM is the mechanism that computes each state transition from the previous one. Understanding what Ethereum is at the network level makes the role of the EVM much clearer.

How the EVM works: from Solidity to bytecode to execution

When a developer writes a smart contract, they write it in a high-level programming language. That code is human-readable. The EVM does not read human-readable code. It reads bytecode: a compact sequence of low-level instructions. Getting from source code to deployed contract requires a compiler, a specific set of rules the EVM follows when executing, and gas to pay for every step. To understand what smart contracts are and what they do, the guide on what smart contracts are covers the full picture.

How the EVM works

Compiling smart contracts into bytecode

Solidity is the most widely used language for writing smart contracts on Ethereum. It uses a JavaScript-like syntax and was designed specifically for the EVM. Vyper is the main alternative: a Python-like language with a stricter design that reduces the attack surface available to developers. Curve Finance and Lido both use Vyper for their core contracts. Yul is an intermediate language that sits close to bytecode and is used for gas optimisation.

All three languages go through the same process. A compiler takes the source code and produces two outputs: EVM bytecode and an ABI (Application Binary Interface). The bytecode is what gets deployed to the network and what the EVM executes. The ABI is a separate description of the contract interface that tells external applications which functions exist, what inputs they accept, and what outputs they return. Uniswap, Aave, and OpenSea all exist on the Ethereum network as compiled EVM bytecode.

Opcodes: the instruction set of the EVM

EVM bytecode is a sequence of opcodes. An opcode is a single low-level instruction. The EVM has approximately 140 opcodes in its instruction set. Each one tells the EVM to do something specific: add two numbers, read from storage, write to memory, jump to a different position in the code, or stop execution.

Every opcode has a fixed gas cost determined by how much computational work it requires. Simple arithmetic operations are cheap: ADD costs 3 gas, MUL costs 5 gas. Reading from contract storage with SLOAD costs 2,100 gas. Writing to contract storage with SSTORE costs 20,000 gas for a new value. That difference in cost is deliberate. Writing to storage means every node in the network must update its copy of the global state and store that change permanently. The high gas cost of SSTORE is a direct disincentive against storing unnecessary data on-chain. For a full explanation of how gas fees work across the network, the guide on Ethereum gas fees covers the calculation in detail.

The EVM execution environment: stack, memory, and storage

The EVM operates on a stack-based architecture. When it executes opcodes, it works with three distinct data areas, each with different properties and different costs.

The stack is a last-in-first-out (LIFO) structure. It uses a 256-bit word size and holds a maximum of 1,024 items. The stack is where the EVM stores the immediate values it is working with during execution. It is volatile: the stack resets between calls and is not persisted anywhere. Operations on the stack are cheap.

Memory is a byte array available to the EVM during a single execution. It is also volatile, cleared completely when execution ends. Memory can grow as needed during execution, but the gas cost of expanding it grows quadratically. Using a large amount of memory in a single transaction becomes expensive quickly.

Storage is the only persistent data area. It is a key-value store that maps 256-bit keys to 256-bit values and is tied to a specific contract address. Changes to storage survive after execution ends and are part of the permanent Ethereum state. That permanence is why SSTORE costs 20,000 gas and SLOAD costs 2,100 gas.

A fourth data area, calldata, is the read-only input provided with a transaction. It is the cheapest way to pass data into a contract because the EVM cannot write to it. Developers who want to reduce gas costs pass data as calldata rather than writing it to storage.

The 256-bit word size is not arbitrary. Ethereum’s core cryptographic primitives use 256-bit values: the Keccak-256 hash function and the secp256k1 elliptic curve used for signing transactions both operate on 256-bit numbers. Aligning the EVM word size to those primitives avoids costly conversions.

How a transaction moves through the EVM

Every transaction that interacts with a smart contract triggers the EVM to run. The state transition that results either applies cleanly or reverts completely. There is no partial execution. Understanding this flow explains both how the EVM works and why failed transactions still cost gas. To see how this fits into the broader architecture of the network, the guide on how Ethereum works explains the full execution layer.

How a transaction moves through the EVM

Step-by-step: what happens when you send a transaction

When a user sends a transaction to a smart contract, the EVM processes it through the following steps:

  1. Transaction initiation. The user sends a transaction specifying the contract address, any input data, a gas limit, and a maximum fee per unit of gas. The gas limit caps how much computation the sender is willing to pay for.
  2. Gas check. Before execution begins, the EVM confirms the sender has enough ETH to cover the gas limit at the stated price. If not, the transaction is rejected before it runs.
  3. Bytecode execution. The EVM loads the contract bytecode and begins executing it opcode by opcode. The stack, memory, and storage are available. Each opcode deducts from the remaining gas.
  4. State changes applied. As execution proceeds, the EVM writes any state changes: updated account balances, new values in contract storage, events emitted to the log. These changes are staged but not yet finalised.
  5. Completion and gas settlement. When execution finishes, the staged state changes are applied to the global Ethereum state. Any gas not consumed is refunded to the sender. The gas that was consumed is paid to the validator.

What happens when gas runs out

If the EVM reaches a point where the next opcode would cost more gas than remains in the budget, it throws an out-of-gas exception. All state changes staged during that execution are immediately reverted. The contract storage returns to exactly the state it was in before the transaction started. No partial writes survive.

The gas consumed up to the point of failure, however, is not refunded. The validator nodes processed every opcode up to the failure and that work must be compensated. A transaction that fails due to an out-of-gas exception costs the sender the full gas used, produces no output, and leaves the state unchanged. This is a common source of confusion: a failed transaction is not free. Setting a realistic gas limit before sending a complex transaction avoids paying for a revert that could have been caught in testing. ETH is the currency used to pay for all gas costs, and the guide on what ETH is explains its role in the network.

Key properties of the Ethereum Virtual Machine

Three properties define how the EVM behaves and why it can secure a network worth hundreds of billions of dollars. Each one follows directly from the requirement that thousands of independent nodes must agree on the result of every computation.

Key properties of the Ethereum Virtual Machine

Deterministic execution

The EVM produces deterministic output. Given the same bytecode and the same input state, every node in the network will produce exactly the same result. This is not optional. If two nodes produced different results from the same transaction, they would disagree on the state of the network and consensus would break down.

Deterministic execution requires strict constraints. The EVM has no access to a system clock, so timestamps are not available inside contract code without being passed in explicitly. There are no random number generators. There is no access to external data or network requests. A smart contract cannot call an API. Every source of non-deterministic input is excluded by design. When a contract needs external data, such as an asset price, it must use an oracle: a separate system that feeds verified data onto the chain, where it becomes part of the deterministic state the EVM can read. The validators who run the nodes executing the EVM are covered in the guide on Ethereum proof of stake.

Sandboxed and isolated

The EVM runs in a sandboxed environment. A smart contract executing inside the EVM has no access to the host machine running the node. It cannot read files from the validator’s hard drive. It cannot make network requests. It cannot access the operating system. Each contract execution is isolated from all others: one contract cannot directly read another contract’s storage without an explicit function call.

This isolation has consequences beyond individual contract security. Because every node runs the EVM in a fully sandboxed environment, a malicious smart contract cannot compromise the machine running the node. The code runs, it produces its output, and it terminates. The boundary between the EVM and the host system is hard. That hard boundary is part of what allows independent operators around the world to run Ethereum nodes without trusting the contracts they execute.

Quasi-Turing complete

The EVM is described as quasi-Turing complete. A fully Turing-complete machine can execute any computation given enough time and resources, including computations that never terminate. The EVM is Turing complete in terms of the operations it can perform but is deliberately constrained by the gas mechanism.

Every opcode costs gas. Gas is finite. Therefore every program executed by the EVM must terminate. There are no infinite loops in EVM execution because any loop that runs long enough will exhaust the gas supply and trigger an out-of-gas exception. Without this constraint, an attacker could submit a transaction containing an infinite loop and force every node in the network to run it indefinitely, halting the network at effectively zero cost. The gas limit converts the theoretical possibility of infinite execution into a practical impossibility. What looks like a limitation is a fundamental security guarantee.

What the EVM is used for

The EVM executes every smart contract on Ethereum. Every application built on Ethereum runs because the EVM processes its contract code. Three categories account for the majority of EVM activity.

What the EVM is used for

Decentralized finance (DeFi)

DeFi protocols are smart contracts deployed on the EVM. Uniswap’s automated market maker is EVM bytecode. Aave’s lending and borrowing pools are EVM smart contracts. Compound’s interest rate model is EVM bytecode. Curve’s stablecoin pools run on Vyper-compiled EVM contracts. Every swap, every lending position opened, every liquidation triggered is a transaction processed by the EVM.

The total value locked across DeFi protocols on Ethereum has at times exceeded 50 billion dollars. All of that value is managed by smart contracts running inside the EVM, with no central operator and no ability for any single party to pause or modify the smart contracts once deployed.

NFTs and digital ownership

NFTs on Ethereum are governed by smart contracts that implement the ERC-721 standard. Fungible tokens, including stablecoins like USDC and USDT, implement the ERC-20 standard. Both are smart contract interfaces deployed to the EVM. Every NFT mint, transfer, and sale is an EVM transaction. Every token transfer calls a function defined in an EVM smart contract.

Collections like Bored Ape Yacht Club and CryptoPunks exist as EVM bytecode contracts on the Ethereum network. The ownership records they maintain are entries in contract storage, updated by EVM execution every time a transfer occurs.

Decentralized applications (dApps)

A decentralized application (dApp) splits its architecture between a frontend and a backend. The frontend can be a standard web application hosted anywhere. The backend is one or more smart contracts running on the EVM. MetaMask and other wallets connect a user’s browser to the Ethereum network and relay transactions to the EVM on the user’s behalf.

Because the backend of a dApp lives on the EVM rather than on a company’s servers, it cannot be shut down by the company that built it, blocked by a hosting provider, or taken offline by any single actor. The decentralised applications remain available as long as the Ethereum network runs.

EVM-compatible blockchains: what it means and which networks use it

The EVM has become the standard execution environment for smart contract blockchains. Dozens of networks beyond Ethereum Mainnet run their own version of the EVM or a close equivalent. A network described as EVM-compatible accepts smart contracts written in Solidity and uses the same tooling, the same developer workflows, and recognises the same bytecode format.

Network Type Relationship to EVM Notes
Arbitrum One Optimistic rollup (L2) EVM-equivalent Identical EVM behaviour at bytecode level
Optimism / Base Optimistic rollup (L2) EVM-equivalent OP Stack, byte-level compatibility
Polygon PoS Sidechain EVM-compatible Same Solidity tooling, different validator set
Avalanche C-Chain Subnet EVM-compatible Runs a fork of go-ethereum
BNB Smart Chain PoS-authority chain EVM-compatible Different precompiles, 21 validators
zkSync Era ZK rollup (L2) zkEVM Proves EVM execution with ZK proofs
Polygon zkEVM ZK rollup (L2) zkEVM Type 2 EVM-equivalence with ZK proofs

EVM compatibility vs EVM equivalence

EVM compatibility and EVM equivalence are not the same thing. The distinction matters for developers porting smart contracts between networks.

An EVM-compatible network accepts Solidity code and uses the same development tools but may differ at the implementation level. BNB Smart Chain, for example, uses different precompiled contracts and has a different validator set. A contract that works perfectly on Ethereum may behave differently in edge cases on BNB Smart Chain because the underlying implementation has been modified.

An EVM-equivalent network reproduces the EVM’s behaviour exactly at the bytecode level. Arbitrum Nitro and Optimism Bedrock are designed so that any contract deployed on Ethereum Mainnet will produce identical results when deployed on their networks, including behaviour in edge cases. A zkEVM such as zkSync Era or Polygon zkEVM goes further: it generates a cryptographic proof that the EVM execution was carried out correctly, enabling Layer 2 transactions to be verified on Ethereum Mainnet without re-executing every step.

What programming languages compile to EVM bytecode

Three languages dominate EVM development. All three compile down to the same EVM bytecode format that the EVM executes.

Solidity is the most widely used. It uses a syntax familiar to JavaScript and TypeScript developers and was designed from the ground up for the EVM. The majority of deployed smart contracts on Ethereum were written in Solidity. Most developer tooling, audit firms, and educational resources target Solidity first.

Vyper takes a different approach. Its Python-like syntax is intentionally more restrictive than Solidity. It disallows recursion, infinite loops, and operator overloading. Those restrictions make Vyper contracts easier to audit and harder to exploit. Curve Finance, one of the largest DeFi protocols by volume, uses Vyper for its core contracts.

Yul is an intermediate language that compiles to EVM bytecode and gives developers direct control over gas costs at a low level. It is rarely used for full contracts but is common in the inner loops of gas-optimised libraries.

The EVM vs other virtual machines

The term virtual machine is used in computer science for any software layer that abstracts hardware and provides a runtime environment for code. The JVM (Java Virtual Machine) is the most widely known example. The EVM and the JVM are both virtual machines but they operate under fundamentally different constraints. The decision to build Ethereum around a virtual machine rather than a simpler ledger model was central to the original design. The guide on who created Ethereum covers how Vitalik Buterin and the founding team arrived at that approach.

The EVM vs other virtual machines

The JVM runs on a single computer. It has full access to that computer’s file system, network, and operating system. A Java program can read a file, open a socket, or call a system API. The JVM does not need to be deterministic across multiple machines because it only runs on one at a time.

The EVM runs simultaneously on thousands of nodes. Every node must arrive at the same result. That requirement forces the EVM to exclude everything that could produce different results on different machines: no file system access, no network calls, no system clock. The EVM trades the flexibility of the JVM for the property that makes blockchain consensus possible.

WebAssembly (WASM) has been discussed as a possible future execution environment for Ethereum. A proposal called eWASM (Ethereum-flavoured WebAssembly) was studied for several years as a potential replacement for the EVM, offering faster execution and a broader set of supported languages. That proposal has been set aside in favour of incremental improvements to the EVM itself. The EVM Object Format (EOF), introduced through a series of EIPs, adds structured sections to EVM bytecode, separates code from data, and enables stricter validation at deploy time. EOF reduces certain gas costs and makes EVM code easier to analyse statically. It represents the current direction for EVM development rather than a replacement of the EVM with a different architecture.

FAQ

What is the Ethereum Virtual Machine (EVM)?

The Ethereum Virtual Machine (EVM) is the computation engine that executes smart contracts on the Ethereum network. Every node in the network runs the EVM. When a transaction interacts with a smart contract, the EVM executes the contract’s bytecode, applies any resulting state changes to the Ethereum blockchain, and charges gas for each operation performed.

How does the EVM execute smart contracts?

Smart contracts are stored on the Ethereum network as EVM bytecode. When a transaction calls a contract, the EVM loads that bytecode and executes it opcode by opcode. Each opcode performs a specific operation: arithmetic, reading from storage, writing to memory, or calling another contract. Gas is deducted for each opcode. When execution ends, state changes are applied to the global Ethereum state and any unused gas is refunded.

What is EVM bytecode?

EVM bytecode is the low-level instruction format that the EVM executes. Developers write smart contracts in high-level languages like Solidity or Vyper. A compiler translates that source code into EVM bytecode: a compact sequence of opcodes that the EVM can process directly. Bytecode is what gets deployed to the Ethereum network. It is not human-readable but can be decompiled for analysis.

What is the difference between EVM memory, storage, and stack?

The stack is a fast, volatile data area used for immediate values during execution. It resets between calls. Memory is a byte array available during a single execution that is cleared when the call ends. Storage is a persistent key-value store tied to a contract address that survives after execution. Storage is the most expensive: writing to storage costs 20,000 gas. Reading costs 2,100 gas. Stack operations are cheap. Memory costs grow quadratically as the memory footprint expands.

What does it mean for a blockchain to be EVM-compatible?

An EVM-compatible blockchain accepts smart contracts written in Solidity, uses the same bytecode format, and supports the same developer tooling as Ethereum. Developers can deploy the same contract code to an EVM-compatible network without rewriting it. EVM-equivalent networks go further and reproduce the EVM’s behaviour exactly at the bytecode level. zkEVM networks add cryptographic proofs that EVM execution was performed correctly.

Why is the EVM sandboxed?

The EVM runs in a sandboxed environment so that smart contract code cannot access or affect the machine running the node. A contract executing in the EVM has no access to the node’s file system, network connections, or operating system. This isolation protects node operators from malicious contracts. It also ensures that execution is deterministic: because contracts cannot access anything outside the EVM, every node produces the same result from the same input.

What is Turing completeness in the context of the EVM?

A Turing-complete system can perform any computation that can theoretically be computed, given enough resources. The EVM is described as quasi-Turing complete because it can perform any computation but is constrained by the gas mechanism. Every opcode costs gas. Gas is finite. Therefore every EVM program must terminate. This prevents infinite loops from halting the network. The gas limit is what makes Turing completeness safe in a decentralised context.

What happens when a transaction runs out of gas?

When a transaction runs out of gas during EVM execution, the EVM throws an out-of-gas exception. All state changes made during that execution are immediately reverted. The contract storage and account balances return to their state before the transaction began. The gas consumed up to the point of failure is not refunded because the nodes performed that computation. The sender pays for the work done, receives no output, and the state is left unchanged.

Amer Fejzic
Amer Fejzic
Amer Fejzic is the founder and lead writer of Crypto News ETH. He has followed Ethereum since 2017, through two full bull and bear cycles. Over that time he has bought and held ETH, paid gas fees during the 2021 congestion peak, used DeFi protocols on mainnet and on Layer 2 networks, and staked through liquid staking services. He writes about Ethereum because he uses it, not just because he covers it.