Solidity for the EVM

Contract structure, storage vs memory, events and the ABI, and the safety patterns behind the SimpleStaking lab contract.

11 min read·5 quiz questions

Anatomy of a contract

A Solidity file declares a license identifier, a pragma pinning the compiler version, then a contract with state variables, a constructor, functions, events and modifiers. Deployment stores the compiled bytecode at an address; the ABI is the JSON description used by wallets and ethers.js to encode calls.

  • public / external / internal / private control who can call.
  • view and pure functions read but never write state — free via eth_call.
  • payable functions may receive ETH with the call.

Storage, memory and calldata

Storage is the contract's permanent, expensive key-value state. Memory is a scratchpad wiped after the call. Calldata is the read-only input buffer. Writing storage costs gas per slot, so minimising writes is the main optimisation in practice.

  • mapping(address => uint256) is the standard per-user balance pattern.
  • Prefer calldata for large read-only function arguments.
  • Cache a storage value in a local variable when reading it repeatedly.

Errors and events

require and custom errors revert the whole transaction and refund unused gas — state changes are all-or-nothing. Events write cheap, indexed logs that front-ends and explorers subscribe to, since contracts cannot push data to users.

Safety patterns in SimpleStaking

The lab contract follows checks-effects-interactions: validate inputs, update balances in storage, and only then transfer value out. That ordering is what defeats reentrancy, where a malicious receiver calls back in before your bookkeeping is finished.

  • Update state before external calls or transfers.
  • Never trust block.timestamp for precise timing or randomness.
  • Fund the reward pool explicitly — a contract cannot mint ETH.

Key terms

ABI
JSON interface describing a contract's callable functions and events.
Storage slot
32-byte persistent state location; writing one costs significant gas.
revert
Abort execution, undo all state changes, refund remaining gas.
Reentrancy
Attack where an external call re-enters the contract mid-execution.
Event
Log entry emitted for off-chain consumers; not readable by contracts.

Chapter quiz

5 questions · pass mark 75%
  1. 1. Which function type can receive ETH along with the call?

  2. 2. Calling a view function through an RPC node costs…

  3. 3. checks-effects-interactions means…

  4. 4. Why does a dApp need the ABI?

  5. 5. A transaction reverts halfway through. What happens to earlier state changes in it?

Answer every question to submit. Progress for solidity-for-the-evm is saved in this browser.