Substrate knowledgebase: Pallets

以下文档是为熟悉Rust编程语言的技术受众编写的。它是FRAME runtime开发的顶级入口点。

如果你刚刚开始Substrate runtime的开发,我们建议您尝试我们的入门教程来创建您的第一条Substrate链

What is a Pallet?

Pallets是一种特殊的Rust模块,由一组类型(types)、特征实现(trait implementations)和功能(functions)组成,Substrate runtimes可以从这些类型、特征实现和功能组成。FRAME不仅提供了一个常用 Substrate pallets 库,还提供了一个构建定制领域特定的pallets的框架,使runtime工程师能够根据其目标用例灵活地定义其runtime的行为。结果:每个pallet都有自己的离散逻辑,可以修改区块链状态转换函数的特征和功能。

例如, FRAME中包含的Balances pallet定义了区块链的加密货币功能。更具体地说,它定义了:

  • Storage items that keep track of the tokens a user owns.
    跟踪用户拥有的tokens。
  • Functions that users can call to transfer and manage those tokens.
    用户可以调用来转移和管理这些tokens。
  • APIs which allow other pallets to make use of those tokens and their capabilities.
    允许其他pallets使用这些 tokens 及其功能。
  • Hooks which allow other pallets to trigger function calls when a user’s balance changes.
    允许其他pallets在用户的余额发生变化时触发函数调用。

Substrate runtime 工程师可以通过编写自己的pallets并通过将定制的pallets与现有FRAME pallets或Substrate模块相结合来封装其区块链所需的功能来定义其区块链的定制逻辑。下面的文档将向您展示如何实现。

注意:在撰写本文时,FRAME pallets有两种不同的版本—版本1和版本2。本文首先介绍v1托盘的结构。跳至FRAME v2,了解Substrate pallet的最新结构。有关这些更改的更多信息,请阅读此处

Skeleton of a Pallet

FRAME v1

Substrate pallet由5个部分组成:

// 1. Imports and Dependencies
// The pallet supports the use of any Rust library which compiles
// with the `no_std` flag.
use support::{decl_module, decl_event, decl_storage, ...}

// 2. Runtime Configuration Trait
// All of the runtime types and consts go in here. If the pallet
// is dependent on specific other pallets, then their configuration traits
// should be added to the inherited traits list.
pub trait Config: frame_system::Config { ... }

// 3. Runtime Events
// Events are a simple means of reporting specific conditions and circumstances
// that have happened that users, Dapps and/or chain explorers would find
// interesting and otherwise difficult to detect.
decl_event! { ... }

// 4. Runtime Storage
// This allows for type-safe usage of the Substrate storage database, so you can
// keep things around between blocks.
decl_storage! { ... }

// 5. The Pallet Declaration
// This defines the `Module` struct that is ultimately exported from this pallet.
// It defines the callable functions that this pallet exposes and orchestrates
// actions this pallet takes throughout block execution.
decl_module! { ... }

注意:额外的部分,比如decl_error! 是经常使用的,但不是最小工作pallet所必需的。

Example
Basic Token recipe提供了一个简单的FRAME V1 pallet的良好示例,该pallet允许用户在存储器中创建u64代币供应以及帐户ID和u64余额的StorageMap。主要部分包括:

  • decl_storage! defines TotalSupply and Balances the pallet’s storage items;
  • decl_event! defines Initialized and Transfer events;
  • decl_module! defines the pallet’s functions, init() and transfer(); and
  • decl_module! also has a deposit_event() function, common to all pallets that define behavior that emits an event.

FRAME v2

A FRAME v2 pallet is commonly composed of 7 sections:
FRAME v2 pallet 通常由7个部分组成:

// 1. Imports and Dependencies
pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;
}

// 2. Declaration of the Pallet type 
// This is a placeholder to implement traits and methods.
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(PhantomData<T>);

// 3. Runtime Configuration Trait
// All types and constants go here. 
// Use #[pallet::constant] and #[pallet::extra_constants] 
// to pass in values to metadata.
#[pallet::config]
pub trait Config: frame_system::Config { ... }

// 4. Runtime Storage
// Use to declare storage items.
#[pallet::storage]
#[pallet::getter(fn something)]
pub type MyStorage<T: Config> = StorageValue<_, u32>;

// 5. Runtime Events
// Can stringify event types to metadata.
#[pallet::event]
#[pallet::metadata(T::AccountId = "AccountId")]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> { ... }

// 6. Hooks
// Define some logic that should be executed
// regularly in some context, for e.g. on_initialize.
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> { ... }

// 7. Extrinsics
// Functions that are callable from outside the runtime.
#[pallet::call]
impl<T:Config> Pallet<T> { ... }

注意:Pallets可以根据需要由任意多个部分组成,这给运行时工程师在上面描述的基本框架上提供了很大的灵活性。有关向FRAME pallet添加功能的更多信息,请参阅Substrate Runtime Macros

Examples

这是一个最小的工作pallet,它只是简单的让用户将u64值放入存储器:

use support::{decl_module, decl_event, decl_storage, StorageValue, StorageMap};
use system::ensure_signed;

pub trait Config: system::Config {
    // The traits the `Event` type used in this pallet has.
    type Event: From<Event<Self>> + Into<<Self as system::Config>::Event>;
}

decl_event!{
    pub enum Event<T> where
        AccountId = <T as system::Config>::AccountId,
    {
        // An event which is emitted when `set_value` is called.
        // Contains information about the user who called the function
        // and the value they called with.
        ValueSet(AccountId, u64),
    }
}

decl_storage! {
    trait Store for Module<T: Config> as Example {
        // The last value passed to `set_value`.
        // Used as an example of a `StorageValue`.
        pub LastValue get(fn last_value): u64;
        // The value each user has put into `set_value`.
        // Used as an example of a `StorageMap`.
        pub UserValue get(fn user_value): map T::AccountId => u64;
    }
}

decl_module! {
    pub struct Module<T: Config> for enum Call where origin: T::Origin {
        // A default function for depositing events in our runtime
        fn deposit_event() = default;

        // The only callable function of our runtime module.
        // Allows a user to set a `u64` value into the runtime storage.
        pub fn set_value(origin, value: u64) {
            let sender = ensure_signed(origin)?;
            LastValue::put(value);
            UserValue::<T>::insert(&sender, value);
            Self::deposit_event(RawEvent::ValueSet(sender, value));
        }
    }
}

上述示例类似于FRAME的Nicks pallet。有关上下文,请参见:

相关内容:
https://substrate.dev/docs/en/knowledgebase/runtime/pallets

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值