🎓 A1Learner
🔍
0 of 50 lessons completed

Solidity Project: Counter

The Counter project is a complete contract that counts up and down, never below zero, and reports every change. It brings state, functions, a require guard, and events together in one small program.

Increment, decrement, and a guard at zero

The increment function adds 1, and the decrement function takes 1 away. A require check blocks decrement when the count is already 0.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract BasicCounter {
    uint256 public count;

    function increment() public {
        count = count + 1;
    }

    function decrement() public {
        require(count > 0, "Count cannot go below zero");
        count = count - 1;
    }
}

An event fires on every change

The CountChanged event carries the new count each time it changes. Both increment and decrement emit it after updating the count.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract LoudCounter {
    uint256 public count;

    event CountChanged(uint256 newCount);

    function increment() public {
        count = count + 1;
        emit CountChanged(count);
    }

    function decrement() public {
        require(count > 0, "Count cannot go below zero");
        count = count - 1;
        emit CountChanged(count);
    }
}

Reset sets the count back to zero

The reset function sets the count to 0 in one step. It works from any count, including 0 itself.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract ResettableCounter {
    uint256 public count;

    function increment() public {
        count = count + 1;
    }

    function reset() public {
        count = 0;
    }
}

Example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract Counter {
    uint256 public count;

    event CountChanged(uint256 newCount);

    function increment() public {
        count = count + 1;
        emit CountChanged(count);
    }

    function decrement() public {
        require(count > 0, "Count cannot go below zero");
        count = count - 1;
        emit CountChanged(count);
    }

    function getCount() public view returns (uint256) {
        return count;
    }

    function reset() public {
        count = 0;
        emit CountChanged(count);
    }
}

Key points

  • Count: one state variable holds the current count, starting at 0.
  • Increment and decrement: one function adds 1 to the count, and one function takes 1 away.
  • Require guard: a require check stops decrement at zero, so the count never goes below zero.
  • Event: a stored record a contract fires during a call, which outside tools can read later.
  • Every change fires the event: increment, decrement, and reset each emit the new count.
  • Reset: one function sets the count straight back to 0.

In this example, the count starts at 0 in a public state variable. The increment function adds 1 and emits CountChanged with the new count. The decrement function first checks with require that the count is above 0, then takes 1 away and emits the event. The getCount function reads the count, and reset sets the count back to 0 and emits the event for that change too.

Note

the public count variable also gives a free reading function with the same name.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Remix IDE

Exercise

The count is 0. What happens when decrement is called on the Counter project contract?