Chapter 9 — Programming II
Lesson map
Lesson 09 published. Map, example, EX025.
flowchart TD
N0["Learning outcomes"]
N1["9.1 Structure"]
N2["9.2 Explicit errors"]
N3["9.3 Property tests"]
N4["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Worked example"]
EX --> Q["Exercise EX025"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["9.1 Structure"]
N2["9.2 Explicit errors"]
N3["9.3 Property tests"]
N4["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX025"]
[Learning outcomes]
|
v
[9.1 Structure]
|
v
[9.2 Explicit errors]
|
v
[9.3 Property tests]
|
v
[Synthesis]
|
v
[Worked example] --> [Exercise EX025]
Learning outcomes
You will (1) structure larger programs; (2) handle errors explicitly; (3) test properties as well as examples.
9.1 Structure
As programs grow, Jonas organises code into modules: one for ledger state, one for validation rules, one for reporting. Each module has a small public interface and hides its internal details. He writes docstrings explaining each function's purpose and assumptions. Structure matters for security because reviewers must understand code to judge it; a tangled program hides mistakes, while a clear structure lets a reviewer check each rule in one place, as the EthTrust specification's emphasis on documented contract logic suggests.
9.2 Explicit errors
Jonas learns to handle errors explicitly rather than ignoring them. When a transfer is invalid, his function raises a clear exception instead of silently doing nothing, and callers must decide what to do. This mirrors a contract weakness listed in the SWC registry: unchecked return values from low-level calls, where a failed call is treated as success. In both Python and contracts, the defensive rule is the same: a failure must be visible to the code that depends on the result, otherwise state and reality drift apart.
9.3 Property tests
Example tests check specific cases; property tests check rules that should hold for many inputs. Jonas writes a simple generator of random valid transfer sequences using a fixed seed and checks that total balances always equal supply and no balance goes negative. The property test finds a bug that no example caught: a transfer to oneself doubled the balance due to an update order mistake. Property testing is the beginning of invariant thinking, which later chapters use to verify contracts.
Worked example
A seeded property test finds a self-transfer bug that doubled balances, which example tests had missed.
Synthetic case. Code, tests and bugs are synthetic; EEA EthTrust and the SWC registry are real sources.
Errors and limits
Silently ignoring failed operations lets recorded state drift from reality.
Exercises
- EX025 — Module split. How does Jonas organise modules? Rubric: 3 = state, validation, reporting;; 2 = three modules;; 1 = one file;; 0 = none.
- EX026 — SWC parallel. Which SWC weakness parallels silent errors? Rubric: 3 = unchecked return values from low-level calls;; 2 = unchecked return;; 1 = overflow;; 0 = none.
- EX027 — Property bug. What did the property test find? Rubric: 3 = self-transfer doubled the balance;; 2 = self-transfer;; 1 = vague;; 0 = none.
Synthesis
Clear structure, explicit errors and property tests make larger programs reviewable and reliable.
Continue studying — chapter 09 of 50
← Chapter 08 (draft) · Course chapter index · Chapter 10 (draft) →