Skip to main content

Incrementing the Value

It's time to let our users modify storage!

Mutable and Immutable Functions

You may have noticed that the function templates included self as the first parameter of the contract functions. It is through self that you gain access to all your contract functions and storage items.

If you are simply reading from the contract storage, you only need to pass &self. But if you want to modify storage items, you will need to explicitly mark it as mutable, &mut self.

impl MyContract {
#[ink(message)]
pub fn my_getter(&self) -> u32 {
self.my_number
}

#[ink(message)]
pub fn my_setter(&mut self, new_value: u32) {
self.my_number = new_value;
}
}

Lazy Storage Values

There is a Lazy type that can be used for ink! storage values that don't need to be loaded in some or most cases. Because they do not meet this criteria, many simple ink! examples, including those in this workshop, do not require the use Lazy values. Since there is some overhead associated with Lazy values, they should only be used where required.

#[ink(storage)]
pub struct MyContract {
// Store some number
my_number: ink_storage::Lazy<u32>,
}

impl MyContract {
#[ink(constructor)]
pub fn new(init_value: i32) -> Self {
Self {
my_number: Default::default(),
}
}

#[ink(message)]
pub fn my_setter(&mut self, new_value: u32) {
ink_storage::Lazy::<u32>::set(&mut self.my_number, new_value);
}

#[ink(message)]
pub fn my_adder(&mut self, add_value: u32) {
let my_number = &mut self.my_number;
let cur = ink_storage::Lazy::<u32>::get(my_number);
ink_storage::Lazy::<u32>::set(my_number, cur + add_value);
}
}

Your Turn

Follow the ACTIONs in the template code.

Remember to run cargo +nightly test to test your work.

#![cfg_attr(not(feature = "std"), no_std)]

use ink_lang as ink;

#[ink::contract]
mod incrementer {

#[ink(storage)]
pub struct Incrementer {
value: i32,
}

impl Incrementer {
#[ink(constructor)]
pub fn new(init_value: i32) -> Self {
Self {
value: init_value,
}
}

#[ink(constructor)]
pub fn default() -> Self {
Self {
value: 0,
}
}

#[ink(message)]
pub fn get(&self) -> i32 {
self.value
}

#[ink(message)]
pub fn inc(&mut self, by: i32) {
// ACTION: Simply increment `value` by `by`
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn default_works() {