Ethereum State Data Structures

Ethereum state is stored in four different modified merkle patricia tries (MMPTs): the transaction, receipt, state, and storage tries. At each block there is one transaction, receipt, and state trie which are referenced by their root hashes in the block Header. For every contract deployed on Ethereum there is a storage trie used to hold that contract's persistent variables, each storage trie is referenced by their root hash in the state account object stored in the state trie leaf node corresponding to that contract's address.

Trie Node IPLD

This is the general MMPT node IPLD schema used by all the below MMPTs (everything below except the AccountSnapshot). The different tries are broken up and explicitly typed below in order to demonstrate the different purposes and contents of these trie structures.

NOTE: if the value stored at a leaf node would be smaller than or equal to the length of the hash of that leaf node (<= 32 bytes) then the value is directly included in the parent branch or extension node rather than the parent node linking to the entire leaf node. In this case the child is a one element list of bytes where that one element is the RLP encoded value itself. In practice this is only possible for the storage trie, as RLP encoded transactions, receipts, and state accounts are always greater than 32 bytes in length.

# TrieNode ADL
# Node IPLD values are RLP encoded; node IPLD multihashes are always the KECCAK_256 hash of the RLP encoded node bytes and the codec is dependent on the type of the trie
type TrieNode struct {
    Elements [Bytes]
}

Maybe make TrieNode a union type of 3 different node types

Transaction Trie IPLD

This is the IPLD schema type for transaction trie nodes.

# TxTrieNode is an IPLD block for a node in the transaction trie
type TxTrieNode TrieNode

Receipt Trie IPLD

This is the IPLD schema type for receipt trie nodes.

# RctTrieNode is an IPLD block for a node in the receipt trie
type RctTrieNode TrieNode

State Trie IPLD

This is the IPLD schema type for state trie nodes.

# StateTrieNode is an IPLD block for a node in the state trie
type StateTrieNode TrieNode

State Account IPLD

This is the IPLD schema for a state account in the Ethereum state trie.

# Account is the Ethereum consensus representation of accounts.
# These objects are stored in the state trie leafs.
type StateAccount struct {
    Nonce    Uint
    Balance  Balance
    
    # CID link to the storage trie root node
    # This CID links down to all of the storage nodes that exist for this account at this block
    # This CID uses the EthStorageTrie codec (0x98)
    # If this is a contract account the multihash is a KECCAK_256 hash of the RLP encoded root storage node
    # If this is an externally controlled account, the multihash is a KECCAK_256 hash of an RLP encoded empty byte array
    StorageTrieCID &StorageTrieNode
    
    # CID link to the bytecode for this account
    # This CID uses the Raw codec (0x55)
    # If this is a contract account the multihash is a KECCAK_256 hash of the contract byte code for this contract
    # If this is an externally controlled account the multihash is the KECCAK_256 hash of an empty byte array
    CodeCID &ByteCode
}

type ByteCode bytes

Storage Trie IPLD

This is the IPLD schema type for storage trie nodes.

# StorageTrieNode is an IPLD block for a node in the storage trie
# The root node of the storage trie is referenced in an StateAccount by the StorageTrieCID
type StorageTrieNode TrieNode