摘要
IPSE是一个基于IPFS的搜索引擎,目前在基于Substrate进行跨链生态开发。通过Substrate的模块设计获得高扩展特性。
模块(Module
)结构是每个Substrate Runtime模块的骨干。它包装了一组有用的功能和实现。
模块结构的组件
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
// --snip--
}
}
Module
如何在decl_module!macro
中声明原始结构:
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
// --snip--
}
}
Module
结构在Rust标准中的最终生成定义如下:
pub struct Module<T: Trait>();
在此结构之上,Substrate为模块实现提供了丰富的功能和特性,例如:
- 可调用函数
- Runtime存储
- OnInitialize / OnFinalize
- OffchainWorker
- 等等...
模块结构实现
运行时开发人员编写可调用函数,以维护操纵区块链状态的逻辑。这是一个示例,显示了一个名为的可调用函数do_something
:
impl<T: Trait> Module<T> {
pub fn do_something(origin: T::Origin, something: u32) -> Result {
// --snip--
}
}
可调用函数
为了确保可以通过外部调用这些函数,该模块Module
结构还执行Callable
连接到模块的Call
枚举来实现该特性。所有可调度的功能都将通过此Call
枚举公开。
Runtime存储
该Store
特性列出了所有由模块公开运行时存储项目。每个存储项都有一个结构,在其上定义了所有存储API。
impl<T: Trait> Store for Module<T> {
type Something = Something<T>;
}
OnInitialize / OnFinalize
Module
结构实现OnInitialize
和OnFinalize
属性,它们包含应在块执行开始或结束时运行的功能。
模块内部功能
Module
结构还用于实现我们定义的所有各种模块内部功能。
impl<T: Trait> Module<T> {
// --snip--
}
然后,我们可以使用Self::function_name()
来访问整个模块中的这些功能。
例如,默认定义deposit_event
扩展为:
impl<T: Trait> Module<T> {
fn deposit_event(event: Event<T>) {
<system::Module<T>>::deposit_event(<T as Trait>::from(event).into());
}
}
可以通过以下方式访问:
Self::deposit_event(...)
所有模块元组
最后,使用construct_runtime!
宏将Module
结构导入到整个区块链的Runtime中。宏将你的模块以及所有其他模块都包含到一个名为AllModules
的元组中:
type AllModules = (
timestamp::Module<Runtime>,
balances::Module<Runtime>,
template::Module<Runtime>,
// --snip--
);
该元组由Runtime的Executive模块使用,该模块负责处理执行这些模块流程。
模块元数据
就像该Module
结构一样,模块的元数据包含模块的所有各个组件,例如其存储项,可调用函数和事件。当以JSON表示时,模块的元数据将如下所示:
{
"modules":[
{
"name":"template",
"prefix":"TemplateModule",
"storage":[...],
"calls":[...],
"events":[...]
}
]
}
链接: