Try   HackMD

Some notes on Ethereum Yellow paper

Directly starting from the state transition function

σt+1Υ(σt,T).....(1)

where

Υ is the Ethereum state transition function. In Ethereum,
Υ
, together with
σ
are considerably more powerful than any existing comparable system;
Υ
allows components to carry out arbitrary computation, while
σ
allows components to store arbitrary state between transactions.

Υ is State-transition function
σ
is the State (the state that is stored)

σt+1Π(σt,B)

B(...,(T0,T1,...),...)

Π(σ,B)Υ(Υ(σ,T0),T1)...

B is the Block;
Π
is the block-level state-transition function;
T
is a tuple represeting Ethereum Transaction;
Ti
is a nonced Transaction;

Where

B is this block, which includes a series of transactions amongst some other components and
Π
is the block-level state-transition function. This is the basis of the blockchain paradigm, a model that forms the backbone of not only Ethereum, but all decentralised consensus-based transaction systems to date.

Which history?

Since Ethereum is a decentralized platform, any participant can attempt to add a new block to an existing chain of blocks. This creates a branching structure of blocks resembling a tree. To determine the main path from the root (the initial genesis block) to the leaf (the most recent block), a consensus mechanism is needed. If nodes disagree on which path represents the official blockchain, this disagreement results in a fork — a split where different nodes might follow different histories beyond a certain point, each considering their chosen history as the correct one. This divergence can lead to incompatible records of transactions, undermining trust in the system.

Since the Paris hard fork, Ethereum manages consensus through a protocol known as the Beacon Chain. This is part of Ethereum's consensus layer, which sets the rules for identifying the valid sequence of blocks.

This document (these notes as well) discusses the execution layer of Ethereum, which governs interactions and updates to the state of the Ethereum Virtual Machine (EVM). For more details on the consensus mechanisms, one would refer to the consensus specifications.

Occasionally actors do not agree on a protocol change, and a permanent fork occurs. In order to distinguish between diverged blockchains, EIP-155 by Buterin [2016] introduced the concept of chain ID, which we denote by

β.

For the Ethereum main network

β=1

Notations

Υ denotes functions operating on highly structured values like Ethereum State-transition function;
σ
is the Global State (the state that is stored);
μ
is machine state;
C
is the Cost function;
CSSTORE
is cost function for SSTORE operation
B
is the Block;
Π
is the block-level state-transition function;
T
is a tuple represeting Ethereum Transaction;
Ti
is a nonced Transaction;
s
stack;
m
memory

World State

The world state in Ethereum is essentially a mapping that links addresses (which are 160-bit identifiers) to their respective account states. These account states are structured data serialized as Recursive Length Prefix (RLP), detailed in Appendix B. While this mapping is not stored directly on the blockchain, it is maintained within a modified Merkle Patricia tree, or trie. This trie functions atop a simple database backend that maps byte arrays to byte arrays, termed the state database.

The root node of this trie structure is crucial as its cryptographic hash reflects all the internal data, thus serving as a secure identifier for the entire system's state. The immutable nature of this data structure enables retrieval of any previous state by adjusting the root hash, provided all root hashes are logged on the blockchain, allowing for straightforward reversion to past states.

Each account state comprises four main fields:

  1. Nonce: This is a count of transactions sent from an address or, for contract accounts, the number of contracts created. It is denoted as
    σ[a]n
    for an address '
    a
    '.
  2. Balance: The amount of Wei (smallest denomination of ether) held by an address, formally written as
    σ[a]b
    .
  3. StorageRoot: A 256-bit hash representing the root of another Merkle Patricia tree, which stores the account's data values. This is recorded in the trie as a hash-to-RLP mapping and is denoted
    σ[a]s
    .
  4. CodeHash: A hash of the Ethereum Virtual Machine (EVM) code linked to the account, allowing execution when the account receives a message call. The code itself is saved in the state database and referenced by this hash, represented as
    σ[a]c
    .

The system introduces a method to collapse the trie's data into a concise hash using a specific function, which helps in identifying the world state more efficiently.

Additionally, accounts can be "empty" if they have no code, nonce, or balance, identified by a specific condition in the codeHash field. If an account lacks any substantive state, it's considered "dead."

This structure enables Ethereum to manage its complex state efficiently, ensuring data integrity and enabling historical data access through its unique tree-based storage and hashing mechanisms.

Transaction

A transaction in Ethereum, termed

T, is a cryptographically-signed instruction initiated by an entity outside the Ethereum network. The initiator is typically human, assisted by software tools for creating and sending the transaction. Importantly, the sender of a transaction cannot be a contract.

EIP-2718, introduced by Zoltu in 2020, brought forth the concept of multiple transaction types. By the London upgrade, Ethereum supports three primary transaction types:

  • Type 0 (Legacy)
  • Type 1 (EIP-2930 by Buterin and Swende, 2020)
  • Type 2 (EIP-1559 by Buterin et al., 2019)

Each transaction type includes several common fields:

  • Type: Identified under EIP-2718 as
    Tx
    .
  • Nonce (
    Tn
    ): A count of transactions sent by the sender.
  • Gas Limit (
    Tg
    ): The maximum gas allowable for the transaction, set before execution.
  • To (
    Tt
    ): The recipient's address or null (denoted by
    ϕ
    ) for contract creations.
  • Value (
    Tv
    ): Amount of Wei transferred or assigned as a contract's endowment.
  • r,s
    : Signature components vital for sender identification.

Transactions of type 1 and type 2 have additional fields like:

  • Access List (
    TA
    ): Specifies accounts and storage keys for warming up. Each access list entry
    E
    is a tuple of an account address and a list of storage keys:
    E(Ea,Es)
  • Chain ID (
    Tc
    ): Ensures transactions are on the correct network.
  • Signature
    Y
    Parity
    (
    Ty
    ): Helps in signature recovery.

Legacy transactions do not include an access list, while chainId and yParity for legacy transactions are combined into a single value:
w: A scalar value encoding Y parity and possibly chain ID;

while the newer types use more refined gas pricing fields:

  • Max Fee Per Gas (
    Tm
    ) and Max Priority Fee Per Gas (
    Tf
    ) for Type 2 transactions, enhancing control over transaction costs as per EIP-1559.

For contract creation transactions, regardless of the type, they contain:

  • Init (
    Ti
    ): A byte array for EVM-code initialization, executed once when the account is created.

Message call transactions, on the other hand, include:

  • Data (
    Td
    ): Specifies input data for the message call.

Adding to the existing transaction types, the recent DenCun upgrade introduced by EIP-4844 adds a new transaction type, known as the "Blob Transaction". This transaction type is designed to handle large amounts of data more efficiently by introducing "blob-carrying transactions". These transactions enable data to be stored temporarily off-chain in a cost-effective manner while still maintaining its availability for processing by the Ethereum network. This is particularly beneficial for scaling solutions and complex dApps requiring significant data throughput without overly burdening the main blockchain.

Here is how this integrates into the existing transaction format:

  • Type (Tx = 3): New blob transaction type.
  • Blob (Tb): A large data payload handled differently to optimize for both transmission and inclusion costs.

The addition of blob transactions represents a significant enhancement in Ethereum's capabilities, enabling it to handle larger data requirements efficiently and supporting more complex applications on its platform.

Please note that for "blob-carrying transactions" which contain a large amount of data cannot be accessed by EVM execution, but their commitment can be accessed. The format is intended to be fully compatible with the format that will be used in full sharding.

Block

This as too much mathematical notations, I'm condensing it alot.

In Ethereum, a block is a data structure that primarily consists of a block header

H, the transactions
T
it contains, and a previously used component for ommers (which are now deprecated post-Paris hard fork). Here's a simplified breakdown of what a block in Ethereum includes:

Block Header Components:

  • parentHash (
    Hp
    )
    : The hash of the previous block's header, securing the chain's continuity.
  • ommersHash (
    Ho
    )
    : Previously used to include ommers' headers but now deprecated and set to a constant since proof of work is no longer used.
  • beneficiary (
    Hc
    )
    : The address to which transaction fees (priority fees) from this block are paid.
  • stateRoot (
    Hr
    )
    : The root hash of the state trie after transactions are processed, representing the entire state of the system.
  • transactionsRoot (
    Ht
    )
    : The root hash of the transactions trie, reflecting all transactions included in this block.
  • receiptsRoot (
    He
    )
    : The root hash of the receipts trie, which includes receipts of all transactions in the block.
  • logsBloom (
    Hb
    )
    : A Bloom filter aggregating logs for quick searching and filtering.
  • difficulty (
    Hd
    )
    : A deprecated metric used in proof of work to determine mining challenge, now set to zero.
  • number (
    Hi
    )
    : Represents the block's position in the entire blockchain; zero for the genesis block.
  • gasLimit (
    Hl
    )
    : The maximum gas allowed in this block, setting the limit for transaction processing.
  • gasUsed (
    Hg
    )
    : The total gas used by all transactions in the block.
  • timestamp (
    Hs
    )
    : The Unix timestamp at the time the block was proposed.
  • extraData (
    Hx
    )
    : Optional additional data relevant to the block, restricted to 32 bytes.
  • prevRandao (
    Ha
    )
    : A new addition post-consensus change, linked to the Beacon Chain’s RANDAO mix.
  • nonce (
    Hn
    )
    : Another deprecated field following the shift from proof of work, now set to zero. Note: It's the Block Nonce not the one associated with EOAs.
  • baseFeePerGas (
    Hf
    )
    : Defines the minimum fee per gas that is burned, introduced in EIP-1559 for better fee market dynamics.

Transactions and Ommer Blocks:

  • Transactions (
    BT
    )
    : A list of all transactions included in the block.
  • Ommers List (
    BU
    )
    : Previously contained the headers of uncle blocks but is now an empty array following their deprecation.

Transaction Receipts:

Each transaction in a block has a corresponding receipt

BR[i] that logs execution outcomes, facilitating proof creation or indexing. Receipts include:

  • Transaction Type: Matches the transaction’s type.
  • Status Code: Indicates transaction success or failure.
  • Cumulative Gas Used: Gas used after this transaction’s execution.
  • Logs: Event logs emitted by the transaction.
  • Logs Bloom: Bloom filter for the logs for efficient querying.

Block Validation:

The validity of a block in Ethereum is confirmed if:

  • The block’s ommers field is empty.
  • The block header data matches the transactions it contains.
  • State, transaction, and receipt roots correctly derive from the transactions and the state post-execution.

Ethereum’s transition from proof of work to proof of stake (post-Paris hard fork) significantly altered block header properties, eliminating ommers and difficulty and introducing fields like prevRandao to align with the new consensus mechanism. This transition reflects Ethereum’s evolving technology and adaptation to more energy-efficient and scalable network operations.

Gas and Payment

To manage network abuse and address the complexities of Turing completeness, Ethereum imposes a fee structure for any executable computation, including contract creations, message calls, storage operations, and other virtual machine executions. This fee structure is denominated in "gas," which serves as a unit of computational effort (details on specific fees for different operations can be found in Appendix G of the yellow paper).

Each transaction on the Ethereum network is associated with a specific "gasLimit," which represents the maximum amount of gas the sender is willing to use for the transaction. This gasLimit effectively acts as a cap on the total computational cost the sender is prepared to incur. The gas used is prepaid from the sender's account balance at a rate defined as the "effective gas price," and any gas not used by the end of the transaction is refunded to the sender.

The introduction of EIP-1559 in the London hard fork established a new fee model involving a base fee and a priority fee:

  • Base Fee: A mandatory fee that varies block by block, set as wei per unit of gas consumed. It adjusts dynamically based on the previous block's gas usage relative to a predefined "gas target" (usually set at half of the block’s gas limit). If the gas usage exceeds the target, the base fee increases to temper demand; if it falls below the target, the base fee decreases to encourage more transactions. The ether paid as the base fee is permanently "burned," removing it from circulation.
  • Priority Fee: An optional additional fee that users can pay to incentivize validators to prioritize their transaction over others. This fee goes directly to the validator (the beneficiary address) managing the block.

For transaction types introduced post-EIP-1559 (type 2 transactions), users can specify two parameters:

  • maxPriorityFeePerGas: The maximum priority fee a sender is willing to pay per unit of gas.
  • maxFeePerGas: The total maximum fee (including both base and priority fees) a sender is willing to pay per unit of gas. The transaction must at least meet the current base fee to be eligible for inclusion in a block.

Older transaction types (type 0 and type 1) only use a single fee parameter, "gasPrice," which must cover both the base fee and any priority fee the sender wishes to pay.

Validators have the discretion to choose which transactions to include in a block, typically favoring those with higher priority fees due to the direct financial incentive. Thus, while senders can set any priority fee, higher fees increase the likelihood of timely transaction inclusion, creating a trade-off for users between cost and speed of execution.

Transaction Execution

The execution of a transaction in Ethereum is complex because it involves a series of checks and operations that define the state transition function

Υ. Before any transaction can be executed, it must first pass several tests to ensure its intrinsic validity:

  1. Well-formed RLP: The transaction must be properly encoded using the Recursive Length Prefix (RLP) format without any extra bytes.
  2. Valid Signature: The transaction must include a valid signature from the sender.
  3. Valid Nonce: The nonce in the transaction must match the current nonce of the sender's account, ensuring transactions are processed in order.
  4. No Contract Code: The sender's account must not have contract code associated with it, as specified in EIP-3607.
  5. Sufficient Gas Limit: The gas limit set for the transaction must not be less than the intrinsic gas used by the transaction.
  6. Sufficient Balance: The sender’s account must have enough balance to cover the upfront cost of the transaction.
  7. Appropriate Gas Price: For type 2 transactions, the maxFeePerGas must be at least equal to the block’s base fee. For type 0 and type 1 transactions, the gasPrice must also meet or exceed the base fee.
  8. Fee Constraints: For type 2 transactions, the maxPriorityFeePerGas must not exceed the maxFeePerGas.

When a transaction

T is executed, the new state
σ0
is derived from the current state
σ
using
Υ(σ,T)
. The function
Υ
also determines the gas used
Υg
, the logs generated during the transaction
Υl
, and the resulting status code
Υz
.

During execution, an "accrued substate"

A is collected, which includes:

  • Self-destruct set (
    As
    ): Accounts marked for deletion after execution.
  • Log series (
    Al
    ): Event logs that can be indexed and accessed externally.
  • Touched accounts (
    At
    ): Accounts that are interacted with, which may be deleted if empty after the transaction.
  • Refund balance (
    Ar
    ): Amounts added to the refund balance due to specific operations like setting storage to zero.
  • Accessed addresses and storage keys (
    Aa,AK
    ): Introduced in EIP-2929, these are lists of addresses and storage keys that were accessed, affecting the cost of operations.

The intrinsic gas

g0 required for the transaction is calculated based on the type of transaction and the data involved. The effective gas price
p
is determined based on the transaction type and the fees involved. The upfront cost
v0
is calculated as the product of the gas limit and the gas price, plus the transaction value.

The execution begins with the transaction changing the state by increasing the sender's nonce and reducing their balance by the cost of the gas used. The available gas for the transaction is then the gas limit minus the intrinsic gas. The computation results in a new provisional state, which after adjustments, becomes the final state upon completion of the transaction.

The entire process ensures that transactions are securely and accurately processed, maintaining the integrity and state of the Ethereum blockchain.

Gas refund

During the execution of a transaction, certain operations can lead to a situation where not all the gas allocated (or "purchased") by the transaction is used. Ethereum has a mechanism to handle such scenarios by refunding a portion of the gas not used. Here are the key details:

  • Refund for Certain Operations: Some operations in the Ethereum Virtual Machine (EVM) lead to a reduction in the use of storage space, which can be less computationally intensive than initially anticipated. For example, when storage values are reset to zero, the SSTORE operation adds to a "refund counter." This counter tracks the amount of gas to be refunded.

  • Calculation of Refund Amount: The refund amount is determined by specific rules set out in Ethereum's protocol. The basic formula considers the lesser of:

    • A portion of the gas used, often capped to a certain fraction (e.g., one-sixth) of the total gas used by the transaction.
    • The total amount accumulated in the refund counter during the transaction's execution.
  • Final Gas Calculation:

    • The total gas used for the transaction is adjusted by subtracting the amount eligible for refund.
    • The gas refund is then credited back to the sender’s account at the end of the transaction, effectively lowering the overall cost of the transaction.
  • Impact on Transaction Fee: Since the transaction fee is calculated based on the total gas used (multiplied by the gas price), refunds can significantly reduce the fee paid by the sender. This mechanism encourages users to write more efficient code and clean up unnecessary storage, as they can receive refunds for such optimizations.

Example of Gas Refund in a Transaction

Let's consider a transaction where a user interacts with a smart contract to change storage values. If the user resets previously non-zero storage slots to zero, the operation qualifies for a gas refund. Here's how it would be calculated:

  • Intrinsic Gas (
    g0
    ): Gas required for the transaction to be processed.
  • Gas Used
    (Tgg0)
    : Total gas used minus intrinsic gas.
  • Refund Counter
    (Ar)
    : Amount accumulated during operations eligible for refunds.
  • Refundable Gas: The lesser amount between the refund counter and a fraction of the total gas used.
  • Final State Calculation:
    • The sender’s balance is adjusted to reflect the gas refund.
    • The refunded gas is subtracted from the total gas calculation, lowering the cost.

Contract Creation

Creating an account in Ethereum involves several intrinsic parameters that define how the account is set up and initialized. These parameters are critical in determining the result of the account creation process, governed by the Ethereum protocol. Here's a breakdown of the process and its parameters:

  1. Sender (
    s
    )
    : The account initiating the creation.
  2. Original Transactor (
    o
    )
    : The originator of the transaction, potentially different from the sender in cases of nested calls.
  3. Available Gas (
    g
    )
    : The gas available for executing the account creation.
  4. Effective Gas Price (
    p
    )
    : The cost per unit of gas, determined by the transaction conditions.
  5. Endowment (
    v
    )
    : The initial amount of Ether to be transferred to the new account.
  6. Initialization Code (
    i
    )
    : An arbitrary length byte array containing EVM bytecode executed to initialize the account.
  7. Stack Depth (
    e
    )
    : The current depth of the call stack at the point of account creation.
  8. Salt (
    ζ
    )
    : Used for deterministic address generation in CREATE2 operations; can be absent, indicated as
    ζ=ϕ
    .
  9. Permission to Modify State (w): Indicates whether the operation is allowed to alter the blockchain state.

The function

Λ processes these inputs along with the current blockchain state
σ
and the accrued substate
A
to produce:

  • New State (
    σ0
    )
    : The updated state after account creation.
  • Remaining Gas (
    g0
    )
    : Gas left after the account creation process.
  • New Accrued Substate (
    A0
    )
    : Updates to the accrued information during execution.
  • Status Code (z): Indicates the outcome (success or failure) of the operation.
  • Output (o): Returns the result of the initialization code execution.

Address Calculation

The address of the newly created account depends on whether it’s a CREATE or CREATE2 operation:

  • CREATE: The address is derived from the sender’s address and nonce.
  • CREATE2: The address includes a hash of the sender’s address, nonce, salt, and initialization code.

Account Initialization and Execution

Once the address is determined and the account is preliminarily set up with its nonce set to 1, balance set to the endowment, and other initial settings, the initialization code is executed. This execution can modify the account's storage, create further accounts, and make additional message calls. The execution environment is defined with specific parameters that include the sender, gas price, and others relevant to the transaction context.

Exceptions and Code Execution

Gas consumption during initialization is critical. If the gas runs out, or if the code-deposit cost (associated with storing the initialization code on the blockchain) exceeds the remaining gas, an out-of-gas exception occurs. This results in the transaction being reverted without any changes to the state.

Finalization

If the initialization completes successfully and there are no exceptions:

  • The code of the new account is set.
  • Remaining gas is refunded.
  • The final state is updated to reflect the new account or any changes during initialization.

If any exceptions occur during initialization, such as out-of-gas or errors in the initialization code, the process may revert all changes, effectively leaving the blockchain state as it was before attempting the creation.

This detailed process ensures that account creation in Ethereum is secure and that each step—from checking the initial conditions to finalizing the state—adheres to the protocol’s stringent requirements. The complexity of this process underlines the flexibility and security considerations inherent in Ethereum’s design, particularly in how it handles new account creation and the execution of initialization code.

Message call

In Ethereum, executing a message call is a process that involves several parameters, with each playing a specific role in how the call is processed and how it interacts with the Ethereum Virtual Machine (EVM). Here's an organized breakdown of this process:

Parameters Required for a Message Call

  • Sender (
    s
    )
    : The account sending the message.
  • Transaction Originator (
    o
    )
    : The initiator of the transaction chain leading to this message call.
  • Recipient (
    r
    )
    : The account that receives the message.
  • Account to Execute Code (
    c
    )
    : Typically the same as the recipient unless specified otherwise.
  • Available Gas (
    g
    )
    : The gas limit set for this particular message call.
  • Value (
    v
    )
    : The amount of Ether to be transferred to the recipient.
  • Effective Gas Price (
    p
    )
    : The cost per unit of gas, which impacts the overall transaction cost.
  • Input Data (
    d
    )
    : A byte array containing data to be used by the called contract.
  • Call Stack Depth (
    e
    )
    : Indicates the depth of the call/contract creation stack at the time of this message call.
  • State Modification Permission (w): Permissions to alter the blockchain state during the execution.

Execution Process and Outcome

During the execution of a message call, a few important processes occur:

  1. State and Accrued Substate Evaluation: The message call leads to a transition to a new blockchain state

    σ0 and a new accrued substate
    A0
    , along with the consumption of some amount of gas
    g0
    and a resulting status code
    z
    .

  2. Value Transfer: The value

    v specified in the call is transferred from the sender to the recipient, adjusting their balances accordingly unless the sender and recipient are the same. If the recipient does not exist, it is created with a zero balance and nonce.

  3. Code Execution: The code associated with the recipient account

    c is executed. This code can be a smart contract residing at the recipient's address. The hash of this code
    KEC(Ib)
    is used to identify and execute the correct function or contract.

  4. Exception Handling: If an exception occurs due to reasons like out-of-gas, stack underflows, or invalid operations, the transaction may revert. This includes reverting state changes and potentially not refunding gas.

  5. Output Data: In scenarios where a message call is triggered by VM code execution, the output data from the call is captured and can be used further by the EVM.

Special Cases: Precompiled Contracts

  • Ethereum also specifies a set of precompiled contracts that perform common cryptographic operations. These are identified by specific addresses and include operations like public key recovery, hashing, and modular exponentiation.
  • These precompiled contracts are designed to offer efficient execution of operations that would otherwise be costly if implemented as regular smart contracts.

Execution Model and Framework

The execution model

Ξ handles various types of operations based on the code to be executed, which may involve specific precompiled contracts or custom smart contract code. The process ensures that the execution adheres to the gas constraints and correctly processes the input data and transfers value as intended.

This structured approach to message calls in Ethereum provides a robust framework for executing and interacting with smart contracts, ensuring that each step—from transferring value to executing complex operations—is handled securely and predictably within the EVM environment. This system supports Ethereum's capability to execute decentralized applications securely and efficiently.

Execution Model

The execution model of the Ethereum Virtual Machine (EVM) is designed to process bytecode within a structured environment, following a set series of operations dictated by the EVM’s quasi-Turing-complete nature. This limitation, primarily imposed by the gas system, serves to limit the total computation that can be performed.

EVM Architecture Basics

The EVM operates on a stack-based architecture with a 256-bit word size, ideal for cryptographic functions such as Keccak-256 hash and elliptic curve computations. It features:

  • Memory: A volatile, word-addressed byte array.
  • Stack: A simple data structure with a maximum size of 1024 elements.
  • Storage: A non-volatile, word-addressed word array that persists data across transactions.

The EVM does not follow a von Neumann architecture; instead, it stores program code in a separate virtual ROM, accessible only through specific instructions. Execution within the EVM can halt exceptionally for reasons such as stack underflows, invalid instructions, or running out of gas, with all state changes from the current transaction being discarded.

Fee Structure in the EVM

Fees in the EVM, denominated in gas, are incurred under three main circumstances:

  1. Computation Fees: Each operation has an intrinsic gas cost.
  2. Message Calls and Contract Creations: These include operations like CREATE, CREATE2, CALL, and CALLCODE, where gas forms part of the payment.
  3. Memory Usage: Fees increase with the expansion of memory usage, particularly when accessing memory beyond previously used limits.

Storage operations are particularly cost-sensitive. To encourage efficient use of storage, fees for clearing storage are not only waived but also refunded, promoting optimization of state usage.

Execution Environment

The execution environment of a transaction or operation in the EVM includes several key pieces of information:

  • Account Ownership (
    Ia
    )
    : Address owning the executing code.
  • Origin (
    Io
    )
    : Sender address of the original transaction.
  • Gas Price (
    Ip
    )
    : Cost per unit of gas.
  • Input Data (
    Id
    )
    : Data being passed to the executing code.
  • Sender (
    Is
    )
    : Address that initiated the code execution.
  • Value (
    Iv
    )
    : Ether sent along with the command.
  • Code (
    Ib
    )
    : Bytecode being executed.
  • Block Header (
    IH
    )
    : Contains details like the timestamp and block number.
  • Execution Depth (
    Ie
    )
    : Depth of CALLs or CREATEs at the moment.
  • State Modification Permission (
    Iw
    )
    : Whether the transaction can alter the state.

The function

Ξ computes the resulting state (
σ0
), remaining gas (
g0
), accrued substate (
A0
), and output (
o
) based on these environmental inputs.

Execution Process

Execution within the EVM is modeled as an iterative process involving:

  • State Transition: Defined by a function
    X
    that manipulates the full system state and the machine state iteratively.
  • Exception Handling: The function
    Z
    checks if the state is in an exceptional halting condition, indicating whether operations should be stopped and changes reverted.
  • Output Determination: The function
    H
    decides the output data based on the machine’s halting state, distinguishing between normal and exceptional halts.

The EVM manages execution through a series of operational cycles, with each cycle potentially altering the machine's state, adjusting the stack, or expanding memory, guided by specific instruction mnemonics.

EVM Machine State (
µ
)

The state of the machine during execution is represented as a tuple (

µ) consisting of:

  • Gas Available (
    g
    )
    : The amount of gas available for the execution.
  • Program Counter (
    pc
    )
    : A counter indicating the current instruction point in the bytecode.
  • Memory Contents (
    m
    )
    : Represents the volatile memory as a byte array, initially all zeros.
  • Active Memory Words (
    i
    )
    : The count of active words in memory, starting from position 0.
  • Stack Contents (
    s
    )
    : The contents of the stack, which can hold up to 1024 elements.

Exceptional Halting (Function Z)

The EVM can halt execution exceptionally due to various issues:

  • Insufficient Gas: If the gas required for the next operation exceeds the available gas.
  • Stack Underflows/Overflows: When operations attempt to pop more items from the stack than are available, or push beyond its maximum capacity.
  • Invalid Jumps: If a JUMP or JUMPI operation targets an invalid instruction point.
  • RETURNDATACOPY Issues: If this operation tries to access more return data than is available.
  • Invalid Instruction: Executing an undefined instruction or one that is inherently invalid.
  • Storage Access during Low Gas: Particularly when the gas remaining is insufficient for storage operations like SSTORE.

Jump Destination Validity (Function
D
)

The validity of jump destinations is crucial for the secure and correct execution of jump operations. A valid jump destination is defined as:

  • Position Containing JUMPDEST: Only positions explicitly marked with a JUMPDEST instruction are valid jump targets.
  • Instruction Boundaries: These must be at valid instruction boundaries and not within the data payloads of PUSH operations.

Normal Halting (Function
H
)

Normal halting occurs when execution completes without any runtime errors:

  • Controlled Halts: Operations like STOP, RETURN, REVERT, and SELFDESTRUCT lead to normal halts.
  • RETURN and REVERT: These return control to the calling function, potentially with data.
  • HRETURN Function: Specifically manages the data returned by RETURN and REVERT, ensuring that it is correctly handled or cleared if the execution context changes.

Execution Cycle and Memory Model

During the execution:

  • Memory Expansion: Accessing memory beyond the current limit incurs additional gas costs, calculated based on the smallest multiple of 32 bytes covering all accessed indices.
  • Instruction Execution: The cycle follows the opcode definitions, adjusting the program counter and stack accordingly.
  • Gas Calculation: Each instruction has a gas cost, which is deducted from the total available gas.

EVM Code Execution (Function
Ξ
)

The function

Ξ defines how the EVM processes each step in the execution:

  • Iterative Processing: The machine iterates over the bytecode, processing each instruction based on the current state and the defined operations.
  • State Transitions: Based on operations performed, the state of the EVM (including stack, memory, and program counter) is updated.
  • Exception and Output Handling: Determines whether to continue execution or halt (exceptionally or normally), and manages any data output from operations like RETURN.

The entire execution model of the EVM is designed to ensure that each transaction is processed securely and deterministically, adhering to the strict rules laid out by the Ethereum protocol. This structure supports the complex functionalities of smart contracts while maintaining the decentralized integrity of the Ethereum blockchain.

PoS Transition

The Paris hard fork marked a significant transition for Ethereum, shifting its consensus mechanism from Proof of Work (PoW) to Proof of Stake (PoS). This change represents a fundamental shift in how blocks are validated and new transactions are added to the blockchain.

Transition Criteria and Terminal Block

Unlike previous hard forks in Ethereum, which typically occurred at a predetermined block height, the Paris hard fork was designed to activate based on a specific condition known as the "terminal total difficulty" (TTD). This approach was chosen to mitigate potential risks associated with the transition:

  1. Avoiding Malicious Forks: By using total difficulty instead of block height, the transition avoids scenarios where a minority of hash power could potentially extend a competing PoW chain to reach a predefined block height first, thus creating a malicious fork. This method ensures that the transition to PoS would occur only when the cumulative difficulty of mined blocks reached a critical, predefined threshold, making it much harder for any minority group to influence or hijack the transition.

  2. Definition of Terminal Block: The terminal block, which is the last block mined using PoW, was defined by the following criteria:

    • The total difficulty of the block (
      Bt
      ) must exceed a predefined threshold (58750000000000000000000 in this case).
    • The total difficulty of its parent block
      P(BH)t
      must be less than this threshold.

Formula for Total Difficulty

Total difficulty (

Bt) of a block in the PoW system was calculated recursively as:

  • Bt
    P(BH)t
    +
    Hd
  • Where
    Hd
    is the difficulty of the current block
    B
    and
    P(BH)t
    is the total difficulty of its parent block.

This calculation accumulates the difficulty of each block, adding up to a total that reflects the overall computational effort expended to reach the current state of the blockchain.

Transition to Proof of Stake

Upon reaching the terminal block:

  • Beacon Chain Takes Over: The Beacon Chain, already running in parallel to the Ethereum mainnet, assumes responsibility for processing new blocks. Under PoS, blocks are validated by validators who stake their ETH to participate in the consensus mechanism, rather than by miners solving cryptographic puzzles.

  • Security and Efficiency: This transition not only aims to enhance the security of the Ethereum network by making it more decentralized but also significantly reduces its energy consumption, addressing one of the major criticisms of traditional PoW systems.

  • New Consensus Mechanism: The consensus under PoS is achieved through a combination of staking, attestation by validators, and algorithms that randomly select block proposers and committees to ensure the network remains secure and transactions are processed efficiently.

The Paris hard fork was a pivotal event in Ethereum's history, setting the stage for more scalable, sustainable, and secure operations. It represents Ethereum's commitment to innovation and its responsiveness to the broader societal concerns about the environmental impact of cryptocurrency mining.

Blocktree to Blockchain

Before the Paris hard fork, Ethereum's canonical blockchain was defined as the block path with the greatest total difficulty, as described above. This measure of total difficulty accumulated from the difficulty values of individual blocks under the Proof of Work (PoW) system.

However, following the transition to Proof of Stake (PoS) at the Paris hard fork, the rule of the greatest total difficulty was discontinued. Instead, the new rule implemented is known as LMD Ghost, which requires different information for determining the canonical Ethereum blockchain. This information must now include additional data from the Beacon Chain, which is not detailed in this document but is essential for the post-transition blockchain.

After the transition, the canonical chain is identified each time a POS_FORKCHOICE_UPDATED event is emitted by the Beacon Chain, starting with the first event at the transition block detailed in section 10. The chain is defined as starting from the genesis block and ending at the block nominated by the POS_FORKCHOICE_UPDATED event as the head of the chain.

The head of the chain should only be updated following a POS_FORKCHOICE_UPDATED event. Any updates to the head of the chain should only set the head to the block specified by the event, and no optimistic updates should be made without such an event. Each POS_FORKCHOICE_UPDATED event also references a finalized block, which should then be recognized as the most recent finalized block.

Additionally, the canonical blockchain must contain the block with the hash and number of the terminal block as defined in above section, which marks the end of PoW and the full transition to PoS.

Finalization

Finalizing a block in Ethereum involves two main steps: validating the transactions and verifying the state of the blockchain. Here’s a detailed explanation of these processes:

  1. Transaction Validation:

    • The total gas used in the block (
      BHg
      ) must exactly match the cumulative gas used by the last transaction in the block. This ensures that the gas usage reported by the block (
      BHg
      ) corresponds accurately to the total gas recorded across all transactions within it:
      • BHg=(R)u
    • Here,
      (R)u
      represents the summation of gas used by each transaction as recorded in the transaction receipts.
  2. State Validation:

    • Define a function
      Γ
      , which determines the initial state of the block
      B
      :
      • If
        B
        's parent block header
        P(BH)
        is undefined (
        ϕ
        ), the initial state is
        σ0
        .
      • Otherwise,
        σi
        is used where
        σi
        is the state that, when processed through the trie data structure, matches the state root (
        Hr
        ) of the parent block
        P(BH)
        . This ensures that the block’s initial state corresponds to the ending state of the previous block.
    • The block transition function
      Φ
      takes an incomplete block
      B
      and maps it to a completed block
      B
      , where
      B
      differs from
      B
      only in the state root (
      Hr
      ), which is set to the result of applying the state-transition function
      Π
      to
      Γ(B)
      and
      B
      :
      • B[Hr]=TRIE(LS(Π(Γ(B),B)))
    • The state-transition function
      Π
      , defined using the transaction evaluation function
      Υ
      , processes each transaction and the resultant states sequentially:
      • σ[n]=Υ(σ[n1],BT[n])
        if
        n0
        , starting from the initial state
        Γ(B)
        for the first transaction.

For each transaction

BT[n]:

  • R[n]u
    is defined as the cumulative gas used, which is the gas for the current transaction added to the cumulative gas used up to the previous transaction.
  • R[n]l
    uses the function
    Υl
    , which captures the logs generated by executing the transaction.
  • R[n]z
    uses
    Υz
    , capturing the transaction's resulting status code.

Finally,

Π(σ,B), representing the state after the final transaction has been processed, is defined as the last state produced
σ
. This entire mechanism outlines how a block transitions from an initial to a final state before it is validated and added to the blockchain, ensuring all transactions are properly executed and the resulting state is consistent with the block’s data.

Note: The notes are good but please yellow paper as well. I've omitted alot of details especially abstracted alot of Math here and there. Refer appendices from the yellow paper as well.