LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 新闻观点 > 【Substrate开发教程】13 - 模块(Pallets)

【Substrate开发教程】13 - 模块(Pallets)

2020-10-27 松果 来源:区块链网络


之前的文章多次出现了pallet这个术语,它是Substrate生态中的模块,每一个pallet都定义了特定领域所需的业务逻辑和存储单元,封装了各种打包好的功能,这篇文章来深入学习它。

模块(Pallets)

pallet直译为“货盘”,即装载货物的盘子


在Substrate中指的是一种特殊的Rust语言编写的程序模块,可以用来组成Substrate runtime。

Rust生态中很多术语都和“货物”有关,例如包管理器cargo的含义就是“货物”;程序包crate的含义是“箱子”,是用来装货物的;Substrate把模块叫做“货盘”,也延续了Rust的命名风格。

每个pallet都有自己独立的逻辑,这些逻辑可以修改区块链的状态转换函数(STF)和功能和特性。

例如balances模块用于处理账户和余额,定义了一种加密货币,用户可以转移和管理这些token。

开发者可以编写自己的pallet来定义要引入区块链的逻辑和功能。

Pallet的组成

一个pallet由以下6部分组成:

1、导入和依赖项

pallet支持使用任何带有no_std标识进行编译的Rust库。示例代码如下:

use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch, traits::Get}; use frame_system::ensure_signed;

2、运行时配置

运行时配置是一个trait,所有的运行时类型和常量都放在这里,如果pallet依赖于特定的其他pallet,则应将其配置traits添加到继承的traits列表中。示例代码如下:

pub trait Trait: frame_system::Trait { type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>; }

3、运行时存储

安全地使用Substrate存储数据库。示例代码如下:

decl_storage! { trait Store for Module<T: Trait> as TemplateModule { Something get(fn something): Option<u32>; } }

4、运行时事件

事件(Event)是一种通知机制,是报告给用户、DAPP、区块链浏览器特定情况的一种简单方法。示例代码如下:

decl_event!( pub enum Event<T> where AccountId = <T as frame_system::Trait>::AccountId { SomethingStored(u32, AccountId), } );

5、运行时逻辑

定义该pallet最终导出的模块结构,包括该pallet公开的可调用函数,协调该pallet在整个区块执行过程中采取的动作。示例代码如下:

decl_module! { pub struct Module<T: Trait> for enum Call where origin: T::Origin { type Error = Error<T>; fn deposit_event() = default; #[weight = 10_000 + T::DbWeight::get().writes(1)] pub fn do_something(origin, something: u32) -> dispatch::DispatchResult { let who = ensure_signed(origin)?; Something::put(something); Self::deposit_event(RawEvent::SomethingStored(something, who)); Ok(()) } #[weight = 10_000 + T::DbWeight::get().reads_writes(1,1)] pub fn cause_error(origin) -> dispatch::DispatchResult { let _who = ensure_signed(origin)?; match Something::get() { None => Err(Error::<T>::NoneValue)?, Some(old) => { let new = old.checked_add(1).ok_or(Error::<T>::StorageOverflow)?; Something::put(new); Ok(()) }, } } } }

6、错误处理机制

示例代码如下:

decl_error! { pub enum Error for Module<T: Trait> { NoneValue, StorageOverflow, } }

substrate-node-template项目结构

以上示例代码来自之前写的文章:《创建第一条Substrate区块链》中的substrate-node-template项目。

substrate-node-template是一个区块链节点模板,它的源码结构如下


主要目录有以下几个:

node:区块链节点基础服务代码,运行的入口在node/src/main.rs中;runtime:区块链运行时逻辑的代码,一个node包含一个runtime;pallets/template:自定义的业务逻辑代码,一个runtime可以包含多个pallet;target:编译后的应用程序和中间文件;

以上示例代码在pallets/template/src/libs.rs中实现


Substrate允许一个runtime包含多个pallet,即pallets目录下可以有多个自定义的pallet,substrate-node-template项目就自定义了一个名为template的pallet。

做substrate区块链定制主要也是修改pallets/template/src/libs.rs的代码,主要定制以下几部分内容:

decl_storage! 定义数据存储decl_module! 定义模块运行逻辑decl_event! 定义模块事件处理decl_error! 定义错误处理

这些带有感叹号的结构是Substrate runtime宏,template模块对这些宏进行了简单实现,可以完成数据存取工作。

—-

编译者/作者:松果

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...