配置创世状态
Please read Substrate to Polkadot SDK page first.
创世配置定义了存储项的初始状态,例如帐户、余额、自定义模块的创世等。 本指南演示如何为具有以下存储项的模块配置创世状态:
SingleValue<T>类型,用于单个StorageValue存储项。AccountMap<T>类型,用于简单的单键StorageMap存储项。
步骤预览
- 在模块中添加存储项。
- 在模块中添加创世配置宏。
- 在链规范中设置初始值。
在模块中添加存储项
- 在文本编辑器中打开模块的
src//lib.rs文件。 -
添加
StorageValue存储项。例如:
#[pallet::storage] #[pallet::getter(fn something)] pub type SingleValue<T: Config> = StorageValue< _, T::Balance >; -
添加
StorageMap存储项,用于具有可枚举条目的映射。例如:
#[pallet::storage] #[pallet::getter(fn accounts)] pub type AccountMap<T: Config> = StorageMap< _, Blake2_128Concat, T::AccountId, T::Balance >;
添加创世配置宏
GenesisConfig 代码应放在存储项之后。
-
添加
#[pallet::genesis_config]属性宏并定义GenesisConfig结构,用于初始化要初始化的存储项。#[pallet::genesis_config] pub struct GenesisConfig<T: Config> { pub single_value: T::Balance, pub account_map: Vec<(T::AccountId, T::Balance)>, } -
设置
GenesisConfig结构的默认值。#[cfg(feature = "std")] impl<T: Config> Default for GenesisConfig<T> { fn default() -> Self { Self { single_value: Default::default(), account_map: Default::default() } } } -
添加
#[pallet::genesis_build]属性宏并实现GenesisBuild特性。#[pallet::genesis_build] impl<T: Config> GenesisBuild<T> for GenesisConfig<T> { fn build(&self) { <SingleValue<T>>::put(&self.single_value); for (a, b) in &self.account_map { <AccountMap<T>>::insert(a, b); } } }#[pallet::genesis_build]宏允许您执行一些逻辑来定义GenesisConfig结构如何将某些内容放入存储中。
设置初始值
在模块中配置存储项和创世配置后,您可以在链的创世状态中指定要为存储项设置的值。
在本例中,假设运行时的 construct_runtime! 宏将 PalletSomething 作为模块名称,将 pallet_something 作为模块的路径。
construct_runtime!(
pub struct Runtime
where
Block = Block,
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
PalletSomething: pallet_something,
}
)- 在文本编辑器中打开
node/chain_spec.rs文件。 - 验证
use node_template_runtime::BalanceConfig;是否在chain_spec.rs文件的顶部导入。 -
创建一个类型为
T::Balance的常量值,该值将存储在<SingleValue<T>>中(在testnet_genesis方法内)。const VALUE: Balance = 235813; -
创建一个帐户向量,用于在
testnet_genesis方法内使用<AccountMap<T>>初始化。let accounts_to_map: Vec<AccountId> = vec![ get_account_id_from_seed::<sr25519::Public>("Alice"), get_account_id_from_seed::<sr25519::Public>("Bob"), get_account_id_from_seed::<sr25519::Public>("Charlie"), ]; -
将模块添加到
testnet_genesis函数的GenesisConfig子句中。惯例是在
runtime/src/lib.rs中的construct_runtime!内使用模块名称的小写拼写。 例如,对于声明为CamelCase的模块,惯例是在testnet_genesis函数中将其称为camel_case。对于此示例模块,代码如下所示:
pallet_something: PalletSomethingConfig { single_value: VALUE, account_map: accounts_to_map.iter().cloned().map(|x| (x, VALUE)).collect(), }此示例代码将
accounts_to_map中的每个帐户映射到等于VALUE的金额。 此模式与 Balances 模块的GenesisConfig非常相似。
