Deep Dive — Module 1
Review questions for Module 1. Try answering before expanding.
Q: Why does Ethereum use 256-bit words instead of 64-bit?
Answer
Answer
Keccak-256 produces 32-byte hashes, and Ethereum uses Keccak pervasively — for storage keys, address derivation, and state root computation. A 256-bit word can hold a full hash without truncation. Additionally, 256-bit keys provide 128-bit security against brute-force preimage attacks, which is the standard cryptographic target.
Q: What happens when the EVM stack overflows?
Answer
Answer
If a contract pushes the 1025th element, the EVM triggers an exceptional halt — not a REVERT. All state changes are discarded and all remaining gas is consumed. This is a hard protocol limit (Yellow Paper §9.4.2), not a configurable parameter. Note the difference from REVERT, which refunds unused gas.
Q: Is EVM memory persistent between transactions?
Answer
Answer
No. Memory () is ephemeral — it is allocated fresh for each execution context and destroyed when execution completes. Storage () is the persistent key-value map that survives between transactions. Confusing the two is a common mistake in technical discussions.
Q: What does it mean for EVM execution to be deterministic?
Answer
Answer
Given the same world state and the same transaction T, every EVM implementation must produce the exact same output state , return data, gas usage, and logs. There is no randomness, no access to wall-clock time (TIMESTAMP comes from the block header, which is agreed upon by consensus), and no system calls. This determinism is what enables thousands of independent nodes to reach consensus on the state of a single chain.
Q: Why did you implement U256 as a newtype over [u8; 32] instead of using a library?
Answer
Answer
Pedagogical choice. In production (e.g., revm), you'd use a crate like ruint or alloy-primitives::U256 backed by [u64; 4] limbs for performance. But implementing from raw bytes teaches you exactly how big-endian layout works, how carries propagate in addition, and why wrapping is the correct semantics. You also learn the Rust newtype pattern, operator overloading via impl Add, and From/Into conversion idioms — all of which show up in real codebase work.