Overview — The Account Model
The book asks one question over and over: how do you build a single global state machine that runs at hardware speed without falling apart? Proof of History gave us a clock — an ordering of events that validators can agree on without talking to each other. But ordering events is only useful if the events themselves can run fast, and ideally in parallel. That is where this part begins.
To run transactions in parallel you need one thing above all: you must know, before a transaction runs, exactly which pieces of state it will read and write. Two transactions that touch disjoint state can run at the same time on different cores; two that touch the same state cannot. So the whole performance story rests on a data-layout question — how do you arrange global state so a transaction’s footprint is knowable up front? This part answers it. The answer is the account model, and it starts with a single decision: separate code from state.
The thesis, stated up front
Section titled “The thesis, stated up front”Here is the core claim of this entire part, in one line:
State and code are separable. Accounts hold state; programs hold only code.
That sounds almost too simple to matter. It is the opposite. Nearly everything Solana does differently — parallel execution, cheap state, predictable fees, program-derived addresses — falls out of this one split. Get it now and the rest of the book stops looking like a bag of tricks and starts looking like consequences.
The account model in one picture ─────────────────────────────────
PROGRAMS (code only, stateless) ACCOUNTS (state only) ┌─────────────────────────┐ ┌──────────────────────────┐ │ System Program │ owns ───► │ Alice's wallet │ │ Token Program │ │ lamports, no data │ │ your Counter program │──── owns ──► │ a Counter's state buffer │ └─────────────────────────┘ └──────────────────────────┘ ▲ ▲ │ pure functions over accounts │ named by a 32-byte Pubkey └──────────────────────────────────────────┘ one flat global map: Pubkey → AccountGlobal state is not a tree of contracts each hiding its own storage. It is one flat key→value map: a 32-byte public key (Pubkey) points at an Account. Every wallet, every token balance, every piece of program state, and even the programs themselves live as entries in that single map. There is exactly one namespace for all state on the chain.
What an account is (previewed, not yet taught)
Section titled “What an account is (previewed, not yet taught)”An account is deliberately dumb. In real Solana it is five fields:
Account ├── lamports u64 native balance (1 SOL = 1_000_000_000 lamports) ├── owner Pubkey the program allowed to change data / debit lamports ├── data [u8] an opaque byte buffer the owner interprets ├── executable bool is this account itself a program (code)? └── rent_epoch u64 rent accounting (largely vestigial after rent-exemption)The whole part unpacks these fields, but notice the shape already:
lamportsis the only value the runtime itself understands. Everything else is opaque.datais just bytes. The runtime never looks inside it. Only theownerprogram knows what type lives there — a token balance, a counter, a governance proposal.owneris the access-control rule of the entire system: only the owner program may write an account’sdataor debit itslamports.executableis how “code is an account too” is expressed — a program is an account whosedatais its compiled bytecode and whoseexecutableflag is set.
The running model for this part strips the last two fields, because our miniature runtime does not load bytecode or charge rent. In solmini, the book’s companion crate, an account is exactly this:
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]pub struct Account { pub lamports: u64, // native balance (Solana's smallest unit) pub data: Vec<u8>, // opaque buffer a program interprets however it likes pub owner: Pubkey, // the program id allowed to mutate this account's data}That three-field struct is the entire data model you will map onto real Anchor by the end of the part. Every page below builds on it.
The Ethereum contrast (it recurs through the whole part)
Section titled “The Ethereum contrast (it recurs through the whole part)”If you have any Ethereum background, the account model will feel inverted, so name the contrast now — it comes back on nearly every page.
Ethereum Solana ──────── ────── contract account program account (code only, STATELESS) = code + its OWN storage owns ▼ data accounts (typed buffers + lamports)
state hidden INSIDE the contract state in NAMED, EXTERNAL accounts → footprint unknown until you run → footprint declared up frontOn Ethereum a contract is its code and it holds its own storage inside itself. That is intuitive, but it has a hidden cost: you cannot know which storage slots a contract call will touch until you actually execute it, because that storage is the contract’s private business. So the runtime must execute calls one at a time — it cannot tell in advance whether two calls collide.
Solana pulls code and state apart. A program is pure code that owns no state. All mutable state lives in separate, externally named accounts that the program owns. Because state now lives in named, external accounts, a transaction can list the accounts it will touch before it runs — and that list is precisely the information a scheduler needs to know which transactions are independent. The account model is not just a different data layout. It is the precondition for parallel execution. That single sentence is the thread this part exists to prove.
The thread
Section titled “The thread”What does the account model force you to understand? That state and code are separable, and that separating them is what makes a transaction’s footprint knowable in advance. Knowability is the whole game: it is the one fact the parallel scheduler (later in the book) depends on. Ethereum hides state inside contracts and pays for it with serial execution; Solana exposes state as named accounts and buys the right to run transactions side by side. Everything in this part is a detail of how that exposure works — and every later part is a payoff that only exists because the footprint was knowable up front.
Roadmap for this part
Section titled “Roadmap for this part”Read these in order. Each one adds a single idea to the flat Pubkey → Account map above.
| # | Page | What it adds | The one idea |
|---|---|---|---|
| 2 | Everything Is an Account | the flat global map and the five account fields, taught in full | wallets, state, and code are all entries in one Pubkey → Account map |
| 3 | Stateless Programs Act on Accounts | programs as pure functions over a passed-in account list | code holds no state; it mutates the accounts a transaction hands it |
| 4 | Program Derived Addresses (PDAs) | deterministic, keyless addresses a program owns | how a program gets accounts it controls without a private key |
| 4 | Contrast: Contract-Owned Storage vs External Accounts | the Ethereum comparison in depth | why external named state is what unlocks parallelism |
| 900 | Revision — The Account Model | a recap of the whole part | the part compressed to what you must retain |
By the end you will be able to point at a real Anchor #[account] struct, a #[derive(Accounts)] context, and a declare_id!, and say exactly which piece of this flat map each one names — and why that naming is what lets Solana run at hardware speed.
The first job is to make the flat map concrete and teach all five fields properly: Everything Is an Account.
Check your understanding
Section titled “Check your understanding”- State the core thesis of this part in one sentence, and name the single property it is designed to give a transaction.
- Solana’s global state is described as a “flat map.” What are the keys, what are the values, and what kinds of things live in it that might surprise someone from Ethereum?
- Of the five account fields, only one is understood by the runtime itself; the rest are opaque to it. Which one, and who gives meaning to the
datafield? - Ethereum stores a contract’s state inside the contract; Solana stores a program’s state in external accounts. Why does that one difference determine whether transactions can run in parallel?
- The
ownerfield is called “the access-control rule of the entire system.” What exactly does an account’s owner get to do that nothing else can?
Show answers
- State and code are separable: accounts hold state, programs hold only code. It is designed to make a transaction’s footprint knowable before it runs — the precondition for running independent transactions in parallel.
- The keys are 32-byte public keys (
Pubkey); the values areAccounts (lamports + owner + data, plusexecutable/rent_epochin real Solana). Everything lives in this one map: wallets, token balances, program state — and the programs themselves, since code is stored in an account with itsexecutableflag set. There is a single global namespace for all state. - Only
lamports(the native balance) is understood directly by the runtime. Thedatabuffer is just opaque bytes; only the account’sownerprogram knows what type those bytes represent and how to interpret them. - If state is hidden inside a contract, the runtime cannot know which state a call touches until it executes it, so it must run calls serially (any two might collide). If state lives in named external accounts, a transaction can declare its accounts up front, so the runtime can see which transactions are independent before executing and run those simultaneously.
- Only an account’s
ownerprogram may change itsdatabuffer and debit itslamports. That single rule is how the flat, shared map stays safe: anyone can name any account, but only the owner can mutate it.