Overview
A common distinction between Ethereum and Bitcoin lies in their on-chain data models. Bitcoin operates on a UTXO-based blockchain/ledger system, while Ethereum utilizes an Account/State model. But what exactly makes this Account/State model different? This article explores Ethereum's fundamental data unit - the Account.
Ethereum operates as a _transaction-based state machine_. The system consists of multiple accounts (similar to bank accounts), where:
- State reflects an account's value at a specific moment
- The basic data structure representing state is called StateObject
- When StateObject values change, we call this state transition
Accounts serve as:
- The basic unit in Ethereum's state machine model
- Participants in on-chain transactions (as both initiators and receivers)
- Currently, Ethereum has two account types: External Owned Accounts (EOA) and Contract Accounts
External Owned Accounts (EOA)
EOAs are user-controlled accounts that:
- Sign and initiate transactions
- Maintain control via private keys
- Don't contain executable code
Contract Accounts
Contract accounts:
- Are created by EOAs via transactions
- Store immutable, Turing-complete code segments and persistent data variables
- Use specialized languages (like Solidity) with external API interfaces
- Form the foundation of DApp ecosystems
Key clarification:
- Only contract code logic is immutable
- Persistent data variables can be modified through function calls
StateObject, Account, and Contract
In actual code, both account types are defined by the stateObject data structure (core/state/state_object.go). Key components include:
Address
type Address [AddressLength]byte // AddressLength = 20
type Hash [HashLength]byte // HashLength = 32Each account has a unique 20-byte address that serves as immutable identification.
Data and StateAccount
The StateAccount structure (core/types/state_account.go) contains:
Nonce: Transaction sequence numberBalance: Account's Ether balanceRoot: Storage layer Merkle Patricia Trie root (for contracts)CodeHash: Contract code hash (empty for EOAs)
Database Reference
The db variable holds a StateDB pointer for account operations. StateDB essentially serves as an in-memory database managing stateObject information.
Storage Cache
Four Storage type variables serve as memory caches for contract data:
trie: Manages persistent contract variablescode: Caches contract bytecodeoriginStorage,pendingStorage,dirtyStorage,fakeStorage: Cache modified persistent data during transactions
Deep Dive into Accounts
Private Key, Public Key, and Address
Account security relies on:
- Cryptographic strength of Ethereum's tools
- Proper contract implementation (for token security)
Account generation involves:
- Creating a 64-character private key (32 bytes)
- Deriving public key via ECDSA (spec256k1 curve)
- Generating address from the public key's Keccak-256 hash (last 20 bytes)
Signature and Verification
Ethereum uses ECDSA signatures where:
- The private key signs transaction data
- The signature allows public key recovery
- Recovered addresses must match transaction senders
Deep Dive into Contracts
Contract Storage
Contract accounts maintain independent storage spaces with:
- Basic units called Slots (256 bits each)
- Theoretical maximum of $2^{256} - 1$ slots
- Managed via MPT (Merkle Patricia Trie)
Storage Examples
Example 1: Sequential variable declaration
uint256 number; // Slot 0
uint256 number1; // Slot 1
uint256 number2; // Slot 2Storage follows declaration order regardless of assignment.
Example 2: Reordered declaration
uint256 number2; // Slot 0
uint256 number; // Slot 1
uint256 number1; // Slot 2Slot assignment follows declaration sequence.
Example 3: Partial assignment
uint256 number; // Slot allocated but unused
uint256 number1; // Slot 1
uint256 number2; // Slot 2Slots are allocated at declaration, not first assignment.
Example 4: Mixed-size variables
uint256 number; // Slot 0
address addr; // Slot 1 (shared with isTrue)
bool isTrue; // Slot 1 (shared with addr)Smaller variables may share slots (but cause read/write amplification).
Example 5: Mapping storage
mapping(string => uint256) balances; // Slot 1Map elements use keccak256(key, slot_position) for storage location.
FAQ
Q: Can contract code be modified after deployment?
A: No, contract code is immutable. Only persistent data variables can be modified.
Q: How are mapping elements stored?
A: Using keccak256(key, slot_position) to determine storage location.
Q: Do smaller variable types save gas?
A: Not always. 32-byte variables may be more gas-efficient due to reduced read/write operations.
๐ Learn more about Ethereum account security
๐ Understanding smart contract storage