Skip to main content

EOA vs Contract Account: Architecture

EOA vs contract account architecture: state fields, validation logic, deployment, gas semantics, and how the Ethereum protocol distinguishes the two.

Written by Eco
Updated today


The Ethereum protocol defines exactly two account types: externally owned accounts (EOAs) and contract accounts. The architectural difference is the value of two of the four state fields. An EOA's code hash is the keccak-256 hash of the empty string and its storage trie is empty. A contract account's code hash points to deployed bytecode and its storage trie persists state. Everything else (ECDSA validation versus contract-defined validation, the ability to originate transactions, gas semantics, deployment cost) follows from those two facts. The Ethereum.org account specification formalizes the distinction.

This article walks through the four-field account state, how validation differs between the two types, the consequences for transaction origination, deployment, gas, and cross-chain address derivation, and how EIP-7702 introduces a hybrid that breaks the clean two-class taxonomy.

What Is an EOA?

An externally owned account is an Ethereum account whose authority lives outside the chain in a private key. The key is a 256-bit integer drawn from the secp256k1 curve order. The corresponding 20-byte address is derived deterministically: hash the public key with keccak-256, take the last 20 bytes, encode in EIP-55 mixed-case checksum format.

EOAs can originate transactions because the protocol's signature-validation rule (verify ECDSA over secp256k1 against the sender address) is hard-coded in the EVM. They are universal across EVM chains: the same private key controls the same address on Ethereum, Arbitrum, Base, Polygon, and roughly 200 other chains.

What Is a Contract Account?

A contract account is created by deploying bytecode through a transaction. The address is derived from either the sender and nonce (CREATE) or the sender, salt, and bytecode hash (CREATE2, defined in EIP-1014). Authority lives in the bytecode: a call to the contract executes its code, which can implement any validation rule the developer encodes.

Contract accounts cannot originate transactions on their own. They need an EOA (or another contract initiated by an EOA) to call them. ERC-4337 works around this by introducing an off-chain EntryPoint and bundlers, but the protocol-level constraint stands: every chain of calls traces back to an EOA signature.

The Four-Field Account State

Both account types are stored as the same tuple in the world-state Merkle Patricia trie. The tuple has four fields. Two are identical in shape between EOAs and contracts. Two encode the architectural difference.

Nonce

For an EOA, the nonce counts outgoing transactions. Each transaction increments it by one. The nonce prevents replay: a signed transaction with nonce 7 can be included exactly once. For a contract account, the nonce starts at 1 (since EIP-161) and increments each time the contract creates a new contract via CREATE.

Balance

The wei balance of the account. One ether equals 10^18 wei. Identical semantics for both account types. Token balances (ERC-20, ERC-721) are not stored in this field; they live in the token contract's storage trie indexed by account address.

Storage Root

The root hash of the account's storage trie. For an EOA, this is the empty trie hash (0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421). For a contract, the storage root commits to the entire contents of the contract's storage slots — every SSTORE changes it.

Code Hash

The keccak-256 hash of the account's bytecode. For an EOA, this is the hash of the empty string (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470). For a contract, this is the hash of the deployed bytecode. EIP-7702 introduces a third case: a delegated EOA whose code hash points to a target contract's code without the EOA itself having deployed any bytecode.

How Validation Differs

Validation is the protocol's mechanism for deciding whether a transaction is authorized. It is the deepest architectural difference between the two account types.

EOA Validation: Fixed by the Protocol

An EOA transaction is valid if and only if the ECDSA signature recovers to the sender's address. The check is implemented in the EVM's transaction processing: extract (v, r, s) from the transaction, recover the signer with ecrecover, compare to tx.from. There is no flexibility. Every EOA on Ethereum validates the same way.

Contract Account Validation: Defined by Code

A contract account validates by running its code. Safe validates by checking that N of M owners signed the transaction hash. Argent validates by checking the signer's signature plus optional guardian timelocks. An ERC-4337 wallet validates by running validateUserOp, which can require a passkey, a session key, or any other policy.

Custom validation is what makes contract accounts powerful. A contract can require a passkey signature, a multisig threshold, a daily spend limit, a session key bounded to one dapp, or a hardware-attested signature. Each of these patterns is impossible to express in a pure EOA.

Transaction Origination

Only EOAs can originate transactions. The protocol's transaction-pool semantics require an ECDSA signature, and a contract account has no private key to sign with. Every contract call traces back to an EOA-originated transaction, possibly through several layers of contract-to-contract calls.

ERC-4337 sidesteps this by defining a separate user-operation mempool. Users sign user operations off-chain. A bundler (an EOA or a contract called by an EOA) collects user operations into a single transaction sent to the EntryPoint contract, which dispatches each operation to its target wallet. The protocol still requires an EOA at the bottom of the call stack, but the user-facing experience is "the smart wallet is the sender."

Deployment and Cost

EOAs are free. A wallet generates a key pair offline and the address exists. The account only consumes state when it sends or receives its first transaction.

Contract accounts cost gas. A typical Safe deployment on Ethereum mainnet uses 200K to 300K gas, which at a 15-gwei base fee runs $5 to $10 per deployment. ERC-4337 wallets can defer this through counterfactual deployment: the wallet's address is computed via CREATE2 before the contract exists, and the deployment transaction is bundled into the first user operation. The user does not pay deployment gas separately.

Gas Semantics

An EOA pays gas in the chain's native token. ETH on Ethereum, MATIC on Polygon, BNB on BNB Chain. The gas comes out of the EOA's balance.

A contract account can pay gas in any token through a paymaster. The paymaster is a contract that fronts the gas in native token and bills the user in another asset. Alchemy's gas manager processes more than 10 million sponsored user operations per month, according to its 2025 paymaster metrics.

Address Derivation Across Chains

An EOA address is the same on every EVM chain because the derivation is deterministic from the public key. The chain ID does not enter the calculation. A single private key controls 200+ chain addresses simultaneously.

A contract account address depends on the deployment method. CREATE addresses depend on the deployer EOA's address and nonce, so they differ across chains. CREATE2 addresses depend on the deployer, salt, and init-code hash, so they can be made identical across chains if every chain uses the same factory and the same parameters. EIP-2470's singleton factory is deployed at the same address on most chains specifically to enable cross-chain identical contract addresses. Rhinestone Omni Accounts standardizes the salt-and-factory pattern for cross-chain smart accounts.

The EIP-7702 Hybrid

EIP-7702, included in the Pectra hardfork that activated on May 7, 2025, breaks the clean EOA-versus-contract taxonomy. Under 7702, an EOA can sign an authorization tuple (chain_id, contract, nonce, signature) that temporarily attaches contract code to its address. The EOA's code hash, normally the hash of the empty string, becomes the hash of the target contract's code for the duration of the authorization.

A 7702-delegated EOA validates like a contract account (running the delegated code's validation logic) but originates transactions like an EOA (signing with the original ECDSA private key). It is neither cleanly an EOA nor a contract account at the protocol level. The Ethereum specification updated to acknowledge this third class of behavior.

Side-by-Side Architecture Reference

Field

EOA

Contract Account

EIP-7702 Delegated EOA

Code hash

Empty string hash

Hash of bytecode

Hash of delegated bytecode

Storage root

Empty trie hash

Hash of storage trie

Empty trie hash

Validation

ECDSA on secp256k1

Contract-defined

Contract-defined (delegated)

Originates transactions

Yes

No (needs EOA caller)

Yes

Address derivation

Public key hash

CREATE / CREATE2

Public key hash

Same address across chains

Yes

Only with shared factory

Yes

Deployment cost

Free

200-300K gas

Free (delegation tx only)

Gas payment

Native token only

Any token via paymaster

Any token via paymaster

Eco's Role: Routing Across the Account-Type Boundary

Eco is the stablecoin execution network that abstracts the account-type distinction at the orchestration layer. A user holding USDC in an EOA, a Safe, or a 7702-delegated wallet signs one intent. Eco's solver network selects between Circle CCTP, Hyperlane, LayerZero, and Wormhole rails to route the stablecoin to the destination chain. Eco Accounts is the standardized smart-account layer that pairs cleanly with both EOAs and contract accounts so multi-chain stablecoin flows take one signature regardless of which account type the user prefers. The protocol-level distinction stops mattering at the integration boundary.

FAQ

Can a contract account hold ETH?

Yes. The balance field is identical for both account types. A contract account can hold ETH, ERC-20s, ERC-721s, and any other asset whose token contract supports the address as a recipient. The contract just cannot spend its ETH without an EOA-originated transaction triggering its code.

Why does the protocol track a nonce on contract accounts?

To address newly deployed contracts deterministically. The CREATE opcode derives the new contract's address from the deployer's address and nonce. Every CREATE in a contract increments its nonce by one, ensuring each child contract has a unique address. EIP-161 sets the starting nonce at 1 for contracts.

Is a multisig wallet an EOA or a contract account?

A multisig wallet (Safe, Aragon, Gnosis) is a contract account. The contract enforces the M-of-N signature threshold. The signers themselves are typically EOAs whose private keys live in hardware wallets, but the multisig itself is a contract.

How does EIP-7702 affect existing EOAs?

It does not affect EOAs that do not opt in. Existing EOAs continue to behave exactly as before. EOAs that sign a 7702 authorization gain contract-account-like validation for as long as the delegation is active, and can revoke the delegation at any time. EIP-7702 is opt-in, not a global change.

Can a contract account become an EOA?

No. The deployment is irreversible: once bytecode is committed, the contract account exists with that code hash forever. SELFDESTRUCT was historically the closest thing to deletion, but EIP-6780 in the Cancun hardfork (March 2024) restricted SELFDESTRUCT to the same transaction the contract was created in, removing the on-chain "delete contract" path.

Did this answer your question?