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

Set up a local Solidity project

Keep source, compiler settings and tests together.

LET’S PICTURE IT

A laboratory notebook records the apparatus as well as the result.

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.

Create an isolated workspace

Use a dedicated project folder for source files and local tests. Keep private keys and production credentials out of a beginner practice project.

Record the toolchain

Pin or record the compiler and dependency versions, optimizer settings and EVM target. A pragma range alone does not reproduce the exact build.

Choose a local execution environment

A test runner can deploy examples to an in-process or local development EVM. A public network and funded wallet are unnecessary for these exercises.

Start with one small contract

Compile the PracticeCounter below, then add a test for its initial count. Expand only after you can explain the deployment account and local state.

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

Do local Solidity unit tests require real ETH?

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.