首页
/ Substrate开发者指南:构建自定义FRAME Pallet

Substrate开发者指南:构建自定义FRAME Pallet

2025-07-05 16:05:53作者:温玫谨Lighthearted

前言

在Substrate区块链开发框架中,FRAME(Framework for Runtime Aggregation of Modular Entities)是一个核心组件,它允许开发者通过组合称为"pallet"的模块来构建区块链运行时。本文将详细介绍如何从零开始构建一个自定义的FRAME pallet,特别适合那些希望深入了解Substrate底层机制的开发者。

FRAME Pallet基础概念

什么是Pallet?

Pallet是Substrate运行时中的功能模块,每个pallet封装了特定的区块链功能逻辑。可以将其类比为:

  • 传统Web开发中的插件或组件
  • 微服务架构中的独立服务
  • 面向对象编程中的类

Pallet的核心组件

一个完整的FRAME pallet通常包含以下关键部分:

  1. Config trait:配置接口,定义pallet所需的类型和参数
  2. Storage:定义区块链状态存储的数据结构
  3. Events:定义pallet发出的事件类型
  4. Errors:定义pallet可能返回的错误类型
  5. Callable functions:定义用户可以调用的公开函数

构建Proof of Existence Pallet

我们将构建一个"存在证明"(Proof of Existence) pallet,它允许用户:

  1. 声明某个文件或数据的哈希存在于区块链上
  2. 撤销之前的声明

1. 项目结构准备

首先,我们需要准备pallet的基本结构:

#![cfg_attr(not(feature = "std"), no_std]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*};
    use frame_system::pallet_prelude::*;
    use sp_std::vec::Vec;
    
    // 后续各部分将填充在这里
}

关键点说明:

  • no_std属性是必需的,因为运行时需要编译为WASM
  • 使用FRAME提供的宏和工具函数

2. 配置Trait实现

#[pallet::config]
pub trait Config: frame_system::Config {
    type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
}

这个配置trait定义了pallet的基本要求,目前只需要能够发出事件。

3. 事件定义

#[pallet::event]
#[pallet::metadata(T::AccountId = "AccountId")]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
    ClaimCreated(T::AccountId, Vec<u8>),
    ClaimRevoked(T::AccountId, Vec<u8>),
}

我们定义了两个事件:

  • ClaimCreated:当新的证明被创建时触发
  • ClaimRevoked:当证明被撤销时触发

4. 错误处理

#[pallet::error]
pub enum Error<T> {
    ProofAlreadyClaimed,
    NoSuchProof,
    NotProofOwner,
}

定义了三种可能的错误情况:

  • 证明已被声明
  • 证明不存在
  • 非证明所有者尝试撤销

5. 存储设计

#[pallet::storage] 
pub(super) type Proofs<T: Config> = StorageMap<
    _,
    Blake2_128Concat, 
    Vec<u8>, 
    (T::AccountId, T::BlockNumber),
    ValueQuery
>;

使用StorageMap存储结构:

  • 键:证明数据的哈希值(Vec)
  • 值:元组(账户ID, 区块号)
  • 哈希算法:Blake2_128Concat

6. 可调用函数实现

创建证明

#[pallet::weight(1_000)]
pub fn create_claim(
    origin: OriginFor<T>,
    proof: Vec<u8>,
) -> DispatchResultWithPostInfo {
    let sender = ensure_signed(origin)?;
    ensure!(!Proofs::<T>::contains_key(&proof), Error::<T>::ProofAlreadyClaimed);
    
    let current_block = <frame_system::Pallet<T>>::block_number();
    Proofs::<T>::insert(&proof, (&sender, current_block));
    
    Self::deposit_event(Event::ClaimCreated(sender, proof));
    Ok(().into())
}

撤销证明

#[pallet::weight(10_000)]
pub fn revoke_claim(
    origin: OriginFor<T>,
    proof: Vec<u8>,
) -> DispatchResultWithPostInfo {
    let sender = ensure_signed(origin)?;
    ensure!(Proofs::<T>::contains_key(&proof), Error::<T>::NoSuchProof);
    
    let (owner, _) = Proofs::<T>::get(&proof);
    ensure!(sender == owner, Error::<T>::NotProofOwner);
    
    Proofs::<T>::remove(&proof);
    Self::deposit_event(Event::ClaimRevoked(sender, proof));
    Ok(().into())
}

开发注意事项

  1. 权重(Weight):每个可调用函数必须指定权重,表示其计算复杂度
  2. 存储操作:注意存储操作的代价,频繁写入会影响性能
  3. 错误处理:确保所有可能的错误情况都被覆盖
  4. 事件触发:重要状态变更应该触发相应事件

测试与部署

完成pallet开发后,可以通过以下步骤测试:

  1. 编译节点:cargo build --release
  2. 启动开发链:./target/release/node-template --dev --tmp

如果一切正常,节点应该开始出块,此时可以通过前端或命令行与你的新pallet交互。

进阶思考

  1. 如何扩展这个pallet以支持证明的有效期?
  2. 如何添加权限控制,只允许特定账户创建证明?
  3. 如何优化存储结构以减少gas费用?

这个简单的Proof of Existence pallet展示了FRAME pallet的基本结构和开发模式。在实际项目中,你可能需要更复杂的逻辑和更完善的错误处理,但核心概念是相通的。

登录后查看全文
热门项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
178
263
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
868
514
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
130
183
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
288
323
HarmonyOS-ExamplesHarmonyOS-Examples
本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计!
Cangjie
398
373
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.07 K
0
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
93
15
note-gennote-gen
一款跨平台的 Markdown AI 笔记软件,致力于使用 AI 建立记录和写作的桥梁。
TSX
83
4
cherry-studiocherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
600
58
GitNextGitNext
基于可以运行在OpenHarmony的git,提供git客户端操作能力
ArkTS
10
3