Построение среды выполнения: строка не найдена в этой области

Dec 18 2020

Распространенная проблема, с которой могут столкнуться разработчики подложек: разработка пользовательского поддона для хранения сопоставления в хранилище с распространенными типами, например String. Например:

#[derive(Encode, Decode, Clone, Default, RuntimeDebug)]
pub struct ClusterMetadata {
    ip_address: String,
    namespace: String,
    whitelisted_ips: String,
}

При создании среды выполнения вы получаете эту ошибку для каждого String:

     |
  21 |     ip_address: String,
     |                 ^^^^^^ not found in this scope

Почему Stringsне включены в объем? А другие stdвиды ржавчины?

Ответы

4 ShawnTabrizi Dec 18 2020 at 07:35

Ошибка здесь не связана no_std, поэтому вам, вероятно, просто нужно импортировать Stringтип, чтобы получить реальные ошибки с использованием строк во время выполнения.

Настоящая проблема, которую вы обнаружите, заключается в том, что Stringкодек Parity SCALE не кодируется, что, очевидно, является требованием для любого элемента хранения (или почти любого типа, который вы хотите использовать) во время выполнения.

Итак, вопрос: «Почему SCALE не кодирует String»?

Это по выбору. В общем, Stringэто удивительно сложный тип. В книге Rust целый раздел посвящен сложностям шрифтов.

Таким образом, он легко может стать подножкой в ​​среде выполнения, которую люди используют Stringнеправильно.

Более того, как правило, хранить Stringв хранилище времени выполнения - плохая практика . Я думаю, мы можем легко согласиться с тем, что минимизация использования хранилища во время выполнения является наилучшей практикой, и поэтому вы должны помещать в хранилище только те элементы, которые вам нужны, чтобы иметь возможность получать консенсус и переходы между состояниями во время выполнения. Чаще всего Stringданные используются для метаданных, и такое использование не является оптимальной практикой.

Если вы внимательно посмотрите на Substrate, вы обнаружите, что мы нарушаем эту передовую практику более одного раза, но это решение мы принимаем явно, имея под рукой информацию, позволяющую правильно оценить затраты / выгоду.

Все это вместе является причиной того, почему Stringво время выполнения не рассматриваются как объект первого класса. Вместо этого мы просим пользователей кодировать строки в байты, а затем вместо этого работать с этим массивом байтов.