Ethereum & Smart Contracts

EVM Deep Dive

The EVM Deep Dive

Module 2 of Ethereum & Smart Contracts


What Is the EVM?

The Ethereum Virtual Machine (EVM) is the runtime environment for smart contracts. Every Ethereum node runs an identical copy.

Think of it as:

  • The "CPU" of Ethereum's world computer
  • A sandboxed execution environment
  • A deterministic state machine

Key Properties

1. Deterministic

Same input ALWAYS produces same output.

Given:
  - Current state
  - Transaction

Output is completely predictable.
No randomness, no external data (without oracles).

2. Isolated

Contracts can only interact through defined interfaces.

  • Cannot access filesystem
  • Cannot access network
  • Cannot access other contracts' storage directly

3. Stack-Based

Operations work on a Last-In-First-Out stack.

Stack size: 1024 elements max
Element size: 256 bits (32 bytes)

4. Resource-Metered

Every operation costs gas. This:

  • Prevents infinite loops
  • Compensates validators
  • Creates a fee market

EVM Architecture

Memory Model

┌─────────────────────────────────────┐
│ STACK                               │
│ - 1024 max depth                    │
│ - 256-bit words                     │
│ - Cheapest computation              │
├─────────────────────────────────────┤
│ MEMORY                              │
│ - Byte-addressable                  │
│ - Volatile (cleared after call)     │
│ - Expansion costs gas               │
├─────────────────────────────────────┤
│ STORAGE                             │
│ - Key-value store (256-bit → 256-bit)│
│ - Persistent across calls           │
│ - Most expensive operations         │
├─────────────────────────────────────┤
│ CALLDATA                            │
│ - Read-only input data              │
│ - Passed in transaction             │
├─────────────────────────────────────┤
│ CODE                                │
│ - Immutable contract bytecode       │
│ - Can be read with CODECOPY         │
└─────────────────────────────────────┘

Gas Costs by Area

OperationGas CostWhy
Stack (ADD, MUL)3-5Cheap, in-memory
Memory read/write3Volatile, ephemeral
Storage read (warm)100Persistent, cached
Storage read (cold)2,100Persistent, uncached
Storage write (new)20,000Permanent state change
Storage write (existing)5,000Modifying existing

Bytecode and Opcodes

What Is Bytecode?

Compiled smart contract code:

Solidity:
function add(uint a, uint b) returns (uint) {
    return a + b;
}

Bytecode:
6080604052... (hex string)

Opcodes:
PUSH1 0x80
PUSH1 0x40
MSTORE
...
ADD

Common Opcodes

Stack Operations

OpcodeHexDescription
PUSH10x60Push 1 byte
POP0x50Remove top
DUP10x80Duplicate top
SWAP10x90Swap top two

Arithmetic

OpcodeHexDescription
ADD0x01Addition
MUL0x02Multiplication
SUB0x03Subtraction
DIV0x04Division

Comparison

OpcodeHexDescription
LT0x10Less than
GT0x11Greater than
EQ0x14Equality

Memory/Storage

OpcodeHexDescription
MLOAD0x51Load from memory
MSTORE0x52Store to memory
SLOAD0x54Load from storage
SSTORE0x55Store to storage

Control Flow

OpcodeHexDescription
JUMP0x56Unconditional jump
JUMPI0x57Conditional jump
STOP0x00Halt execution
RETURN0xF3Return data
REVERT0xFDRevert with data

Execution Context

Transaction Context

Available during execution:

msg.sender  // Immediate caller address
msg.value   // ETH sent with call
msg.data    // Calldata (function + args)
tx.origin   // Original EOA (dangerous!)
tx.gasprice // Gas price of transaction

Block Context

block.number     // Current block number
block.timestamp  // Current block timestamp
block.coinbase   // Block validator address
block.gaslimit   // Block gas limit
block.basefee    // Current base fee (EIP-1559)

Contract Interactions

Types of Calls

Call TypeState ChangeGasReturns
CALLYes (other contract)ForwardedYes
DELEGATECALLYes (this contract)ForwardedYes
STATICCALLNoForwardedYes
CALLCODEDeprecated--

CALL vs DELEGATECALL

CALL:
  Caller → Contract B
  - msg.sender = Caller
  - Modifies B's storage

DELEGATECALL:
  Caller → Contract B (as library)
  - msg.sender = Original sender
  - Modifies Caller's storage
  - B's code runs in Caller's context

DELEGATECALL is powerful but dangerous — used in proxy patterns.


Contract Creation

CREATE

Deploy at deterministic address:

address = keccak256(deployer, nonce)[-20:]

Address depends on deployer's nonce (changes each transaction).

CREATE2

Deploy at predictable address:

address = keccak256(0xff, deployer, salt, keccak256(bytecode))[-20:]

Same salt + bytecode = same address (before deployment).

Use case: Counterfactual contracts, deterministic deployments.


Error Handling

REVERT

Returns unused gas, reverts all state changes.

require(condition, "Error message");
// If false, reverts with message

Out of Gas

When gas runs out:

  • All state changes reverted
  • Gas is NOT refunded
  • Transaction marked as failed

Assert Failures

assert(condition);
// If false, consumes ALL remaining gas
// Use for invariants that should never fail

Precompiled Contracts

Special contracts at low addresses with native implementations:

AddressFunctionGasUse Case
0x01ECRECOVER3000Signature recovery
0x02SHA25660+Hashing
0x03RIPEMD160600+Hashing
0x04IDENTITY15+Data copy
0x05MODEXPVariableRSA verification
0x06-0x08BN128 opsVariableZK proofs
0x09BLAKE2BVariableZcash compatibility

These are much cheaper than implementing in Solidity.


EVM Limitations

1. No Floating Point

Only integers. Use fixed-point math:

// Instead of 0.5
uint256 HALF = 5 * 10**17; // 0.5 * 10**18

2. No Randomness

Blockchain is deterministic. "Random" solutions:

  • Commit-reveal schemes
  • Chainlink VRF (external oracle)
  • Block hash (weak, manipulable)

3. No External Data

Can't fetch APIs or URLs. Solutions:

  • Oracles (Chainlink, API3)
  • User-provided data (with verification)

4. 256-bit Words

Smaller types still use full word:

uint8 a = 1;  // Still 256 bits in storage

Pack multiple values to save gas.


The Future: EVM Evolution

EVM Object Format (EOF)

New bytecode format:

  • Separation of code and data
  • Better static analysis
  • Removal of dynamic jumps

Verkle Trees

Replace Merkle Patricia Tries:

  • Smaller proofs
  • Enable stateless clients

Alternative VMs

Some chains use different VMs:

  • SVM (Solana)
  • MoveVM (Aptos, Sui)
  • WASM (Polkadot, Near)

Key Takeaways

  1. EVM is a stack-based, deterministic VM
  2. Three memory areas: Stack (cheap), Memory (volatile), Storage (expensive)
  3. Gas meters all computation — prevents abuse
  4. Opcodes are low-level — Solidity abstracts them
  5. Different call types have different security implications
  6. Precompiles provide efficient cryptographic operations

Questions to Consider

  1. Why is storage so expensive compared to memory?
  2. When would you use CREATE2 vs CREATE?
  3. What makes DELEGATECALL dangerous?
  4. Could the EVM be replaced with WASM?