Goal: build solid mental models of EVM execution, storage, state, and gas—validated by small, real traces on your node.
- Geth (or your node with debug/trace APIs): https://geth.ethereum.org/
- Foundry (cast/forge): https://book.getfoundry.sh/
- Solidity compiler (solc): https://docs.soliditylang.org/en/latest/installing-solidity.html
Read
-
EVM overview: https://ethereum.org/en/developers/docs/evm/
-
Execution-specs (EELS) README: https://github.com/ethereum/execution-specs
-
Keep these open while learning:
- Opcodes (reference): https://ethereum.org/en/developers/docs/evm/opcodes/
- Opcodes (interactive, gas, traces): https://www.evm.codes/
Output
- 1-page notes: account model, call stack vs. memory vs. storage, gas lifecycle, where env/state come from.
Read (targeted)
- Yellow Paper PDF: https://ethereum.github.io/yellowpaper/paper.pdf Focus: State transition (transactions→blocks), Execution model, Gas, Memory, and the Opcode appendix.
Output
- Bullet list of invariants (e.g., call/revert behavior, exceptional halts, memory expansion rules).
Read
- Opcode groups (stack/mem/storage/call/flow/log/precompiles) via: https://www.evm.codes/
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.solOutput
- 10–15 opcode “flashcards” with purpose + gotcha (e.g.,
CALLgas stipend,JUMPDEST,PUSH0).
Read
- JSON-RPC basics: https://ethereum.org/en/developers/docs/apis/json-rpc/
- Geth tracing overview: https://geth.ethereum.org/docs/developers/evm-tracing
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.
Read
- Solidity storage layout: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html (mappings/dynamic arrays hashing formula)
eth_getProof: https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getproof
Hands-on (ERC-20 balance slot example)
- For
mapping(address⇒uint)at slotp(often0): 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).
Read
- Merkle–Patricia Trie: https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/
- RLP: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/
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.
Read (EIPs)
- SSTORE pricing: https://eips.ethereum.org/EIPS/eip-2200
- Warm/cold access: https://eips.ethereum.org/EIPS/eip-2929
- Refund reductions: https://eips.ethereum.org/EIPS/eip-3529
- Access lists: https://eips.ethereum.org/EIPS/eip-2930
- Newer opcodes to recognize:
PUSH0(Shanghai) https://eips.ethereum.org/EIPS/eip-3855MCOPY(Shanghai) https://eips.ethereum.org/EIPS/eip-5656TLOAD/TSTORE(Cancun) https://eips.ethereum.org/EIPS/eip-1153
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.
- EVM From Scratch (stepwise, multi-lang): https://www.evm-from-scratch.xyz/
- EIP index (when you hear an opcode/fork name): https://eips.ethereum.org/
- evm.codes playground (paste bytecode, step it): https://www.evm.codes/playground
- 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.