Bitcoin Cycle
go-ethereum v1.0 · Frontier · July 2015

Inside the code that launched Ethereum.

Bitcoin's script can only lock and unlock coins. Ethereum puts a whole computer in every node: accounts that hold code, and a virtual machine that runs it, with every step metered in gas. This page opens up geth v1.0.0, the Go client tagged on 29 July 2015 for the Frontier launch the next day. Every hash is computed live in your browser with Keccak-256, and every code excerpt is copied word for word from the v1.0.0 tag.

Go source
The computer
core/vm
the EVM: 1,024-deep stack, 256-bit words
Block reward
5 ETH
+ uncles, no halving
Genesis block, re-hashed just now
…
1

The whole client on one screen

Each tile is a Go package in geth v1.0.0, sized by source bytes (tests and vendored libraries left out). The consensus rules live in a few small packages: core, core/vm, core/state, trie, rlp.

2

Accounts, not coins

Bitcoin tracks unspent outputs. Ethereum keeps a world state: a map from address to account, where each account is four fields, [nonce, balance, storageRoot, codeHash]. A transaction edits that map. The whole map is summed up by one hash, the state root.

A tiny world state
stateRoot (Patricia trie of keccak(address) → RLP(account), chapter 6)
The nonce counts the transactions an account has sent, so the same signed transaction can't be replayed. A contract is an account with code. Its storageRoot commits to its own key-value storage.
3

A transaction is six fields and a signature

Everything Ethereum stores or sends is serialised with RLP (recursive length prefix): byte strings and lists, each with a short header saying how long it is. The sender signs the Keccak-256 hash of the first six fields, SigHash(). Edit any field.

Build a transaction

RLP length
SigHash = keccak256(rlp([nonce, price, gasLimit, to, amount, payload]))
4

Gas: paying for computation up front

A program might loop forever, so every step costs gas, bought in advance. The sender pre-pays gasLimit × gasPrice. Every transaction pays a flat 21,000 plus 68 per non-zero data byte (4 per zero byte). Whatever isn't burned by execution is refunded.

Where the gas in the transaction from chapter 3 goes

Execution cost comes from the last program run in the EVM (chapter 5). Change the data or gas limit in chapter 3, or run a program below, and this updates.

5

The Ethereum Virtual Machine, one opcode at a time

Vm.Run() is a loop: read the opcode at pc, charge its gas, execute it, move on. The machine has a stack of 256-bit words, scratch memory that is wiped after each call, and storage that persists in the contract's account. This is a small EVM written for this page, following v1.0's rules and Frontier gas costs, running real bytecode.

gas left
stacktop ↑
memory
storagepersists between runs

6

The Merkle-Patricia trie: a hash for a whole database

Accounts, contract storage, transactions and receipts each live in a trie keyed by hex digits (nibbles). Shared prefixes are stored once, and every node is hashed into its parent, so one 32-byte root commits to everything. Change one value and the root changes.

Keys and values
root = keccak256(rlp(root node))
branch (17 slots: one per nibble + a value)extension (shared prefix)leaf (rest of key + value)
7

The genesis block, rebuilt field by field

An Ethereum block header has 15 fields. Its hash is Keccak-256 of the header's RLP. This page rebuilds the real Frontier genesis header (loaded into geth with --genesis at launch) and hashes it.

Block 0 header
keccak256(rlp(header))
The gas limit started at 5,000, too small for even one 21,000-gas transaction. For the first days miners could only mine empty blocks while voting the limit up. Each block could move it by 1/1024. This launch period was called the thawing.
8

Difficulty, re-tuned every single block

Bitcoin re-checks its difficulty every 2,016 blocks (see Satoshi's code). Frontier does it on every block with one rule: if the block came less than 13 seconds after its parent, difficulty rises by 1/2048, otherwise it falls by 1/2048.

Simulate the network

Each dot is a block. Its time is random, as real mining is, averaging difficulty ÷ hashrate. The rule only looks at whether a block was under or over 13 s, so it holds the median block time at 13 s and the average comes out near 19 s.

9

Uncles: paying the runners-up

With blocks every ~15 seconds, two miners often find a block at almost the same moment. Bitcoin throws the loser away. Ethereum lets a later block cite it as an uncle (up to two, from the last 6 generations) and pays both sides. That rewards small miners and makes the chain more secure.

Block N includes…