Single Value

Substrate supports all primitive Rust types (bool, u8, u32, etc) as well as some custom types specific to Substrate (Hash, Balance, BlockNumber, etc).

Basic Storage

Within a specific module, a single value (u32 type) is stored in the runtime with this syntax:


# #![allow(unused_variables)]
#fn main() {
decl_storage! {
    trait Store for Module<T: Trait> as Example {
        MyValue: u32;
    }
}
#}

Storage Interaction

To interact with single storage values, it is necessary to import the support::StorageValue type. Functions used to access a StorageValue are defined in srml/support:


# #![allow(unused_variables)]
#fn main() {
/// Get the storage key.
fn key() -> &'static [u8];

/// true if the value is defined in storage.
fn exists<S: Storage>(storage: &S) -> bool {
    storage.exists(Self::key())
}

/// Load the value from the provided storage instance.
fn get<S: Storage>(storage: &S) -> Self::Query;

/// Take a value from storage, removing it afterwards.
fn take<S: Storage>(storage: &S) -> Self::Query;

/// Store a value under this key into the provided storage instance.
fn put<S: Storage>(val: &T, storage: &S) {
    storage.put(Self::key(), val)
}

/// Mutate this value
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: Storage>(f: F, storage: &S) -> R;

/// Clear the storage value.
fn kill<S: Storage>(storage: &S) {
    storage.kill(Self::key())
}
#}

Therefore, the syntax to "put" Value:


# #![allow(unused_variables)]
#fn main() {
<MyValue<T>>::put(1738);
#}

and to "get" Value:


# #![allow(unused_variables)]
#fn main() {
let my_val = <MyValue<T>>::get();
#}

Getter Syntax

Storage values can also be declared with a get function to provide cleaner syntax for getting values.


# #![allow(unused_variables)]
#fn main() {
decl_storage! {
    trait Store for Module<T: Trait> as Example {
        MyValue get(value_getter): u32;
    }
}
#}

The get parameter is optional, but, by including it, the module exposes a getter function (fn value_getter() -> u32).

To "get" the Value with the getter function


# #![allow(unused_variables)]
#fn main() {
let my_val = Self::value_getter();
#}

Setter Syntax

Here is an example of a module that stores a u32 value in runtime storage and provides a function set_value to set the given u32. This code follows convention for naming setters in Rust.


# #![allow(unused_variables)]
#fn main() {
use srml_support::{StorageValue, dispatch::Result};

pub trait Trait: system::Trait {}

decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
        fn set_value(origin, value: u32) -> Result {
            // check sender signature to verify permissions
            let sender = ensure_signed(origin)?; 
            <MyValue<T>>::put(value);
            Ok(())
        }
    }
}

decl_storage! {
    trait Store for Module<T: Trait> as Example {
        MyValue: u32;
    }
}
#}

Substrate Specific Types

To access Substrate specific types, the module's Trait must inherit from the SRML. For example, to access the Substrate types Hash, AccountId, and BlockNumber, it is sufficient to inherit the system module:


# #![allow(unused_variables)]
#fn main() {
pub trait Trait: system::Trait {}
#}

This provides access to the types Hash, AccountId, and BlockNumber anywhere that specifies the generic <T: Trait> using T::<Type>. It also provides access to other useful types, declared in the pub Trait {} block in systems/src/lib.rs.

If access to the Balances type is required, then the trait bound should specify


# #![allow(unused_variables)]
#fn main() {
pub trait Trait: balances::Trait {}
#}

Because the balances module also inherits the system module, it grants access to all the types in system as well as those specified in the pub Trait {} block in balances/src/lib.rs. For a practical example of this syntax, see the Incrementing Balance event recipe.