Zelcore

Accounts, Contracts, and the EVM: How Ethereum Actually Executes

10 min read
Accounts, Contracts, and the EVM: How Ethereum Actually Executes

Every Ethereum address is a row in a giant table. The table has four columns — nonce, balance, storageRoot, codeHash — and the entire protocol exists to mutate those rows, one signed transaction at a time, with every full node in the world replaying the same mutations to stay in lockstep. That is the whole model. Everything else — tokens, DeFi, NFTs, rollups — is code living in a few million of those rows, triggered by calls from the others.

This is a sharp departure from how Bitcoin tracks balances with UTXOs, where there are no account rows at all — only a forest of unspent transaction outputs that wallets sum up client-side. Ethereum swapped that forest for a table, and in exchange got arbitrary programmability. Part 1 covered ETH's supply history and The Merge; this part opens the hood on what actually executes when you sign a transaction.

Two account types, one world state

Ethereum's world state is a mapping from 20-byte addresses to account state, maintained as a modified Merkle Patricia Trie that the protocol updates every block. When you hear developers talk about "state," this is what they mean: a single authenticated dictionary keyed by address, with a root hash committed into each block header so everyone can prove what the balance table looked like at a given block.

Every account — whether a human's wallet or a Uniswap pool — stores the same four fields:

Those two defaults — empty storageRoot, empty codeHash — define an Externally-Owned Account (EOA). An EOA is controlled by a private key; whoever holds the key can sign transactions from that address. Under the hood, addresses are derived from ECDSA public keys, the same public-key cryptography that backs an EOA wallet on any chain.

A contract account is everything else: an address whose codeHash points to bytecode and whose storageRoot points to a populated trie. Contract accounts cannot initiate transactions. They sit dormant until someone calls them — and only then do their opcodes execute, reading and writing their storage slots as directed.

Compare with Bitcoin: there is no "balance" field on Bitcoin. Your wallet shows a number, but that number is computed by scanning every UTXO you can spend. On Ethereum, balance is a literal column the protocol reads and writes directly — cheaper to query, but the state table grows monotonically with every new address ever funded.

What a transaction actually mutates

Only EOAs originate transactions. A transaction is a signed payload — a nonce, a destination, a value, calldata, gas limit, fee parameters, a signature — and the signature must be valid for the sender's EOA. Contract accounts never sign anything; they only respond when called, and their responses happen inside an EOA-initiated transaction.

The nonce is how Ethereum blocks replay. Each transaction carries a nonce that must equal the sender's current account nonce. A successful transaction increments it by exactly one. Broadcast the same signed payload twice and the second broadcast gets rejected — its nonce no longer matches. This replaces Bitcoin's UTXO-based replay protection (a UTXO can only be spent once by definition) with a counter-based one (a nonce can only be used once per account).

A successful transaction can mutate:

What it doesn't mutate directly: storageRoot and codeHash. Those are recomputed by the protocol after writes. A contract's bytecode is fixed at deployment; only its storage changes.

Bytecode and the EVM stack machine

The Ethereum Virtual Machine (EVM) is a stack-based virtual machine with a maximum stack depth of 1,024 items, where every item is a 256-bit word. Every contract is a sequence of bytes — opcodes — and execution is a loop: fetch the next opcode, pop its operands from the stack, execute, push the result.

A stack machine means there are no registers and no named variables at the bytecode level. Want to add two numbers? Push both onto the stack, execute ADD, and the two operands are replaced by their sum. The 256-bit word size was chosen to fit a cryptographic hash or an address with room to spare, which makes hashing primitives first-class.

Opcodes cluster into families:

During execution, a contract has four data regions to play with. The stack is transient and tops out at 1,024 words. Memory is a transient byte array that grows as you write to it, charged per word used. Storage is the persistent key-value store anchored in the account's storageRoot — this is the expensive region, because every write permanently changes the state trie. And calldata is the read-only input from the caller: the ABI-encoded function selector plus arguments. Cancun added a fourth, transient storage (TSTORE/TLOAD), which persists across calls within one transaction and then vanishes — useful for reentrancy locks and multi-call scratchpads.

Gas: pricing computation per opcode

Every opcode has a gas cost, and the sender prepays for all of them with a gasLimit. Cheap opcodes (ADD = 3, PUSH = 3) are pure CPU work. Expensive ones pay for state that every node must persist. If you are new to this layer, gas, approvals, and wallet fundamentals covers the user-facing side; here we are looking at where the numbers come from.

Before any opcode runs, there is an intrinsic gas cost: 21,000 gas for any transaction, plus calldata charges of 4 gas per zero byte and 16 gas per non-zero byte. Then execution begins and each opcode is metered until either the transaction completes, reverts, or runs out of gas — at which point the protocol halts, the state changes revert, but the sender still pays all gas consumed. This is how Ethereum sidesteps the Halting Problem: it can't statically detect infinite loops, so it charges per step and kills runaway programs.

The pricing model also distinguishes between cold and warm access, introduced in EIP-2929 (Berlin, 2021). The first time a transaction touches a particular storage slot or account, the access is cold and expensive:

The pattern: the first load or write of the transaction caches the trie lookup; subsequent accesses in the same transaction are cheap. That is why batched operations often cost dramatically less per action than the same operations spread across separate transactions.

Worked example: an ERC-20 transfer

An ERC-20 token isn't a coin — it's a contract with a balance map. When you send USDC, you're not moving a token; you're calling USDC's contract and asking it to decrement one slot in its balances map and increment another. An ERC-20 transfer(address,uint256) call typically lands in the 40,000–65,000 gas range, with the spread driven almost entirely by whether the recipient's slot is cold or warm.

Walk through the bill for a first-touch transfer to a recipient who has never held that token:

Add it up and you are in the mid-40,000s for the cold case, which matches what block explorers show for a first-touch USDC send. If the recipient had already held the token — meaning the slot was non-zero — the big SSTORE drops from 22,100 to 2,900 and the whole transfer lands closer to 30,000 gas. Batch ten transfers to the same recipient and only the first pays cold pricing.

The Transfer event is worth calling out. Logs live in the receipt trie, not the state trie — they are historic records, not queryable state. That's why they're much cheaper than SSTORE and why indexers like Etherscan rebuild token balance history by streaming Transfer events rather than scanning storage. The same mechanism fires when minting an NFT is a contract state mutation: a Transfer event from the zero address to the owner.

Account abstraction ahead

The EOA-versus-contract dichotomy isn't as rigid as it used to be. EIP-7702 activated on Ethereum mainnet with the Pectra upgrade on May 7, 2025, and lets an EOA delegate to contract code — the account can temporarily execute smart-contract logic while keeping the same address and key.

Mechanically, an EOA can sign a delegation that writes an indicator — 0xef0100 followed by a contract address — into its own code slot. From then on, calls to that EOA follow the pointer and execute the target contract's code in the EOA's context. The balance and nonce still live at the EOA's address; only the code is borrowed. The user can revoke the delegation at any time by signing another delegation, including one that points back to the zero address.

The practical effect is that a regular wallet can now batch an ERC-20 approve plus a swap into a single atomic transaction, have a third party pay its gas (sponsorship), or delegate limited privileges to session keys. For roughly two years account abstraction was a separate ERC-4337 track for smart-contract wallets only (the ERC-4337 EntryPoint went live on mainnet in March 2023); EIP-7702 folds those features back into the humble EOA that most users already have.

Key takeaways

Part 3 turns to the fee market itself — how EIP-1559 split transactions into a base fee plus a priority tip, what the base-fee burn does to supply, and where blob fees fit in after Dencun.


Further Reading

How a Blockchain Transaction Works, Step by Step

How a Blockchain Transaction Works, Step by Step

Traces a single send from the moment you hit confirm through signing, broadcast, the mempool, block inclusion, and final confirmation — so you understand why it takes time and why fees exist.

7 min read
Transaction Fees Explained: Why You Pay Them and How to Estimate Them

Transaction Fees Explained: Why You Pay Them and How to Estimate Them

What transaction fees actually pay for, why they spike during congestion, and how to use a fee estimator to avoid overpaying on Bitcoin and Ethereum.

7 min read
What Is Cryptocurrency? Coins, Tokens, and the Difference

What Is Cryptocurrency? Coins, Tokens, and the Difference

Clarifies the often-confused distinction between native coins (like BTC or ETH) and tokens issued on top of an existing chain, with practical examples and real-world implications.

7 min read

Join Our Newsletter

Get a friendly update from us once a month. No spam, just the latest from Zelcore.

Join Our Newsletter
    Ethereum Account Model and EVM Explained | Zelcore