A 32-byte fingerprint keeps thousands of Ethereum nodes in step
In the first week of November 2026, Base, BNB Chain and the Tempo network pushed upgrades to their node operators. A bug in staking means depositing a proof of stake coin with a protocol that stakes it for you and issues a transferable token (such as Lido stETH or rETH) representing the deposit plus rewards, which you can use or sell while the coins stay staked.">Reth, an execution client built by Paradigm, could make a node compute a wrong state root. Fixes shipped between 4 and 6 November and no loss of funds, exploit or outage was reported, as our report on the Reth state-root bug and the layer-2 patches sets out. The episode is a good way into how the Ethereum Virtual Machine works, because Reth is one of the programs that implement it. The fix itself, Reth pull request 28264, was merged on 3 November under the title “fix(trie): tighten iterator seek boundary”.
A state root is one 32-byte number. Every Ethereum block header carries one. It sums up every account balance, every piece of contract code and every storage slot as they stand once the block’s transactions have run. Thousands of computers, running five main client programs written in four programming languages, recompute that number on their own. A node that arrives at a different value no longer agrees with the chain. The rules all of them must reproduce, to the last bit, are those of the Ethereum Virtual Machine (EVM).
What follows starts with the data, the world state and how a block commits to it, then opens the machine: bytecode run one opcode at a time on a stack of 256-bit words, calls between contracts, the path of a transaction from signature to receipt, the clients that run it all and the changes ahead. It picks up where our lesson on Ethereum’s history and white paper stopped. No Solidity is needed; we stay at the level of bytes.
The world state: a ledger of accounts and what each one commits to
Four fields per account, and what the machine does with them
Every Ethereum account has four fields: a nonce, a balance in wei, a code hash and a storage root. Externally owned accounts (EOAs) are controlled by a private key; contract accounts are controlled by their code and cannot start a transaction on their own. Our guide to the UTXO and account models already covers those fields, the nonce and the weight of contract storage, so here we only look at what the EVM does with them.
Accounts are found by a 20-byte address. For an EOA, the address is the last 20 bytes of the Keccak-256 hash of its public key, according to ethereum.org’s account documentation. For a contract, the address is derived when the contract is created, as described further down. The code hash points to the bytecode, and the machine has no instruction to rewrite the code stored at an address once deployed. The storage root is itself the root of a second tree that holds that one contract’s storage.
The Ethereum documentation writes the whole system as a function, Y(S, T) = S’: an old state plus a valid transaction gives a new state. Every node applies the same function to the same input and must land on the same output. Everything else in this lesson is a detail of that function.
Why the state is a trie and not a table
A table of accounts would be easy to store and impossible to check without downloading it. Ethereum instead keeps the state in what ethereum.org calls a modified Merkle Patricia Trie: a tree with up to 16 branches per node, where the path to a leaf is spelled out by the key and every node is identified by the hash of its contents. Change one balance and the hashes along the path from that leaf to the top change, up to the state root in the block header.
The payoff is proofs. A node can hand a stranger the short list of tree nodes between an account and the root, and anyone holding the block header can check that the balance is what the node claims. An eth_getProof request to a public Ethereum node on 10 November 2026 returned, for one ordinary address, an account proof of nine nodes. Each contract’s storage forms its own trie of the same kind, which is why a token balance is ultimately a leaf in the token contract’s storage tree. The data adds up: the EIP-8037 proposal states that Geth’s state database was about 390 GiB as of January 2026.

Binary tree, Verkle tree or neither: the next state tree is still a draft
The hexary trie has a cost. Proofs are long, because every level can carry up to 15 sibling hashes, and Keccak is slow to prove inside zero-knowledge circuits. For years the official plan was a Verkle tree, and ethereum.org’s roadmap page still describes it that way. Since January 2025 a rival design has been on the table: EIP-7864, “Ethereum state using a unified binary tree”, written by Vitalik Buterin, Guillaume Ballet, Dankrad Feist and others.
EIP-7864 would start a new binary tree that holds account data, code and storage together, while the existing trie is frozen and later migrated by a separate proposal. Its authors argue that a hash-only tree gives smaller proofs, suits zero-knowledge proofs better and avoids the elliptic-curve cryptography that Verkle trees rely on, which quantum computers could one day break. The hash function is not chosen: the draft uses BLAKE3 for testing and names Keccak and Poseidon2 as candidates. As of 10 November 2026 the EIP is still a Draft and no named upgrade schedules any change to the state tree.
How the Ethereum Virtual Machine works: a stack machine of 256-bit words
Bytecode: what a contract really is on-chain
On-chain, a smart contract is nothing more than a string of bytes stored at an address. The USDC token address on Ethereum, 0xA0b8…eB48, held 2,186 bytes of code on 10 November 2026. Since the Spurious Dragon upgrade of 22 November 2016 (block 2,675,000), EIP-170 caps deployed code at 24,576 bytes. EIP-7954, scheduled for the Glamsterdam upgrade (status Last Call, review deadline 1 November 2026), would raise that cap to 64 KiB, or 65,536 bytes, and the limit on initialisation code from 48 KiB to 128 KiB.
Each instruction, or opcode, is one byte. 0x01 is ADD, 0x55 is SSTORE, 0x00 is STOP. A few opcodes carry data inline: PUSH1 (0x60) is followed by one byte to place on the stack, and so on up to PUSH32, which carries 32. A contract written in Solidity or Vyper is compiled into this format, as our guide to learning Solidity shows from the developer’s side.
When a transaction calls a contract, its input data (calldata) usually starts with a 4-byte function selector, the first four bytes of the Keccak-256 hash of the function’s signature. 0xa9059cbb, for instance, is transfer(address,uint256), the function behind most token transfers. The contract’s first instructions read those four bytes and jump to the matching piece of code. There is no other dispatch mechanism.
The stack: 1,024 slots of 256 bits
It is a stack machine with a depth of 1,024 items, and each item is a 256-bit word. Ethereum.org explains the word size by the cryptography the chain uses every day: Keccak-256 hashes and secp256k1 keys both fit in 256 bits. Most opcodes take their inputs from the top of the stack and push their result back. ADD pops two words and pushes their sum, modulo 2^256.
The machine has no registers. DUP and SWAP instructions reach only the 16 topmost items, a limit that EIP-8024 (scheduled for Glamsterdam) would lift with three new instructions, SWAPN, DUPN and EXCHANGE. Pushing a 1,025th item, or popping from an empty stack, stops the current execution with an error.
Five places to keep data, five lifetimes
Contract code works with several data areas. They differ by how long they last and by what they cost, and that difference shapes how every contract is written.
| Data area | What it holds | Lifetime | Typical cost (gas) | Who can write it |
|---|---|---|---|---|
| Stack | Up to 1,024 words of 256 bits | One call frame | 2 to 3 per simple opcode | The running code |
| Memory | A byte array that grows as it is used | One call frame | 3 per word access, plus a growing expansion charge | The running code |
| Storage | Key-value pairs of 256-bit words, per contract | Permanent, part of the world state | 2,100 for a first (cold) read, 100 warm; 22,100 to fill an empty slot cold | Only code running in that contract’s context |
| Transient storage | Key-value pairs per contract | One transaction | 100 per TLOAD or TSTORE | Only code running in that contract’s context |
| Calldata | Read-only input bytes of the call | One call frame | Paid by the sender as part of intrinsic gas | The caller |
Transient storage is the newest area. It came with EIP-1153 in the Dencun upgrade of 13 March 2024 (on the execution side, Cancun) and adds two opcodes, TLOAD (0x5c) and TSTORE (0x5d). The EIP puts its lifetime plainly: “All values in transient storage are discarded at the end of the transaction.” It costs a fraction of storage and is used for reentrancy locks or to pass data between contracts within one transaction. Two read-only areas complete the picture: the return data of the last call, and the contract’s own code.
A nine-byte program, run by hand
The quickest way to see the machine is to run a tiny program. The nine bytes 0x600260030160005500 add 2 and 3 and store the result in storage slot 0. Anyone can reproduce the run with the eth_call method of a public node and a state override that places this code at an empty address.
60 02 PUSH1 0x02
60 03 PUSH1 0x03
01 ADD
60 00 PUSH1 0x00
55 SSTORE
00 STOP
| Step | Opcode | Stack after (top first) | Gas charged | Execution gas so far |
|---|---|---|---|---|
| 1 | PUSH1 0x02 | [2] | 3 | 3 |
| 2 | PUSH1 0x03 | [3, 2] | 3 | 6 |
| 3 | ADD | [5] | 3 | 9 |
| 4 | PUSH1 0x00 | [0, 5] | 3 | 12 |
| 5 | SSTORE (key 0 on top, value 5) | [] | 22,100 | 22,112 |
| 6 | STOP | [] | 0 | 22,112 |
SSTORE takes the key from the top of the stack and the value below it, so the order of the pushes matters. Four cheap instructions cost 12 gas in total; the single storage write costs 22,100, because the slot is touched for the first time in the transaction (2,100) and goes from zero to a non-zero value (20,000). Add the 21,000 gas every transaction pays before any code runs and the bill is 43,112 gas. On 10 November 2026 a public node accepted the call with a 43,112 gas limit and refused it with 43,111, answering “out of gas”.
Five more micro-programs, run the same way on the same day, price the other data areas. The figures below are execution gas, after the 21,000 base.
| Program | What it does | Execution gas measured (10 Nov 2026) |
|---|---|---|
| 0x60005400 | Read storage slot 0 once (cold) | 2,103 |
| 0x600054506000545000 | Read slot 0 twice | 2,210 (2,100 cold, then 100 warm) |
| 0x600160005d00 | Write 1 to transient slot 0 | 106 |
| 0x60005c5000 | Read transient slot 0 | 105 |
| 0x600160005200 | Write one word to memory | 12 (9 for the opcodes, 3 to grow memory by one word) |
Compare the rows: filling an empty storage slot cost 22,100 gas, a transient write 100, a ratio of 221 to 1. Contract designers spend much of their effort avoiding SSTORE.
Why every instruction has a price
Gas is a meter before it is a fee
The 2014 white paper was frank about the risk of a programmable chain: the EVM is Turing-complete, and “this means that EVM code can encode any computation that can be conceivably carried out, including infinite loops”. Nobody can predict in general whether a program will stop (the halting problem), so Ethereum does not try. Each transaction sets a gas limit; the machine deducts the price of every opcode before running it; when the counter would go below zero, execution stops with an out-of-gas error, the state changes of that call are undone and the gas is still consumed. A loop that never ends simply runs out of gas. The history lesson tells how that idea was born; the mechanism above is what it became.
Prices are part of the protocol. Go Ethereum’s source code lists the values in force, and the EIPs explain where they come from.
| Operation | Gas (mainnet rules in force on 10 November 2026) | Source |
|---|---|---|
| ADD, PUSH1, MSTORE (base) | 3 each | ethereum.org opcode reference |
| KECCAK256 | 30 plus 6 per 32-byte word hashed | Go Ethereum protocol parameters |
| LOG0 to LOG4 | 375, plus 375 per topic, plus 8 per byte of data | Go Ethereum protocol parameters |
| SLOAD | 2,100 cold, 100 warm | EIP-2929 |
| Account access (CALL, BALANCE, EXTCODESIZE…) | 2,600 cold, 100 warm | EIP-2929 |
| CALL sending ETH | 9,000 extra; 25,000 extra if the recipient account does not exist | Go Ethereum protocol parameters |
| CREATE, CREATE2 | 32,000, plus 200 per byte of code deployed and 2 per 32-byte word of initialisation code; CREATE2 adds 6 per word to hash that code | Go Ethereum protocol parameters |
| Transaction base (intrinsic) | 21,000 | Go Ethereum protocol parameters |
The cold and warm prices have a history. EIP-2929, activated with the Berlin upgrade on 15 April 2021 (block 12,244,000), raised the cost of the first access to an account or a storage slot in a transaction after the denial-of-service attacks of 2016. The EIP cites replays in which the attack transactions took 20 to 80 seconds to execute, against a few milliseconds for an average one, and says that raising those prices by a factor of about 3 cuts the worst case to about 7 to 27 seconds. A scan of Goerli testnet transactions, it adds, put the average rise in gas costs at about 2.36%.
What a user finally pays is the gas used multiplied by a price per unit of gas, made of a base fee that is burned and a tip to the validator. That mechanism, EIP-1559 and the history of fees belong to our next lesson on gas and EIP-1559. For the machine, two limits matter. Block 26,383,691, produced at 09:43 UTC on 10 November 2026, had a gas limit of 60 million, the default that client teams adopted with Fusaka (EIP-7935), and used 33.57 million, with a base fee of 0.0549 gwei. Since the Fusaka upgrade of 3 December 2025, EIP-7825 also caps any single transaction at 16,777,216 gas (2^24).
Deterministic by construction
For thousands of nodes to agree on one state root, every instruction must give the same result everywhere. The EVM therefore has no floating-point numbers, no access to the network, no file system and no clock other than the timestamp of the current block. Anything a contract learns about the outside world, a price for example, has to be written on-chain by a transaction, which is the job of an oracle.
That strictness is what allows independent codebases, in Go, C#, Java and Rust, to run the same blocks and land on the same state root. The clients also check themselves against shared test suites: ethereum.org notes that every execution client it lists passes the client tests. A user sending a transaction through a public node has no way to tell which client executed it, and has no need to.
When contracts call contracts
CALL, STATICCALL and DELEGATECALL decide whose storage changes
A contract can call another contract in the middle of its own execution. Each call opens a new frame with its own stack and memory. Three opcodes do most of the work, and the choice between them decides whose data the called code can touch.
| Opcode (byte) | Code that runs | Storage that changes | Sender seen by the callee | Can it modify state? |
|---|---|---|---|---|
| CALL (0xF1) | The target’s | The target’s | The calling contract | Yes, and it can send ETH |
| STATICCALL (0xFA) | The target’s | None | The calling contract | No: any attempt to modify state fails |
| DELEGATECALL (0xF4) | The target’s | The caller’s | The caller’s own caller | Yes, but in the caller’s storage |
Go Ethereum’s source describes DELEGATECALL as executing the target’s code “with the caller as context”, the sender being set to “the caller of the caller”. In plain words, the calling contract borrows another contract’s logic and runs it on its own data.
That is how upgradeable proxies work. The 2,186 bytes at the USDC address are a proxy: they hold the balances in their own storage and forward every call by DELEGATECALL to a separate logic contract, whose address is kept in one of the proxy’s storage slots. On 10 November 2026 that slot pointed to 0x4350…02dd. Replace the address in the slot and the same token runs new code. Who holds that power is a governance question we leave to the later lesson on upgradeable contracts and admin keys.
A call that sends ETH also passes a stipend of 2,300 gas to the recipient, too little to write to storage. Old contracts that rely on that exact figure are one reason the Glamsterdam repricing, described below, is delicate.
CREATE and CREATE2: where new contracts land
New contracts are born from running initialisation code, whose output becomes the stored code. With CREATE (0xF0), the new address is derived from the creator’s address and nonce. With CREATE2 (0xF5), added by EIP-1014 in the Constantinople upgrade of 28 February 2019 (block 7,280,000), it is derived from the creator’s address, a salt chosen by the creator and the hash of the initialisation code. The result is an address that can be computed, and even funded, before the contract exists, which smart wallets and factory contracts use widely.
Deleting code has changed too. Since Dencun, EIP-6780 makes SELFDESTRUCT delete an account only when it is called in the same transaction that created the contract; otherwise it merely sends the balance away. Glamsterdam’s list adds EIP-8246, titled “Remove SELFDESTRUCT Burn”.
The Pectra upgrade of 7 May 2025 added a twist to the code hash of EOAs. With EIP-7702, an EOA can sign an authorisation that writes a 23-byte delegation designator, 0xef0100 followed by a contract address, into its own code field. Calls to the EOA then run the delegated contract’s code in the EOA’s context. On 10 November 2026 such a designator sat in the code of at least one well-known mainnet address. You can check your own address the same way: an eth_getCode result starting with 0xef0100 means it is delegated.
Precompiles: native code at the lowest addresses
Some operations would be too slow or too costly in EVM bytecode, so the protocol provides them as precompiled contracts at fixed addresses. They are called like any contract but run as native code inside each client. EIP-2929 counts them as warm from the start of every transaction.
| Address | Function | Arrived with |
|---|---|---|
| 0x01 | ecrecover: recovers the signer of a secp256k1 signature | From launch, 2015 |
| 0x02 to 0x04 | SHA-256, RIPEMD-160, identity (data copy) | From launch, 2015 |
| 0x05 | MODEXP: modular exponentiation | Byzantium, 16 October 2017 |
| 0x06 to 0x08 | alt_bn128 curve: addition, multiplication, pairing check | Byzantium, 16 October 2017 |
| 0x09 | BLAKE2 compression function F | Istanbul, 8 December 2019 |
| 0x0a | KZG point evaluation (blob proofs) | Cancun, 13 March 2024 |
| 0x0b to 0x11 | Seven BLS12-381 curve operations | Prague (Pectra), 7 May 2025 |
| 0x100 | P256VERIFY: checks secp256r1 (P-256) signatures | Osaka (Fusaka), 3 December 2025 |
The list comes from the precompile sets in Go Ethereum’s source code, one set per fork. Precompiles matter outside Ethereum too: chains that call themselves EVM-compatible do not always ship the same set, and a contract that depends on one may fail elsewhere.
One transaction, from signature to receipt
Checks before any code runs
A transaction is one of five types: 0 (legacy), 1 (access lists, EIP-2930), 2 (EIP-1559 fees, now the standard), 3 (blob transactions, EIP-4844) and 4 (EIP-7702 authorisations). Before a single opcode runs, the client checks that the signature recovers a sender, that the nonce matches the sender’s account, that the balance covers the gas limit multiplied by the maximum fee plus any ETH sent, and that the gas limit covers the intrinsic gas: 21,000, plus charges for calldata, access lists and contract creation. Since Fusaka the gas limit must also stay at or under 16,777,216. A transaction that fails these checks is not included at all and costs nothing.
Execution, revert and commit
Once these checks pass, the sender’s nonce goes up, the gas is paid for in advance and the EVM runs the target’s code. Execution ends with STOP or RETURN (success), with REVERT (0xFD, a deliberate failure that can return an error message) or with an exceptional halt such as out-of-gas or an invalid opcode. A failure undoes every state change of the failing frame, transient storage included, but not the gas spent. A failed transaction still appears in its block, still increments the nonce and still pays.
Clearing storage earns a partial gas refund, capped since the London upgrade of 5 August 2021 at one fifth of the gas used (EIP-3529). Glamsterdam’s list includes EIP-7778, which stops counting refunds when measuring how full a block is.
Wallets ask a node to estimate the gas a transaction needs, with the eth_estimateGas call, and the answer usually exceeds the real use. For our nine-byte program the estimate on 10 November 2026 was 43,488 gas, against 43,112 actually needed. The margin is deliberate: a transaction that runs out of gas fails and still pays for the gas it burned.
Receipts and logs: what a transaction leaves behind
Every transaction produces a receipt: its status (1 for success, 0 for failure), the gas it used and the logs it emitted. Logs are written by the LOG0 to LOG4 opcodes. Contracts cannot read them; they exist for wallets, explorers and apps, and they are far cheaper than storage. The block header commits to all receipts through a receipts root, just as it commits to the state.
A live example: transaction 0x7c26…416b, in block 26,383,708 on 10 November 2026, called the USDT contract with the selector 0xa9059cbb. It set a gas limit of 64,043, used 63,209 and succeeded. Its receipt holds one log from the USDT contract. The first topic, 0xddf2…b3ef, is the Keccak-256 hash of Transfer(address,address,uint256); the second and third topics are the sender and recipient; the data field is the amount, 58,709,442 in raw units, which is 58.709442 USDT since the contract reports six decimals. Our guide on how to read a block explorer shows where these fields appear on Etherscan.
Who runs the machine: five execution clients and one consensus link
Geth, Nethermind, Besu, Erigon and Reth, counted in different ways
As a specification, the EVM does nothing on its own. It runs inside execution clients, the programs that receive transactions, execute them and hold the state. Ethereum.org lists Geth (Go), Nethermind (C# .NET), Besu (Java), Erigon (Go) and Reth (Rust), plus the newer ethrex (Rust). Our guide to what a node is explains how they fit on a machine.
How many nodes run each client is harder to say than it sounds. The sources measure different things and do not agree.
| Source (pages read on 10 Nov 2026) | What it measures | Geth | Nethermind | Besu | Reth | Erigon |
|---|---|---|---|---|---|---|
| Ethernodes, shown on clientdiversity.org, updated daily | Nodes visible to a crawler with free peer slots | 50.13% | 25.46% | 9.45% | 7.67% | 6.53% |
| supermajority.info, shown on clientdiversity.org, updated manually | Operators’ self-reports, 59.4% of the network covered, much of it more than a year old | 43% | 43% | 8% | 3% | 3% |
| supermajority.info snapshot of 26 Oct 2025, shown on ethereum.org | Operators’ self-reports | 41% | 38% | 16% | 2% | 3% |
Clientdiversity.org itself warns that the Ethernodes numbers reflect which clients show free peers and that it is “not well understood” how this relates to what operators actually run and calls survey data from execution-diversity.info the most reliable source. Ethereum.org’s client-diversity page shows the October 2025 snapshot in the last row, while another sentence on the same page still gives Geth “around 85%” of nodes, a figure from earlier years. The fair summary: Geth has lost its old supermajority, and depending on the method it runs somewhere between four and five nodes in ten.
The Engine API: how the EVM takes orders since The Merge
Since The Merge of 15 September 2022 (block 15,537,394), an execution client no longer decides which block comes next. A separate consensus client, such as Lighthouse, Prysm, Teku, Nimbus, Lodestar or Grandine, runs proof of stake and tells the execution client what to do through the Engine API: engine_newPayload hands it a block to execute and check, and engine_forkchoiceUpdated tells it which chain head to follow or asks it to build a block. The Engine API specification says the consensus layer “drives” the execution layer, on a dedicated port (8551 by default) protected by JWT authentication. How the consensus side works is the subject of our later lesson on The Merge and proof of stake.
Why one client’s bug matters: the one-third and two-thirds lines
On the consensus layer the thresholds are arithmetic. According to ethereum.org, a bug in a consensus client used by more than a third of nodes could stop the chain from finalising, and a critical bug in a client with a two-thirds majority could finalise an invalid chain, leaving its validators stuck and exposed to slashing. Clientdiversity.org sets the same goal for every client, a share under 33%, and says the risks “apply to both consensus clients and execution clients equally”.
The Reth episode of November 2026 shows the other side of the coin. Reth runs on 2% to 8% of Ethereum nodes depending on the count in the table, far from the one-third line. Base, BNB Chain’s BSC-Reth and Tempo, on the other hand, run Reth-based nodes, and for them the same bug was a reason to patch within days. The risk of a client bug depends on how many nodes of a given network run that client.

The same machine on other chains
EVM-compatible, EVM-equivalent and the chain ID
Because the EVM is a published specification with several open-source implementations, dozens of other networks run it. DefiLlama’s chain list, read on 10 November 2026, tracks 422 chains, of which 238 have a chain ID recorded, the number EVM wallets use to tell networks apart. The largest by total value locked, per DefiLlama at the same date, are shown below.
| Chain | Value locked per DefiLlama (10 Nov 2026) | Chain ID | Note |
|---|---|---|---|
| Ethereum | $41.74 billion | 1 | The reference EVM |
| Base | $5.72 billion | 8453 | Layer 2 built on the OP Stack |
| BNB Smart Chain | $5.10 billion | 56 | Its own validator set |
| Arbitrum | $1.40 billion | 42161 | Optimistic rollup |
| Monad | $0.94 billion | 143 | Separate layer 1 |
| Polygon | $0.62 billion | 137 | Polygon PoS chain |
| Avalanche | $0.61 billion | 43114 | C-Chain |
The chain ID is signed into every modern transaction (EIP-155, also from Spurious Dragon), so a transaction valid on one network cannot be replayed on another. Addresses, on the other hand, use the same 20-byte format on every EVM chain. The same private key controls the same address on Ethereum, Base or BNB Chain, which is convenient and also why funds sent on the wrong network can reach an address its owner never meant to use there.
“EVM-compatible” means a chain runs the same bytecode with the same core semantics. It does not promise identical gas prices, precompiles, block times or the latest opcodes. Rollups that settle on Ethereum, compared in our guide to layer 1 and layer 2, tend to track mainnet closely; our later lesson on layer 2 will go further.
Vitalik Buterin’s zkEVM types 1 to 4
Zero-knowledge rollups face a harder version of the question, because they must prove EVM execution, and some of its features are expensive to prove. In a post of 4 August 2022, Vitalik Buterin sorted zkEVMs into types. “Type 1 ZK-EVMs strive to be fully and uncompromisingly Ethereum-equivalent,” he wrote; each type after it trades some equivalence for faster proofs.
| Type | What it keeps and what it changes |
|---|---|
| 1 | Ethereum exactly, including hashes and state trees: slowest to prove |
| 2 | EVM-equivalent, but changes outer structures such as the state tree to speed up proofs |
| 2.5 | Like type 2, with higher gas prices for operations that are hard to prove |
| 3 | Almost equivalent: drops or alters a few features, such as some precompiles |
| 4 | Compiles Solidity or Vyper source to a proof-friendly language, bypassing EVM bytecode |
The classification dates from 2022, and projects have moved between types since. Which network sits in which type today is for each project’s own documentation to show.
How the EVM keeps changing
Fork by fork: the upgrades that changed the machine
Ethereum’s machine has never been frozen. The table lists the upgrades that changed it most, with dates and blocks from ethereum.org’s history page and the content from the EIPs.
| Upgrade | Date (UTC) and block | What changed in the EVM |
|---|---|---|
| Spurious Dragon | 22 Nov 2016, block 2,675,000 | 24,576-byte code limit (EIP-170), chain ID in signatures (EIP-155) |
| Byzantium | 16 Oct 2017, block 4,370,000 | MODEXP and alt_bn128 precompiles |
| Constantinople | 28 Feb 2019, block 7,280,000 | CREATE2 (EIP-1014) |
| Istanbul | 8 Dec 2019, block 9,069,000 | BLAKE2 precompile |
| Berlin | 15 Apr 2021, block 12,244,000 | Cold and warm access prices (EIP-2929), access lists (EIP-2930) |
| London | 5 Aug 2021, block 12,965,000 | EIP-1559 fees, refunds capped (EIP-3529) |
| Shanghai (Shapella) | 12 Apr 2023, block 17,034,870 | PUSH0 (EIP-3855), initcode limit (EIP-3860) |
| Cancun (Dencun) | 13 Mar 2024, block 19,426,587 | Transient storage, MCOPY, SELFDESTRUCT restricted, blobs and KZG precompile |
| Prague (Pectra) | 7 May 2025, block 22,431,084 | EOA code delegation (EIP-7702), BLS12-381 precompiles |
| Osaka (Fusaka) | 3 Dec 2025, block 23,935,694 | CLZ opcode, P256VERIFY, per-transaction gas cap, 60M default block gas limit |
Glamsterdam: a repricing that could break contracts with hard-coded gas
The next upgrade, Glamsterdam, has a scheduled list in its meta EIP-7773. Besides its headline features, enshrined proposer-builder separation (covered in our guide to MEV protection and PBS) and block-level access lists, it touches the EVM directly: a SLOTNUM opcode (EIP-7843), the deeper stack instructions of EIP-8024, larger contracts (EIP-7954), a log for every ETH transfer (EIP-7708) and a new gas schedule.
The new schedule is the sensitive part. EIP-8037 prices the creation of state by the byte: 1,530 gas per new byte of state. A new account counts as 120 bytes, so 183,600 gas against 25,000 under the current rules; a new storage slot counts as 64 bytes, 97,920 gas against 20,000. EIP-8038 raises the cost of reading and writing existing state. Both EIPs were in Last Call status on 10 November 2026. The Ethereum Foundation’s post of 24 August 2026 says the new schedule is derived from a target of roughly three times more base throughput, and that replaying historical mainnet transactions under it shows “a small set of smart contracts” relying on assumptions it shifts. “Most flagged issues are fixed with a gas-limit increase,” the post adds. The contracts that can break even with more gas are those that rely on fixed stipends such as the 2,300 gas of Solidity’s transfer and send, hard-code gas values in calls, branch on the remaining gas or depend on pre-signed transactions with fixed gas limits.
Not everyone is reassured. On 8 November 2026 two developers filed rival drafts to protect old contracts, as our report on the rival Glamsterdam proposals details: pull request 12638 by Leo Glisic would version opcodes so that existing contracts keep the old prices, and pull request 12637 by Giulio Rebuffo would separate the gas a contract sees from the gas it is billed. Both were still open on GitHub on 10 November 2026, without client code. Core developers meet on 12 November (ACDC #191) and 19 November (ACDE #249), and Glamsterdam has no mainnet date.
EOF: in neither Fusaka nor Glamsterdam
The EVM Object Format (EOF) was a long-prepared plan to wrap bytecode in a structured container that separates code from data and is validated at deployment. It is in neither Fusaka’s final list (EIP-7607) nor Glamsterdam’s scheduled list (EIP-7773), and its meta EIP, EIP-7692, is marked Stagnant as of 10 November 2026.
RISC-V: a 2025 proposal, not a plan
On 20 April 2025, Vitalik Buterin posted on the Ethereum Magicians forum a long-term proposal to “replace the EVM with RISC-V as the virtual machine language that smart contracts are written in”. Accounts, storage and calls between contracts would stay as they are; opcodes such as SLOAD, SSTORE and CALL would become system calls; old EVM contracts would keep working and interoperate with new ones. His reason is proving: he wrote that block execution makes up roughly half of the work done by zero-knowledge provers at the time, so a VM closer to what provers already use would help. Replies in the thread point out that the EVM works natively with 256-bit numbers, which a RISC-V machine would have to split into smaller pieces, at a cost in speed. As of 10 November 2026 the idea is in no upgrade’s list.
What the machine means for users, developers and courts
For a developer, the EVM’s cost model is the design brief: every storage slot avoided saves thousands of gas, and every hard-coded gas figure is a bet on a schedule that Glamsterdam is about to change. For a user, two habits follow from this lesson. A failed transaction still costs gas, so a wallet warning that a transaction will fail deserves attention. And a quick eth_getCode on your own address, or the code tab of an explorer, tells you whether it carries an EIP-7702 delegation you did not intend.
Code with no owner has also reached the courts. On 26 November 2024, in Van Loon v. Department of the Treasury, the US Court of Appeals for the Fifth Circuit held that “Tornado Cash’s immutable smart contracts (the lines of privacy-enabling software code) are not the ‘property’ of a foreign national or entity”, so OFAC could not block them under the sanctions statute IEEPA, as the opinion states. The opinion explains that the developers gave up their control over the smart contract holding reserves of two or more tokens, supplied by users, that a decentralized exchange uses to execute trades automatically at a price set by a formula.">pool contracts in a 2020 “trusted setup ceremony”, after which those contracts became irreversibly immutable. On 21 March 2025 the Treasury removed Tornado Cash from its sanctions list, citing “the novel legal and policy issues” raised by sanctioning it. The holding is about immutable contracts; a proxy whose logic can be swapped, like the one behind USDC, was not before the court.
The next dates to watch are the core developers’ calls of 12 November (consensus) and 19 November 2026 (execution), both with Glamsterdam on the agenda. Whatever they settle on the gas schedule will become part of the function that turns one state root into the next.



