Skip to main content
Smart contracts store data in their account’s state, which is public on the chain. The storage starts empty until a contract is deployed and the state is initialized. It is important to know that the account’s code and account’s storage are independent. Updating the code does not erase the state.

Defining the State

The attributes of the struct marked as the contract define the data that will be stored.
Store only what the contract needs. Contract state is not a database for your app: storage requires staking NEAR, and data your app only displays can be read from the contract’s transactions with an indexer. Never store values you can derive from other stored values. See A contract is not a backend.
The contract can store all native types (e.g. u8, string, HashMap, Vector) as well as complex objects. For example, our Auction contract stores when the auction ends, and an object representing the highest bid.
The structures that will be saved need a special macro that tells the SDK to store them serialized in Borsh.
The SDK also provides collections to efficiently store collections of data.
lib.rs
Contracts pay for their storage by locking part of their balance.It currently costs ~1Ⓝ to store 100KB of data.

Initializing the State

After the contract is deployed, its state is empty and needs to be initialized with some initial values. There are two ways to initialize a state:
  1. By creating an initialization function
  2. By setting default values

I. Initialization Functions

An option to initialize the state is to create an initialization function, which needs to be called before executing any other function. In our Auction example, the contract has an initialization function that sets when the auction ends. The contract derives the PanicOnDefault, which forces the user to call the init method denoted by the #[init] macro.
It is a good practice to mark initialization functions as private. We will cover function types in the functions section.
lib.rs
lib.rs

II. Default State

Another option to initialize the state is to create a Default version of our contract’s struct. For example, our “Hello World” contract has a default state with a greeting set to "Hello". The first time the contract executes, the Default will be stored in the state, and the state will be considered initialized.
The state can only be initialized once.
lib.rs
lib.rs
Lifecycle of the StateWhen a function is called, the contract’s state is loaded from the storage and put into memory.The state is actually stored serialized, and the SDK takes a bit of time to deserialize it before the method can access it.When the method finishes executing successfully, all the changes to the state are serialized, and saved back to the storage.
State and CodeIn NEAR, the contract’s code and contract’s storage are independent.Updating the code of a contract does not erase the state, and can indeed lead to unexpected behavior or errors.Make sure to read the updating a contract if you run into issues.