Skip to content

Latest commit

 

History

History
185 lines (117 loc) · 6.66 KB

File metadata and controls

185 lines (117 loc) · 6.66 KB

EVM Foundations (Days 1–7)

Goal: build solid mental models of EVM execution, storage, state, and gas—validated by small, real traces on your node.


Prereqs (install any you’re missing)


Day 1 — Big-picture EVM & “living spec”

Read

Output

  • 1-page notes: account model, call stack vs. memory vs. storage, gas lifecycle, where env/state come from.

Day 2 — Yellow Paper (surgical read)

Read (targeted)

Output

  • Bullet list of invariants (e.g., call/revert behavior, exceptional halts, memory expansion rules).

Day 3 — Opcodes by category + minimal bytecode

Read

Hands-on

# Tiny contract → bytecode & opcodes
printf 'pragma solidity ^0.8.20; contract T { function f(uint x) public pure returns(uint){ return x+1; } }' > T.sol
solc --bin --opcodes T.sol

Output

  • 10–15 opcode “flashcards” with purpose + gotcha (e.g., CALL gas stipend, JUMPDEST, PUSH0).

Day 4 — Trace one real mainnet tx end-to-end

Read

Hands-on (pick a tx hash you care about)

# Inspect tx quickly
cast tx 0xYOUR_TX_HASH --json | jq '.'

# Geth-style deep trace (call graph)
curl -s -X POST http://127.0.0.1:8545 \
  -H 'content-type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"debug_traceTransaction",
           "params":["0xYOUR_TX_HASH", {"tracer":"callTracer","timeout":"30s"}]}' | jq '.'

# Optional: step-by-step VM trace
curl -s -X POST http://127.0.0.1:8545 \
  -H 'content-type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"debug_traceTransaction",
           "params":["0xYOUR_TX_HASH", {"tracer":"vmTrace","timeout":"30s"}]}' | jq '.'

Output

  • Short write-up mapping call tree ↔ opcodes/memory/storage deltas for one internal call.

Day 5 — Storage layout, mappings, and proofs

Read

Hands-on (ERC-20 balance slot example)

  • For mapping(address⇒uint) at slot p (often 0): storage slot = keccak256(pad32(addr) ++ pad32(p))
# Read a raw storage slot once you've computed it
cast storage 0xTOKEN_ADDRESS 0xCOMPUTED_SLOT
# Or raw JSON-RPC
cast rpc eth_getStorageAt 0xTOKEN_ADDRESS 0xCOMPUTED_SLOT latest

# Get Merkle proof for account + specific storage keys
cast rpc eth_getProof 0xTOKEN_ADDRESS '["0xCOMPUTED_SLOT"]' latest | jq '.'

Output

  • One example showing: computed slot → raw 32-byte value → decoded balance (uint256).

Day 6 — Tries & encoding (just enough to reason about state)

Read

Hands-on (light)

# Fetch a block header and tx for context
cast block 17000000 --json | jq '.'
cast tx 0xYOUR_TX_HASH --json | jq '.'

Output

  • Diagram that names the tries (state / tx / receipt), and where your Day-5 storage proof sits in the state trie.

Day 7 — Gas you must actually know (post-fork reality)

Read (EIPs)

Hands-on

# Compare gas behavior via traces for two txs:
# (1) cold SLOAD/SSTORE vs (2) warmed access or no-op SSTORE
# Use callTracer/vmTrace from Day 4 and note gas deltas at the op level.

Output

  • Table with 3 rows: memory expansion cost example, SSTORE (0→non-0 vs non-0→non-0), cold→warm access delta.

Optional quick references


What’s next (use your codebase/tests)

  • Map your C++ EVMC/evmONE boundaries, then replay the Day-4 tx with your internal parallel re-execution + tracers.
  • Cross-check side effects and gas accounting against geth’s traces.