如何使用 PalletS 从 Pallet 中保存记录,而 Pallet 对基材和锈蚀保存的内部结构一无所知
How to use PalletB to save record from PalletA without PalletA knowing anything about internals of the saving in substrate and rust
我想通过简单地传递原始数据并等待 return.
将 PalletA 中的记录保存到 PalletB 中
我试过以下方法:
// ./PalletB/lib.rs
pub trait PutInStorage {
fn put_rule_in_storage(value: u32);
}
impl<T: Trait> PutInStorage for Module<T> {
fn put_rule_in_storage(value: u32) {
SimpleCounter::put(value);
}
}
然后在
// ./PalletA/lib.rs
use palletB::{PutInStorage, Trait as PalletBTrait};
///The pallet's configuration trait.
pub trait Trait: system::Trait + PalletBTrait {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
type ExternalStorage: PutInStorage;
}
然后我像这样将定义添加到运行时:
// ./runtime/lib.rs
// near the construct_runtime macro
impl palletA::Trait for Runtime {
type Event = Event;
type ExternalStorage = palletB::Module<Runtime>;
}
到目前为止,这通过了检查,但没有通过测试。 trait 的测试配置是这样的:
use palletB::{PutInStorage, Trait as PalletBTrait};
impl Trait for Test {
type Event = ();
type ExternalStorage = PutInStorage;
}
这失败了:
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^ help: use `dyn`: `dyn PutInStorage`
impl Trait for Test
------------------- in this `impl` item
type Event = ();
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `pallet_rules::PutInStorage` cannot be made into an object
我尝试了 Rust 编译器给我的所有建议,但没有任何运气。在有人问为什么我的测试中需要这个之前,这是因为 decl_module!
中的可调度 fn 检查在开始处理和保存自己的记录之前是否存在某个记录。它依赖于记录存在。
为了让编译器满意,您的测试配置还必须有一个 PalletB 实例,或任何其他实现 PutInStorage
.
的实例
与您在 ./runtime/lib.rs
中所做的类似:
impl Trait for Test {
type Event = ();
type ExternalStorage = palletB::Module<Test>;
}
请注意,现在struct Test
是扮演Runtime
的角色。我认为这是您唯一缺少的东西。
话虽如此,你似乎在整体设计上走错了路。
PalletA
已经依赖于 PalletB
。鉴于您还具有 link 这两个 PutInStorage
的特征,这不是一个好的设计。通常,您应该尝试并始终选择以下选项之一:
- 两个托盘将相互依赖。在这种情况下,您不需要特征。如果一个需要将某些东西放入另一个的存储中,您只需直接即可。在您的示例中,我假设
PalletB
在 decl_storage
中有一个名为 pub Foo: u32
的存储项,并且 PutInStorage
写入该项。如果是这种情况,则不需要特征。从 PalletA
你可以说:palletB::Foo::put(value)
.
请注意,应谨慎选择这种方法,否则最终可能会出现大量托盘相互依赖的情况,这并不好。
- 你决定你的 pallet 不相互依赖,在这种情况下你使用了一些特性,比如
PutInStorage
。您的代码似乎与这种方法保持一致,除了您将 PalletA 的特征定义为 pub trait Trait: system::Trait
。这里不用依赖PalletB,当然你也可以从Cargo.toml
里抹掉
我想通过简单地传递原始数据并等待 return.
将 PalletA 中的记录保存到 PalletB 中我试过以下方法:
// ./PalletB/lib.rs
pub trait PutInStorage {
fn put_rule_in_storage(value: u32);
}
impl<T: Trait> PutInStorage for Module<T> {
fn put_rule_in_storage(value: u32) {
SimpleCounter::put(value);
}
}
然后在
// ./PalletA/lib.rs
use palletB::{PutInStorage, Trait as PalletBTrait};
///The pallet's configuration trait.
pub trait Trait: system::Trait + PalletBTrait {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
type ExternalStorage: PutInStorage;
}
然后我像这样将定义添加到运行时:
// ./runtime/lib.rs
// near the construct_runtime macro
impl palletA::Trait for Runtime {
type Event = Event;
type ExternalStorage = palletB::Module<Runtime>;
}
到目前为止,这通过了检查,但没有通过测试。 trait 的测试配置是这样的:
use palletB::{PutInStorage, Trait as PalletBTrait};
impl Trait for Test {
type Event = ();
type ExternalStorage = PutInStorage;
}
这失败了:
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^ help: use `dyn`: `dyn PutInStorage`
impl Trait for Test
------------------- in this `impl` item
type Event = ();
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
type ExternalRulesStorage = PutInStorage;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `pallet_rules::PutInStorage` cannot be made into an object
我尝试了 Rust 编译器给我的所有建议,但没有任何运气。在有人问为什么我的测试中需要这个之前,这是因为 decl_module!
中的可调度 fn 检查在开始处理和保存自己的记录之前是否存在某个记录。它依赖于记录存在。
为了让编译器满意,您的测试配置还必须有一个 PalletB 实例,或任何其他实现 PutInStorage
.
与您在 ./runtime/lib.rs
中所做的类似:
impl Trait for Test {
type Event = ();
type ExternalStorage = palletB::Module<Test>;
}
请注意,现在struct Test
是扮演Runtime
的角色。我认为这是您唯一缺少的东西。
话虽如此,你似乎在整体设计上走错了路。
PalletA
已经依赖于 PalletB
。鉴于您还具有 link 这两个 PutInStorage
的特征,这不是一个好的设计。通常,您应该尝试并始终选择以下选项之一:
- 两个托盘将相互依赖。在这种情况下,您不需要特征。如果一个需要将某些东西放入另一个的存储中,您只需直接即可。在您的示例中,我假设
PalletB
在decl_storage
中有一个名为pub Foo: u32
的存储项,并且PutInStorage
写入该项。如果是这种情况,则不需要特征。从PalletA
你可以说:palletB::Foo::put(value)
.
请注意,应谨慎选择这种方法,否则最终可能会出现大量托盘相互依赖的情况,这并不好。
- 你决定你的 pallet 不相互依赖,在这种情况下你使用了一些特性,比如
PutInStorage
。您的代码似乎与这种方法保持一致,除了您将 PalletA 的特征定义为pub trait Trait: system::Trait
。这里不用依赖PalletB,当然你也可以从Cargo.toml
里抹掉