Breaking Down the Ethereum Yellow Paper

A complete overview of the Ethereum Yellow Paper, explained in an understandable way.

1. Introduction

First, let’s answer a simple question: what is the Yellow Paper talking about? Let’s take a look at the conclusion to get an answer:

Ethereum is basically just a bunch of computers doing this over and over again.
  • Ethereum is cryptographically secure. Valid transactions require the cryptographic signature of the sender. Blocks require proof of work, a cryptographic proof that shows a certain amount of computational effort has been spent. All in all, this means it is nearly impossible for attackers to maliciously alter the blockchain (e.g. create fake transactions or delete transactions). The practical result of this is that people can trust the data on the blockchain.
  • Ethereum is a transaction-based state machine. It transitions from one state to the next by running transactions.
  • Ethereum has shared state. Even though the Ethereum network is made up of many computers, they all maintain the same state, and function as a single virtual computer. This is why Ethereum is sometimes called a “world computer.”
  • Ethereum is a generalized technology. Bitcoin implements the same model as Ethereum—it is also a cryptographically secured, transaction-based state machine. However, Bitcoin’s only purpose is to transfer value. You can build lots of different things on top of Ethereum, including but not limited to token systems (ERC20 tokens), identity systems (ENS), DAOs, NFTs, etc.
Similar to the above diagram, but much more complicated! Ethereum is a transaction-based state machine. This means all the nodes in the Ethereum network (the computers running an implementation of the Ethereum protocol) are continuously running transactions in order to update some shared state.

1.1 Driving Factors

What’s the point of this whole thing? Here’s how the paper phrases it:

  • “Incorruptibility of judgement” — why rely on a human judge to be impartial when you can rely on cold hard code?
  • “Transparency” — you can look at the source code and examine the transactions themselves (e.g. on Etherscan) to see exactly what happened and why.

1.2 Previous Work

There’s not too much to discuss here, but I like this quote:

2. The Blockchain Paradigm

This section dives deeper into what a blockchain actually is. First, let’s review what Ethereum is:

The formal definition of transaction execution.

2.1 Value

So, why do miners spend all this energy mining new blocks! It’s simple—because they get rewarded! Ether, or ETH, is the currency of the Ethereum blockchain, and is used to reward miners. You also need to pay ETH if you want to run code on the blockchain. Just like we have dollars and cents, there are different denominations of ETH.

Each denomination is named after a well-known person in the crypto space.

2.2 Which History?

We said above that blocks form a chain. That’s actually not entirely true—anyone has the opportunity to create a new block on some older pre-existing block, which means a tree of blocks get formed.

There is a tree of blocks. The path through the tree with the most computational work is the blockchain.

3. Conventions

This section defines a bunch of symbols for the math portions of the paper. No need to cover this.

4. Blocks, State, and Transactions

This is where things start to get really interesting! This section defines blocks, state, and transactions in detail.

4.1 World State

Let’s start with state.

  • The world state is a key-value store, where the keys are addresses and the values are account states.
  • Nodes store the world state as a Merkle Patricia tree.
  • The blockchain stores the root hash of this tree in each block header.
  1. nonce. For non-contract accounts, it’s the number of transactions sent from the address. For contract accounts, it’s the number of contract creations made by the account.
  2. balance. Pretty self explanatory, it’s how much ETH the account has.
  3. storageRoot. This is the root hash of yet another Merkle Patricia tree. This tree stores data specific to the account, and is nested in the top-level “world state” Merkle Patricia tree.
  4. codeHash. This differentiates contract accounts from external accounts (i.e. accounts owned by real people). If this is the hash of the empty string, the account is an external one.
The root hash of the state tree is stored on-chain in a block header. The state tree maps addresses to accounts. Each account has a storageRoot value, which refers to yet another Merkle Patricia tree.

4.2 The Transaction

Let’s move onto transactions! Remember from section 2 that a transaction is a bridge between two states. In order to transition from one state to the next, a transaction gets executed. The appendix has a good definition for a transaction:

  1. Transactions which result in message calls are the more common type of transaction. They include transactions where you send money to someone else, and transactions where you call the method of some smart contract.
  2. Contract creation transactions. This is pretty self-explanatory… these transactions create contracts. Note that contracts can also be created within another contract. For example, let’s say you call method createRain of a smart contract called Cloud. This method creates a new Rain contract. This transaction is still a message call transaction, even though a new contract was created, because the contract creation was initiated from within a contract. This is a bit confusing, but practically it’s not very important.
  • nonce: Number of transactions sent by the sender.
  • gasPrice: The number of Wei to be paid per unit of gas for all computation costs incurred by executing the transaction (Note: EIP 1559 changed this).
  • gasLimit: A scalar value equal to the maximum amount of gas that should be used in executing this transaction. This is paid up-front, before any computation is done and may not be increased later (Note: EIP 1559 changed this).
  • to: The 160-bit address of the message call’s recipient or, for a contract creation transaction, an empty byte array.
  • value: A scalar value equal to the number of Wei to be transferred to the message call’s recipient or, in the case of contract creation, as an endowment to the newly created account.
  • v, r, s: Values corresponding to the signature of the transaction and used to determine the sender of the transaction.
A simplified depiction of a transaction from the Ethereum whitepaper.
// init codereturn `
contract Foo {
...
}
`;

4.3 The Block

Each block is made up of three parts:

  1. The block header.
  2. A list of ommer block headers.
  3. A list of transactions.
An ommer block’s parent is equal to the current block’s parent’s parent.
A high level diagram of a block
  • parentHash: The Keccak 256-bit hash of the parent block’s header, in its entirety.
  • ommersHash: The Keccak 256-bit hash of the ommers list portion of this block.
  • beneficiary: The 160-bit address to which all fees collected from the successful mining of this block be transferred.
  • stateRoot: The Keccak 256-bit hash of the root node of the state tree, after all transactions are executed and finalisations applied.
  • transactionsRoot: The Keccak 256-bit hash of the root node of the trie structure populated with each transaction in the transactions list portion of the block.
  • receiptsRoot: The Keccak 256-bit hash of the root node of the trie structure populated with the receipts of each transaction in the transactions list portion of the block.
  • logsBloom: The Bloom filter composed from indexable information (logger address and log topics) contained in each log entry from the receipt of each transaction in the transactions list.
  • difficulty: A scalar value corresponding to the difficulty level of this block. This can be calculated from the previous block’s difficulty level and the timestamp.
  • number: A scalar value equal to the number of ancestor blocks. The genesis block has a number of zero.
  • gasLimit: A scalar value equal to the current limit of gas expenditure per block.
  • gasUsed: A scalar value equal to the total gas used in transactions in this block.
  • timestamp: A scalar value equal to the reasonable output of Unix’s time() at this block’s inception.
  • extraData: An arbitrary byte array containing data relevant to this block. This must be 32 bytes or fewer.
  • mixHash: A 256-bit hash which, combined with the nonce, proves that a sufficient amount of computation has been carried out on this block.
  • nonce: A 64-bit value which, combined with the mixHash, proves that a sufficient amount of computation has been carried out on this block.
  1. The status code of the transaction.
emit Transfer(address(0), to, tokenId);
How to determine if stateRoot is valid—run the transactions yourself!

5. Gas and payment

All computational operations in Ethereum (e.g. modifying state, adding two numbers) are subject to fees. Gas is the unit of measurement for these fees.

6. Transaction Execution

This section looks complicated because it contains a lot of formal logic. Instead of going through all the math, we can refer to the whitepaper for a simpler explanation of transaction execution.

A simplified example of a transaction execution, from the whitepaper.

7. Contract Creation

This section is more-or-less covered in sections 4 and 6.

8. Message Call

This section is more-or-less covered in sections 4 and 6.

9. Execution Model

This section goes into the specifics of how a transaction gets executed. Similarly to section 6, we can refer to the whitepaper for a simpler explanation. If you actually want to implement the Ethereum protocol (best of luck!) you should read through the Yellow Paper. Otherwise, the following is enough to understand things at a high level.

10. Blocktree to Blockchain

We covered this already in section 2.2.

There is a tree of blocks. The path through the tree with the most computational work is the blockchain.

11. Block Finalisation

We’re getting close to the end! This section talks about the block finalisation process. Block finalisation refers to either mining a new block or validating an existing block. In each scenario, the steps are similar:

  • There should be a maximum of two ommer headers.
  • Each ommer header should be valid (see section 4.3 for how to check block validity).
  • The generation of each ommer must be at most 6. The first generation of ommer blocks are those whose parent is equal to the current block’s parent’s parent (what a mouthful).
  1. It reduces the effect of network lag on mining rewards, since blocks that are mined slightly later than the chosen block may still get an ommer reward.
  2. It incentivizes mining, since you don’t always need to be the fastest miner to get a reward. Think of it this way—if a contest only has a prize for first place, you might think it’s too hard to win and not bother joining. But if it also has second and third place prizes, maybe it’s worth giving it a shot.

--

--

Software Engineer. Tweeting @pencilflip. Mediocre boulderer, amateur tennis player, terrible at Avalon. https://www.mattlim.me/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Matt Lim

Software Engineer. Tweeting @pencilflip. Mediocre boulderer, amateur tennis player, terrible at Avalon. https://www.mattlim.me/