2026-07-27
session 1
1. PiggyBank
Setup + first contract: PiggyBank
What we did
- Installed Foundry 1.7.1 (forge, cast, anvil) via Homebrew
- Scaffolded the repo with forge init
- Wrote PiggyBank.sol: anyone deposits ETH, only the owner withdraws
- Wrote 8 Foundry tests in Solidity, all passing, including a fuzz test that hit the contract with 256 random deposit amounts
- Generated a fresh testnet-only wallet with cast wallet new
- Spun up anvil (local chain, unlimited fake ETH) and deployed PiggyBank with forge create
- Ran the full lifecycle from the terminal with cast: a stranger deposited 1 ETH, the stranger's withdrawal attempt reverted with NotOwner, the owner wallet withdrew everything
What I learned
- msg.sender and msg.value: who is calling and how much ETH they attached
- All amounts are in wei (1 ETH = 1e18 wei); there are no decimals on chain
- payable, receive(), and why plain transfers revert without them
- Modifiers as reusable access-control guards (onlyOwner)
- Events are the contract's only output; indexers and dashboards live on them
- Custom errors are cheaper than require strings and show up in traces
- Send ETH with low-level call, not transfer (the 2300 gas stipend problem)
- Fuzz testing: assert a property for all inputs, not one example
- A deployed contract is forever; the rules at deploy time are the rules
Next up
- Fund the testnet wallet from a Base Sepolia faucet
- Deploy PiggyBank to Base Sepolia and verify it on a public explorer
- Start project 2: write an ERC-20 token from scratch