What is the purpose of `pub` in decl_storage?
Asked Answered
S

2

2

When implementing a runtime module in substrate, given the following storage

decl_storage! {
  trait Store for Module<T: Trait> as CatAuction {
    Kitties get(kitties): map T::Hash => Kitty<T::Hash, T::Balance>;
    KittyOwner get(owner_of): map T::Hash => Option<T::AccountId>;
    OwnedKitties get(kitties_owned): map T::AccountId => T::Hash;

    pub AllKittiesCount get(all_kitties_cnt): u64;
    Nonce: u64;

    // if you want to initialize value in storage, use genesis block
  }
}

What is the purpose of pub in front of AllKittiesCount? Because whether there is pub or not, polkadot UI can still query it, as if it is a public variable.

Sonni answered 14/6, 2019 at 13:33 Comment(3)
Do we tell you to use pub somewhere in our tutorials? Or is this just a side question?Immovable
@ShawnTabrizi Going through the decl_storage! doc, saying Basic storage can be extended as such: #vis #name get(#getter) config(#field_name) build(#closure): #type = #default; #vis: Set the visibility of the structure. pub or nothing ...Sonni
This is related to: #56902667Immovable
I
5

To expand here a bit, just like any Rust type, you need to be explicit about the visibility of different types. The decl_storage macro generates a struct for each of your storage items. For example:

decl_storage! {
    trait Store for Module<T: Trait> as TemplateModule {
        Something get(something): u32;
    }
}

Would result in (some stuff removed for clarity):

struct Something<T: Trait>(...);

impl <T: Trait> ... for Something<T> {
    fn get<S: ... >(storage: &S) -> Self::Query {
        storage.get(...).unwrap_or_else(|| Default::default())
    }
    fn take<S: ...>(storage: &S) -> Self::Query {
        storage.take(...).unwrap_or_else(|| Default::default())
    }
    fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: ...>(f: F, storage: &S) -> R {
        let mut val = <Self as ...>::get(storage);
        let ret = f(&mut val);
        <Self as ...>::put(&val, storage);
        ret
    }
}

If you make the storage item pub you simply introduce a pub tag to the struct Something. This means, you can now call all these functions exposed by the struct like get, take, mutate from other modules. Otherwise, you would need to create your own public functions which exposes an API to modify the storage.

Immovable answered 21/6, 2019 at 9:17 Comment(0)
D
3

decl_storage! generate a structure for each storage this structure implements the storage trait specified.

$vis specify the visibility of this struct.

note: that the getter get($getter) is a public function implemented on module, it is not affected by this $vis.

note: At the end all modules write to the unique trie storage, thus values are still accessible somehow by requesting the right key.

EDIT: I could add that the interest of having the structure of a storage public is that then other module can write to it directly by using the Storage{Value, Map, ..} trait.

Dispart answered 15/6, 2019 at 8:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.