In this track: Build, test and reason
advanced · 4 MIN READ

A local-only testing capstone

Build evidence for one small contract without using a public network.

LET’S PICTURE IT

A complete rehearsal checks setup, normal actions and deliberate failures.

SEE IT FOR YOURSELF
A valid counter call, step by stepStep 1 / 4
A valid counter call, step by stepFunction requestincrement()No argumentsBefore executionstored count0A local teaching example with a defined starting stateIncoming callCheck function dispatchCheck coded conditionsRules passConditions passContinue executionA failed check can revert insteadCalculation0 + 1Result: 1Storage writecount = 1Persists if call succeedsCalculating a local value and storing it are separate stepsPersistent statecount1Later readGetter reports 1No new incrementState, logs and browser display have different roles

This example begins with count zero and a request to call increment(). No real contract is deployed.

Animated local teaching model. No wallet, RPC or live blockchain data. Some labels and hashes are abbreviated for readability.

Choose the PracticeCounter scope

Use the full contract from the first lesson in this track. Record compiler settings and deploy it to a fresh local execution environment.

Cover the state transition

Assert initial zero, owner increments and repeated increments. Check the count after each action rather than only observing that calls do not throw.

Cover authorization and records

Reject an unrelated caller, inspect NotOwner and confirm unchanged count. Check the successful Increased emitter and fields, plus absence of retained logs after rejection.

Write the evidence report

List what compiled, what executed and what the tests asserted. Keep the contract’s toy scope clear and do not describe the exercise as an audit of production code.

Define the test

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract PracticeCounter {
    error NotOwner(address caller);
    event Increased(address indexed caller, uint256 value);
    address public immutable owner;
    uint256 public count;
    constructor() { owner = msg.sender; }
    function increment() external {
        if (msg.sender != owner) revert NotOwner(msg.sender);
        count += 1;
        emit Increased(msg.sender, count);
    }
}

Test plans are framework-neutral unless labeled as complete Solidity or JavaScript. Use a local test environment and no real funds.

QUICK CHECK · NO PRESSURE

What should the final report distinguish?

Your progress stays in this browser.
Keep exploring the original referenceethereum.org ↗

Original explanations by EtherTools. Examples are educational and source-linked; this site is independent of the Ethereum Foundation. Our approach.