decl_storage 中 `pub` 的用途是什么?
What is the purpose of `pub` in decl_storage?
在substrate中实现runtime模块时,给定以下存储
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
}
}
AllKittiesCount
前面的pub
是什么意思?因为不管有没有pub
,polkadotUI还是可以查询到的,就好像是一个public变量一样
decl_storage!为每个存储生成一个结构此结构实现指定的存储特征。
$vis
指定此结构的可见性。
注意:getter get($getter)
是在模块上实现的 public 函数,不受此 $vis
.
的影响
注意:最后所有模块都写入唯一的 trie 存储,因此仍然可以通过请求正确的密钥以某种方式访问值。
编辑:我可以补充一点,拥有存储结构 public 的好处是其他模块可以使用 Storage{Value, Map, ..}
特征直接写入它。
在这里稍微扩展一下,就像任何 Rust 类型一样,您需要明确不同类型的可见性。 decl_storage
宏为您的每个存储项目生成一个 struct
。例如:
decl_storage! {
trait Store for Module<T: Trait> as TemplateModule {
Something get(something): u32;
}
}
会导致(为清楚起见删除了一些内容):
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
}
}
如果您制作存储项目 pub
,您只需在 struct Something
中引入一个 pub
标签。这意味着,您现在可以从其他模块调用结构公开的所有这些函数,如 get
、take
、mutate
。否则,您将需要创建自己的 public 函数,该函数公开 API 来修改存储。
在substrate中实现runtime模块时,给定以下存储
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
}
}
AllKittiesCount
前面的pub
是什么意思?因为不管有没有pub
,polkadotUI还是可以查询到的,就好像是一个public变量一样
decl_storage!为每个存储生成一个结构此结构实现指定的存储特征。
$vis
指定此结构的可见性。
注意:getter get($getter)
是在模块上实现的 public 函数,不受此 $vis
.
注意:最后所有模块都写入唯一的 trie 存储,因此仍然可以通过请求正确的密钥以某种方式访问值。
编辑:我可以补充一点,拥有存储结构 public 的好处是其他模块可以使用 Storage{Value, Map, ..}
特征直接写入它。
在这里稍微扩展一下,就像任何 Rust 类型一样,您需要明确不同类型的可见性。 decl_storage
宏为您的每个存储项目生成一个 struct
。例如:
decl_storage! {
trait Store for Module<T: Trait> as TemplateModule {
Something get(something): u32;
}
}
会导致(为清楚起见删除了一些内容):
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
}
}
如果您制作存储项目 pub
,您只需在 struct Something
中引入一个 pub
标签。这意味着,您现在可以从其他模块调用结构公开的所有这些函数,如 get
、take
、mutate
。否则,您将需要创建自己的 public 函数,该函数公开 API 来修改存储。