What a Contract Actually Is
The part overview promised to demystify the phrase “smart contract.” This page does exactly that, and the demystification is deliberately deflationary: a smart contract is not a legal document, an AI, or an agent. It is an account — the same kind of entry in the world-state map that a wallet is — with one extra field filled in.
Everything else in this part builds on that single reframing. Solidity is a language that compiles down to the bytecode this page describes; the ABI and selectors are the convention for picking which function of that bytecode to run; storage layout is the rulebook for the storage map introduced here. So before any of that, we answer the most basic possible question with total precision: what, concretely, is the thing sitting at a contract address?
A contract is three things in one account
Section titled “A contract is three things in one account”Recall from Accounts and State that Ethereum’s world state is a map from a 20-byte address to an account record. A contract is one of those records. Concretely, a contract account is three things bundled together:
contract account @ 0xA1B2… (an entry in the world-state map) ┌───────────────────────────────────────────────┐ │ code : immutable EVM bytecode ← set ONCE │ │ storage : key → value map ← code r/w │ │ balance : ETH (in wei) ← can hold │ │ nonce : counter (for CREATE) │ └───────────────────────────────────────────────┘- Immutable EVM bytecode — a frozen array of bytes, the compiled program. It is written once, at deploy time, and can never be changed afterward. This is the “code” of the contract.
- A persistent storage map — a key-value store,
slot → word, that the bytecode can read and write while it runs. This is the contract’s private memory, and — crucially — it survives between calls. - A balance — the contract can hold ETH, denominated in wei, exactly like a wallet can. Code can send that ETH elsewhere and can receive more.
The book’s companion crate, ethmini, models an account with precisely these fields, and its comments name the load-bearing insight:
pub struct Account { pub nonce: u64, pub balance: u128, // native currency, in the smallest unit pub storage: BTreeMap<u64, u64>, // the contract's persistent key/value memory pub code: Vec<u8>, // the contract's bytecode}
// The presence of code is the *only* thing that distinguishes a// contract from a wallet.pub fn is_contract(&self) -> bool { !self.code.is_empty()}Read that last comment twice. In Ethereum there is no separate “contract table” and “wallet table.” There is one account map, and whether an account is a contract is decided by a single test: does it have code? Everything mystical about “smart contracts” reduces to that one non-empty byte array.
Contract account vs. externally owned account
Section titled “Contract account vs. externally owned account”Ethereum has exactly two kinds of account, and the distinction is the cleanest way to understand what a contract is by contrast.
An externally owned account (EOA) — a wallet — is controlled by a private key. It has a balance and a nonce, but no code and no storage. It cannot do anything on its own; it is a passive holder of funds. The only way an EOA acts is when a human (or their software) signs a transaction with the matching private key. An EOA is the only kind of account that can originate a transaction, because originating one requires a signature, and only an EOA has a key to sign with.
A contract account is controlled by its code. It has no private key — nobody can “log in” as a contract or sign for it. Instead, a contract sits inert until something calls it: it is triggered by receiving a message (a transaction from an EOA, or a call from another contract). When triggered, its code runs, and that code decides what happens next.
EOA (wallet) CONTRACT ACCOUNT controlled by a private key its own bytecode has code? no yes ← the whole difference has storage? no yes (persistent key→value map) has balance? yes yes acts by... a human SIGNS a transaction RECEIVING a call, then running code can start a tx? yes (needs a signature) no (only reacts to being called)So the causal chain of everything that happens on Ethereum starts at an EOA — a human with a key signs a transaction. That transaction may target a contract, whose code may call another contract, and so on. But the spark is always a signature from a key-controlled wallet. Contracts are the machinery; EOAs are the only things that can pull the trigger. (Account abstraction, e.g. ERC-4337, blurs this in practice by letting smart-contract wallets act on a user’s behalf, but at the base protocol layer, only an EOA-signed transaction can enter the system.)
Calling a contract runs its code on every node
Section titled “Calling a contract runs its code on every node”Here is where a contract stops being “a struct with four fields” and becomes the world computer this book keeps promising. When you send a transaction to a contract’s address, you are not asking one server to run a program. You are asking every full node in the network to run that program, independently, and to agree on the result.
Recall the throughline from A Ledger Is Already a State Machine: Ethereum is a replicated, deterministic state machine. A call to a contract is just a transaction — an input to the transition function apply. Because the EVM that executes the bytecode is deterministic (no floating point, no wall clock, no true randomness), every node that runs the same code against the same storage, from the same starting state, computes bit-for-bit the same new world state.
the SAME call, fed to every full node:
node A: run bytecode(storage, calldata) ─▶ new storage, new balances ─▶ Sₙ node B: run bytecode(storage, calldata) ─▶ new storage, new balances ─▶ Sₙ node C: run bytecode(storage, calldata) ─▶ new storage, new balances ─▶ Sₙ │ all nodes MUST land on the identical SₙThis is why “calling a contract” is expensive: you are not buying one CPU’s worth of computation, you are buying thousands of strangers independently confirming the same result. That redundancy is the cost side of the book’s central question, and it is exactly why gas must exist — someone has to pay for all that duplicated work, metered by a rule every node computes identically.
Persistence: what makes it a contract, not a calculator
Section titled “Persistence: what makes it a contract, not a calculator”A contract could, in principle, do nothing but arithmetic and throw the answer away. What makes it a contract — a thing that remembers — is that its storage survives between calls.
The reason is not magic; it follows directly from the state-machine model. A contract’s storage map is part of the world state. When a call writes to storage, that write is committed into the world state, and the world state is what all nodes agree on and fingerprint with the state root (see State and Tries). Because the storage is the chain’s state, the next call — possibly in a different block, days later, from a different person — reads exactly what the last call left behind.
The classic minimal example is a counter. In ethmini its entire bytecode is six operations:
PUSH 0 ; slot 0 (the key) SLOAD ; read storage[0] ← the current count, or 0 if never set PUSH 1 ADD ; count + 1 PUSH 0 ; slot 0 again SSTORE ; storage[0] = count + 1 ← persist it STOPTwo opcodes carry the whole idea:
SLOADreads a slot from the account’s storage map. An unset slot reads as 0, so the counter starts at zero with no initialization code (real EVM has the same rule).SSTOREwrites a value back into that map. This is the line that persists: when the call commits, the updated map is saved into the world state, so the next call’sSLOADsees it.
Watch it run three times:
== call counter x3 == status Success, count now 1 status Success, count now 2 status Success, count now 3The number 3 does not live in any running program’s memory — each call starts a fresh EVM execution and tears it down at the end. It lives in the contract’s storage, in the world state, fingerprinted by the state root. That is what “a program that lives on the blockchain” means, concretely: state that outlives every process, because it is the chain. Strip out SSTORE and you have a throwaway calculator; add it back and you have a contract.
Immutability: the code is frozen at deploy
Section titled “Immutability: the code is frozen at deploy”The bytecode field is written once, when the contract is deployed, and is never edited again. There is no UPDATE operation for a contract’s code in the EVM. This is not an implementation gap — it is a deliberate, load-bearing property.
Immutability is what lets an untrusting stranger trust a contract. If the code that governs your funds could be swapped out by its author tomorrow, auditing today’s code would be pointless. Because the bytecode is frozen, anyone can read exactly what a contract will do, forever, and know it cannot change under them. That is the flip side of “code is law”: the law can’t be rewritten after you’ve agreed to it.
The cost is severe: a bug is permanent. You cannot patch a deployed contract. If your logic has a flaw, that flaw is now an immutable, publicly readable feature of the chain that an attacker can study at leisure. The industry works around this — proxy patterns put mutable logic behind a fixed address, and contracts include pause switches and migration paths — but those are patterns layered on top of immutability, not exceptions to it. The base rule never bends: the bytes you deploy are the bytes that run, unchanged, until the contract is destroyed.
A contract can hold ETH and call other contracts
Section titled “A contract can hold ETH and call other contracts”Two capabilities of the balance-and-code combination point straight at the rest of this part.
First, a contract can hold and send ETH. Its balance is real ether, and its code can transfer it — to a wallet, or to another contract — as part of executing a call. This is what makes contracts financial machinery rather than mere databases: an escrow contract genuinely holds the money; a DEX contract genuinely custodies the pool.
Second, a contract can call other contracts. Mid-execution, one contract’s code can invoke another contract’s code (via the EVM’s CALL family of opcodes), which runs that contract against its storage and returns a result. This is composition — the property that lets small contracts snap together into large systems (“money legos”), and it is the entire premise of DeFi.
It is also the single most dangerous feature in the space. Contract-to-contract calls are what made The DAO’s reentrancy possible: calling out to untrusted code hands control to an attacker mid-transaction. We will not fully unpack composition and its hazards on this page — the point here is only to plant the flag. A contract is not an island: it holds value and it can reach out to other code. That reach is both Ethereum’s superpower and its sharpest edge.
The architect’s lens
Section titled “The architect’s lens”The contract account is the central abstraction of programmable Ethereum, so it earns the lens.
- Why does it exist? Because a “world computer” needs somewhere for programs and their memory to live. A contract account is that home: a permanent address whose code and storage are part of the shared, replicated state, so every node agrees on what the program is and what it currently remembers.
- What problem does it solve? It lets untrusting strangers rely on a piece of logic without trusting each other or its author — the code is public, frozen, and executed identically by everyone, so “will it do what it says?” is answerable by reading it, not by trusting a company.
- What are the trade-offs? You buy trustlessness and permanence at the price of immutability (bugs can’t be patched), cost (every node re-runs every call, paid for in gas), and rigidity (no wall clock, no randomness, no off-chain data without an oracle).
- When should I avoid it? When the logic doesn’t need shared, trustless, permanent state — anything private, fast-changing, or cheap belongs off-chain. Putting a mutable app database on Ethereum is paying a global settlement premium for something a Postgres row does better.
- What breaks if I remove it? You are back to Bitcoin’s world: a ledger that can only move value. Remove the contract account and you remove programmability — the entire leap from “digital cash” to “a shared world computer” that this book exists to explain.
Check your understanding
Section titled “Check your understanding”- Name the three things a contract account bundles together, and say which one, if empty, would make the account an EOA instead.
- What controls an EOA, and what controls a contract account? Which of the two can originate a transaction, and why can only that one do it?
- When you “call a contract,” how many machines run its code, and what property of the EVM guarantees they all reach the same result?
- A counter contract with the
SSTOREremoved would still computecount + 1. Why would it no longer be a “contract” in the sense this page means — where does the persistence actually come from? - Immutability makes a contract trustworthy and makes its bugs permanent. Explain both sides in one sentence each, and name the incident this page uses to illustrate the danger.
Show answers
- Immutable EVM bytecode (the code, set once at deploy), a persistent storage map (key→value memory the code reads and writes), and a balance (ETH in wei). If the code field is empty, the account has no program to run and is therefore an externally owned account (EOA) — a plain wallet. (An EOA also has no storage.)
- An EOA is controlled by a private key; a contract account is controlled by its own bytecode and has no key. Only an EOA can originate a transaction, because originating one requires a signature, and only an EOA has a private key to sign with. A contract can only react to being called.
- Every full node in the network runs the code independently. Because the EVM is deterministic — no floating point, no wall clock, no true randomness — every node running the same bytecode against the same storage from the same starting state computes the identical new world state, so they all agree.
- The persistence comes from storage being part of the world state:
SSTOREcommits the write into the state, so a later call’sSLOADreads it back. WithoutSSTORE, the computedcount + 1is thrown away when the EVM execution ends — nothing survives the call, so it’s a throwaway calculator, not a stateful contract. - Trustworthy: because the code can never change, anyone can read exactly what the contract will do forever and know it can’t be swapped out under them. Permanent bugs: because the code can never change, a flaw can’t be patched and becomes a publicly readable, exploitable feature of the chain. The illustrating incident is The DAO (June 2016), whose reentrancy bug couldn’t be patched and led to a hard fork splitting Ethereum and Ethereum Classic.