Skip to main content
Version: 3.x

Storing Values

Here is how you store simple values in storage:

#[ink(storage)]
pub struct MyContract {
// Store a bool
my_bool: bool,
// Store some number
my_number: u32,
}
/* --snip-- */

Supported Types

Substrate contracts may store types that are encodable and decodable with Parity Codec which includes most Rust common data types such as bool, u{8,16,32,64,128}, i{8,16,32,64,128}, String, tuples, and arrays.

ink! provides Substrate specific types like AccountId, Balance, and Hash to smart contracts as if they were primitive types.

ink! also provides a Mapping storage type. You can read more about it here.

Here is an example of how you would store an AccountId and Balance:

// We are importing the default ink! types
use ink_lang as ink;

#[ink::contract]
mod MyContract {

// Our struct will use those default ink! types
#[ink(storage)]
pub struct MyContract {
// Store some AccountId
my_account: AccountId,
// Store some Balance
my_balance: Balance,
}
/* --snip-- */
}

Here is an example of a structure storing String and Hash values.

pub struct Auction {
/// Branded name of the auction event.
name: String,
/// Some hash identifying the auction subject.
subject: Hash,
/// Auction status.
status: Status, // Enum: Usage shown in next section
/// Candle auction can have no winner.
/// If auction is finalized, that means that the winner is determined.
finalized: bool,
/// vector
vector: Vec<u8>,
}

Use of enum

Enum can be used as a datatype in struct as depicted above in struct Auction

pub enum Status {
/// An auction has not started yet.
NotStarted,
/// We are in the starting period of the auction, collecting initial bids.
OpeningPeriod,
/// We are in the ending period of the auction, where we are taking snapshots
/// of the winning bids.
}

The values of an enum should be referenced as Status::OpeningPeriod.

Initializing Storage in Constructors

Constructors are how values get initialized. Every ink! smart contract must have a constructor which is run once when a contract is created. ink! smart contracts can have multiple constructors:

Note that if you have a contract whose storage contains Mapping's you will need to use ink_lang::utils::initialize_contract in your constructor. See the Mapping documentation for more details.

use ink_lang as ink;

#[ink::contract]
mod mycontract {

#[ink(storage)]
pub struct MyContract {
number: u32,
}

impl MyContract {
/// Constructor that initializes the `u32` value to the given `init_value`.
#[ink(constructor)]
pub fn new(init_value: u32) -> Self {
Self {
number: init_value,
}
}

/// Constructor that initializes the `u32` value to the `u32` default.
#[ink(constructor)]
pub fn default() -> Self {
Self {
number: Default::default(),
}
}
/* --snip-- */
}
}