Back to Learn
basic examples

First App - Counter

Build a simple counter contract that stores and modifies state on-chain.

First App - Counter Contract

This tutorial demonstrates building a simple smart contract that manages a counter stored on-chain.

Storage

The #[storage] macro enables persistent data storage. Your struct fields must implement the StorageType trait.

``rust

#[storage]

pub struct Counter {

number: StorageU256,

}

`

Entry Point

The #[entrypoint] macro marks where Stylus execution begins.

Public Methods

Use #[public] to expose methods to external callers:

- get() - Returns current count

- set_count(count) - Sets count to a specific value

- inc() - Increments by one

- dec()` - Decrements by one

Code Example

#![cfg_attr(not(feature = "export-abi"), no_main)]
extern crate alloc;

use stylus_sdk::{alloy_primitives::U256, prelude::*};

#[storage]
#[entrypoint]
pub struct Counter {
    number: StorageU256,
}

#[public]
impl Counter {
    pub fn get(&self) -> U256 {
        self.number.get()
    }

    pub fn set_count(&mut self, count: U256) {
        self.number.set(count);
    }

    pub fn inc(&mut self) {
        let count = self.number.get();
        self.set_count(count + U256::from(1));
    }

    pub fn dec(&mut self) {
        let count = self.number.get();
        if count > U256::ZERO {
            self.set_count(count - U256::from(1));
        }
    }
}

Practice Challenge

Key Points

  • #[storage] macro for persistent state
  • #[entrypoint] marks contract entry
  • #[public] exposes methods externally
  • StorageU256 for numeric storage
  • Use .get() and .set() for storage access