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?