Какова цель `pub` в decl_storage? - PullRequest
1 голос
/ 14 июня 2019

При реализации модуля времени выполнения в подложке предоставляется следующее хранилище

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
  }
}

Какова цель pub перед AllKittiesCount? Потому что, есть ли pub или нет, пользовательский интерфейс polkadot может по-прежнему запрашивать его, как если бы он был публичной переменной.

Ответы [ 2 ]

3 голосов
/ 15 июня 2019

decl_storage!генерировать структуру для каждого хранилища, эта структура реализует указанную черту хранилища.

$vis определяет видимость этой структуры.

примечание: что метод получения get($getter) является открытой функцией, реализованной в$vis.

Примечание: в конце все модули записывают в уникальное временное хранилище, таким образом, значения все равно доступны, если запрашивать правильный ключ.

РЕДАКТИРОВАТЬ: Я мог бы добавить, что интерес иметь структуру публичного хранилища в том, что тогда другой модуль может писать в него напрямую, используя черту Storage{Value, Map, ..}.

2 голосов
/ 21 июня 2019

Чтобы немного расширить здесь, как и для любого типа 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, вы просто вводите тег pub в struct Something. Это означает, что теперь вы можете вызывать все эти функции, предоставляемые структурой, например get, take, mutate из других модулей. В противном случае вам потребуется создать свои собственные общедоступные функции, которые предоставляют API для изменения хранилища.

...