substrate进阶(2)-pallet结构概述

本文主要综合介绍pallet的组成,初步了解pallet的全局情况

pallet模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// 库头
#![cfg_attr(not(feature = "std"), no_std)]

// 导出该pallet
pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
//使用到的依赖
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

// 声明一个pallet类型,类似一个占位符,用于方便实现接口和方法
// 其中的泛形T指的是Runtime,在runtime.rs中会调用引入
#[pallet::pallet]
#[pallet::generate_store(pub (super) trait Store)]
pub struct Pallet<T>(_);

// 声明配置
// 一些全局常用的类型和常量均在此处配置,
// 该config trait必须需要实现frame_system::Config,另外也根据业务需要实现别的config trait
#[pallet::config]
pub trait Config: frame_system::Config {
/// 例如定义如下两个数据类型:
// 案例1:需要实现相关所有trait
type Id: Member
+ Parameter
+ AtLeast32BitUnsigned
+ Codec
+ Copy
+ Debug
+ Default
+ MaybeSerializeDeserialize;

//案例2:此处带有宏定义的类型以及常量,会在runtime中(就是代码runtime/src/lib.rs中)使用时,会指定具体的类型。
#[pallet::constant]
type Limit: Get<u32>;
}

// 声明存储
// 存储(Storage)允许我们在链上存储数据,使用它存储的数据可以通过Runtime进行访问。substrate提供了四种存储方式,分别是:
// Storage Value、Storage Map、Storage Double Map、Storage N Map
// 说明:StorageValue是存储单个的值,StorageMap是以map的方式存储(key-value),StorageDoubleMap则是以双键的方式存储(就是两个key对应value的方式),StorageNMap则是N个key的方式。
#[pallet::storage]
#[pallet::getter(fn something)]
pub type MyStorage<T: Config> = StorageValue<_, u32>;

// 声明事件
// 当pallet需要把运行时上的更改或变化通知给外部主体时,就需要用到事件。事件是一个枚举类型
// 在区块链写交易函数的时候,一般分为三步,分别是判断条件、修改状态、发出事件。
#[pallet::event]
#[pallet::generate_deposit(pub (super) fn deposit_event)]
pub enum Event<T: Config> {
// 例如:
ValueSet(u32, T::AccountId),
}

// 声明钩子函数
// 钩子函数,是在区块链运行过程中希望固定执行的函数,例如希望在每个区块构建之前、之后的时候执行某些逻辑等,就可以把这些逻辑放在钩子函数中。
// 钩子函数一共有如下几个实现:
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
//on_finalize是在区块finalize的时候执行
fn on_finalize(_n: BlockNumber) {}
//on_idle是在on_finalize之前执行
fn on_idle(_n: BlockNumber, _remaining_weight: Weight) -> Weight {}
//on_initialize是在准备打包区块之前执行
fn on_initialize(_n: BlockNumber) -> Weight {}
//on_runtime_upgrade是升级的时候执行
fn on_runtime_upgrade() -> Weight {}
//pre_upgrade是在升级之前执行
fn pre_upgrade() -> Result<(), &'static str> {}
//post_upgrade是在升级之后执行
fn post_upgrade() -> Result<(), &'static str> {}
//offchain_worker在每个区块同步的时候执行
fn offchain_worker(_n: BlockNumber) {}
//待定
fn integrity_test() {}
}

// 是可以从runtime外部可以调用的函数,也是pallet对外提供的逻辑功能。
#[pallet::call]
impl<T: Config> Pallet<T> {}

//一般还会有一个内部逻辑,不对外开放,方便开发内部pallet使用
impl<T: Config> Pallet<T> {}
}

总结

本文编辑完毕

  • Copyrights © 2017-2023 Jason
  • Visitors: | Views:

谢谢打赏~

微信