问题
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/56599293/what-is-the-purpose-of-pub-in-decl-storage