substrate - 如何将一个托盘中的存储变量用作另一个托盘中的配置变量?
问题描述
所以你有2个托盘。目标是在pallet_1 中有一个配置变量C:
- 在pallet_2 中有一些不断改变存储变量A 的逻辑;
- 然后运行时应该自动将 var A 的新状态写入到pallet_1 中的常量 C 中。
Pallet_1 特征中的配置变量应该类似于MyConfig: Get<u32>
像这样的东西:https ://github.com/paritytech/substrate/blob/master/frame/recovery/src/lib.rs#L200
所以这表示我们需要定义一个实现该Get<T>
特征的类型:
https://github.com/paritytech/substrate/blob/master/frame/support/src/traits.rs#L471
所以这只是一个函数fn get() -> T
然后假设您有pallet_2,其中有一些您想要控制此配置的存储项目:
decl_storage!{
MyStorage: u32;
}
在您的 runtime/src/lib.rs 中,您定义如下内容:
struct StorageToConfig;
impl Get<u32> for StorageToConfig {
fn get() -> u32 {
return pallet_2::MyStorage::get();
}
}
如何在pallet_1 的特征定义中使用这个结构,并确保运行时自动推送(或pallet_1 从运行时提取)pallet_2 中的MyStorage 变量?
解决方案
这是一个工作示例,说明如何将配置特征的值附加到另一个托盘的存储项目。
托盘 1
这是pallet_1
我们要使用的存储项目。
注意:此存储已标记
pub
,因此可在托盘外访问。
use frame_support::{decl_module, decl_storage};
use frame_system::ensure_signed;
pub trait Trait: frame_system::Trait {}
decl_storage! {
trait Store for Module<T: Trait> as TemplateModule {
pub MyStorage: u32;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
#[weight = 0]
pub fn set_storage(origin, value: u32) {
let _ = ensure_signed(origin)?;
MyStorage::put(value);
}
}
}
托盘 2
这是pallet_2
具有我们要使用来自的存储项填充的配置特征pallet_1
:
use frame_support::{decl_module, dispatch, traits::Get};
use frame_system::ensure_signed;
pub trait Trait: frame_system::Trait {
type MyConfig: Get<u32>;
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
#[weight = 0]
pub fn do_something(origin) -> dispatch::DispatchResult {
let _ = ensure_signed(origin)?;
let _my_config = T::MyConfig::get();
Ok(())
}
}
}
运行时配置
这两个托盘非常简单,可以分开工作。但是如果我们想连接它们,我们需要配置我们的运行时:
use frame_support::traits::Get;
impl pallet_1::Trait for Runtime {}
pub struct StorageToConfig;
impl Get<u32> for StorageToConfig {
fn get() -> u32 {
return pallet_1::MyStorage::get();
}
}
impl pallet_2::Trait for Runtime {
type MyConfig = StorageToConfig;
}
// We also update the `construct_runtime!`, but that is omitted for this example.
在这里,我们定义了一个结构StorageToConfig
,它实现Get<u32>
了pallet_2
. 这个结构告诉运行时什么时候MyConfig::get()
被调用,然后它应该调用pallet_1::MyStorage::get()
读入运行时存储并获取该值。
T::MyConfig::get()
所以现在,对in的每次调用都pallet_2
将是一次存储读取,并将获取 in 中设置的任何值pallet_1
。
让我知道这是否有帮助!
推荐阅读
- c# - 通过字符串转换反序列化枚举时,如何获得空值而不是序列化错误?
- typescript - 按顺序在可观察对象中执行
- python - Pandas 中的 .dropna() 问题
- ruby-on-rails - 在不知道文件名的情况下在 rails 公共目录中派生文件的自动化方法
- c# - 如何在 Web 浏览器控件中单击单独的网页元素
- mysql - 如何为 Spring 和 MySql 设置 Kubernetes
- postgresql - 将 postgres 分区添加到现有表
- ffmpeg - 使用 NVENC 的 FFmpeg GPU 10 位 HEVC 编码
- javascript - 当用户错误地将完整的电子邮件地址包含为用户名时,想要从输入中删除“@email.com”
- azure - 使用用户名和密码写入 Azure Blob