Skip to main content

Overview

AccountState represents the four fields of an Ethereum account as defined in the Yellow Paper (section 4.1). Every account has a nonce, balance, storage root, and code hash.
const primitives = @import("primitives");
const state = .{
    .nonce = 5, // u64
    .balance = 1_000_000_000_000_000_000, // 1 ether in wei
    .storage_root = try primitives.Hash.fromHex(
        "0x56e81f171bcc55a6ff8345e692c0f86e5b47e5b60e2d8c5ab6c7c9fa0e32d3c5",
    ),
    .code_hash = try primitives.Hash.fromHex(
        "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
    ),
};

Type Definition

// Use primitives types: Nonce (u64), Hash (B256) and balances in wei (u256).
Fields:
  • nonce - Transaction count (EOA) or contract creations (contract)
  • balance - Account balance in Wei
  • storageRoot - Merkle Patricia Trie root of storage slots
  • codeHash - Keccak256 hash of EVM bytecode

Creating AccountState

from

Universal constructor from object with required fields.
const primitives = @import("primitives");
const state = .{
    .nonce = 0,
    .balance = 0,
    .storage_root = primitives.State.EMPTY_TRIE_ROOT,
    .code_hash = primitives.State.EMPTY_CODE_HASH,
};

createEmpty

Creates an empty EOA (Externally Owned Account) with zero balance and nonce.
const primitives = @import("primitives");
const empty_nonce: u64 = 0;
const empty_balance: u256 = 0;
const storage_root = primitives.State.EMPTY_TRIE_ROOT;
const code_hash = primitives.State.EMPTY_CODE_HASH;

Account Type Detection

isEOA

Checks if account is an Externally Owned Account (has no bytecode).
// EOA if code_hash == EMPTY_CODE_HASH
const is_eoa = std.mem.eql(u8, &state.code_hash, &primitives.State.EMPTY_CODE_HASH);

isContract

Checks if account is a contract (has bytecode).
// Contract if code_hash != EMPTY_CODE_HASH
const is_contract = !std.mem.eql(u8, &state.code_hash, &primitives.State.EMPTY_CODE_HASH);

Comparing AccountStates

equals

Compares all four fields for equality.
const a = state;
const b = state;
const equal = std.mem.eql(u8, &a.code_hash, &b.code_hash) and
              std.mem.eql(u8, &a.storage_root, &b.storage_root) and
              a.nonce == b.nonce and a.balance == b.balance;

Constants

// Keccak256 of empty string - used for EOA code hash
AccountState.EMPTY_CODE_HASH
// "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"

// Keccak256 of RLP([]) - used for EOA storage root
AccountState.EMPTY_TRIE_HASH
// "0x56e81f171bcc55a6ff8345e692c0f86e5b47e5b60e2d8c5ab6c7c9fa0e32d3c5"

EOA vs Contract Accounts

FieldEOAContract
nonceTransaction countContract creations
balanceETH ownedETH owned
storageRootEMPTY_TRIE_HASHStorage trie root
codeHashEMPTY_CODE_HASHBytecode hash

See Also