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>::put(1738);
#}

and to "get" Value:


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

Note that we do not need the type T because the value is only of one type u32. If the T was polymorphic over more than one type, the syntax would include T in call like


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

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>::put(value);
            Ok(())
        }
    }
}

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