Published on

Understanding the Basic Structure of Smart Contracts on Starknet

Basic Structure of a Simple Smart Contract

This chapter will introduce you to the basics of Starknet contracts using a very simple smart contract as an example. You will learn how to write a contract that allows anyone to store a single number on the Starknet blockchain.

Let’s consider the following contract for the whole chapter. It might not be easy to understand it all at once, but we will go through it step by step:

#[starknet::interface]
trait ISimpleStorage<TContractState> {
  fn set(ref self: TContractState, x: u128);
  fn get(self: @TContractState) -> u128;
}

#[starknet::contract]
mod SimpleStorage {
  use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};

  #[storage]
  struct Storage {
    stored_data: u128
  }

  #[abi(embed_v0)]
  impl SimpleStorage of super::ISimpleStorage<ContractState> {
    fn set(ref self: ContractState, x: u128) {
      self.stored_data.write(x);
    }

    fn get(self: @ContractState) -> u128 {
      self.stored_data.read()
    }
  }
}

What Is this Contract?

Contracts are defined by encapsulating state and logic within a module annotated with the #[starknet::contract] attribute.

The state is defined within the Storage struct and is always initialized empty. Here, our struct contains a single field called stored_data of type u128, indicating that our contract can store any number between 0 and 2^128-1.

The logic is defined by functions that interact with the state. Here, our contract defines and publicly exposes the functions set and get that can be used to modify or retrieve the value of the stored variable.

The Interface: The Contract’s Blueprint

#[starknet::interface]
trait ISimpleStorage<TContractState> {
  fn set(ref self: TContractState, x: u128);
  fn get(self: @TContractState) -> u128;
}

Interfaces represent the blueprint of the contract. They define the functions that the contract exposes to the outside world, without including the function body.

Public Functions Defined in an Implementation Block

In Starknet, a public function is a function that is exposed to the outside world. A public function can be called by anyone, either from outside the contract or from within the contract itself. In the example above, set and get are public functions.

Conclusion

In this article, we explored the basic structure of smart contracts on Starknet.

In the next article, I will guide you on how to write a simple Donation smart contract that forwards STRK tokens to an account while keeping track of it. This contract will serve as one of the simplest examples of handling transfers.