Rust区块链成员管理插件pallet-membership的使用,实现Substrate链上成员权限与身份管理

Rust区块链成员管理插件pallet-membership的使用,实现Substrate链上成员权限与身份管理

模块介绍

Membership模块允许控制一组AccountId的成员资格,对于管理集体成员非常有用。可以设置一个主要成员(prime member)。

许可证:Apache-2.0

安装

在项目目录中运行以下Cargo命令:

cargo add pallet-membership

或在Cargo.toml中添加以下行:

pallet-membership = "42.0.0"

完整示例代码

// 引入必要的模块和类型
use frame_support::{decl_module, decl_event, decl_storage, dispatch::DispatchResult, ensure};
use frame_system::{self as system, ensure_root};
use sp_std::prelude::*;

// 配置trait,定义模块所需的类型
pub trait Trait: system::Trait {
    /// 事件类型
    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}

// 定义存储项
decl_storage! {
    trait Store for Module<T: Trait> as Membership {
        /// 当前成员列表
        Members get(fn members): Vec<T::AccountId>;
        /// 主要成员(prime member)
        Prime get(fn prime): Option<T::AccountId>;
    }
}

// 定义事件
decl_event!(
    pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
        /// 成员已添加
        MemberAdded(AccountId),
        /// 成员已移除
        MemberRemoved(AccountId),
        /// 主要成员已更改
        PrimeChanged(Option<AccountId>),
    }
);

// 定义模块
decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
        fn deposit_event() = default;

        /// 添加一个新成员
        #[weight = 10_000]
        pub fn add_member(origin, who: T::AccountId) -> DispatchResult {
            ensure_root(origin)?;
            
            // 确保该账户还不是成员
            ensure!(!Members::<T>::contains(&who), "Already a member");
            
            // 添加到成员列表
            Members::<T>::mutate(|members| members.push(who.clone()));
            
            // 发出事件
            Self::deposit_event(RawEvent::MemberAdded(who));
            Ok(())
        }

        /// 移除一个成员
        #[weight = 10_000]
        pub fn remove_member(origin, who: T::AccountId) -> DispatchResult {
            ensure_root(origin)?;
            
            // 确保该账户是成员
            ensure!(Members::<T>::contains(&who), "Not a member");
            
            // 从成员列表中移除
            Members::<T>::mutate(|members| members.retain(|m| m != &who));
            
            // 如果移除的是主要成员,则清除主要成员
            if Prime::<T>::get() == Some(who.clone()) {
                Prime::<T>::put(None);
                Self::deposit_event(RawEvent::PrimeChanged(None));
            }
            
            // 发出事件
            Self::deposit_event(RawEvent::MemberRemoved(who));
            Ok(())
        }

        /// 设置主要成员
        #[weight = 10_000]
        pub fn set_prime(origin, who: T::AccountId) -> DispatchResult {
            ensure_root(origin)?;
            
            // 确保该账户是成员
            ensure!(Members::<T>::contains(&who), "Not a member");
            
            // 设置主要成员
            Prime::<T>::put(Some(who.clone()));
            
            // 发出事件
            Self::deposit_event(RawEvent::PrimeChanged(Some(who));
            Ok(())
        }

        /// 清除主要成员
        #[weight = 10_000]
        pub fn clear_prime(origin) -> DispatchResult {
            ensure_root(origin)?;
            
            // 清除主要成员
            Prime::<T>::put(None);
            
            // 发出事件
            Self::deposit_event(RawEvent::PrimeChanged(None));
            Ok(())
        }
    }
}

功能说明

  1. 成员管理

    • 添加成员 (add_member)
    • 移除成员 (remove_member)
  2. 主要成员管理

    • 设置主要成员 (set_prime)
    • 清除主要成员 (clear_prime)
  3. 事件通知

    • 成员添加/移除事件
    • 主要成员变更事件

使用场景

该模块适用于需要管理特权账户或成员资格的区块链场景,例如:

  • 治理委员会成员管理
  • 特权操作账户管理
  • 多签钱包成员管理

通过该模块,可以实现链上成员资格的透明管理,所有变更都会记录在区块链上,确保可审计性和不可篡改性。


1 回复

Rust区块链成员管理插件pallet-membership的使用

概述

pallet-membership是Substrate框架中的一个FRAME pallet,用于管理区块链上的成员资格和权限系统。它提供了一套功能来添加、删除和修改链上成员,并可以与其他pallet(如集体pallet)结合使用来实现治理功能。

主要功能

  1. 添加和移除成员
  2. 设置和修改成员元数据
  3. 与其他治理模块集成
  4. 成员身份验证

使用方法

1. 在runtime中集成pallet-membership

首先需要在你的Substrate runtime的Cargo.toml中添加依赖:

[dependencies.pallet-membership]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'master'

然后在runtime的lib.rs中配置和实现:

impl pallet_membership::Config for Runtime {
    type Event = Event;
    type AddOrigin = frame_system::EnsureRoot<AccountId>;  // 或使用EnsureOneOf等
    type RemoveOrigin = frame_system::EnsureRoot<AccountId>;
    type SwapOrigin = frame_system::EnsureRoot<AccountId>;
    type ResetOrigin = frame_system::EnsureRoot<AccountId>;
    type PrimeOrigin = frame_system::EnsureRoot<AccountId>;
    type MembershipInitialized = ();
    type MembershipChanged = ();
}

2. 基本操作示例

添加成员

use frame_support::dispatch::DispatchResult;

fn add_member(account_id: AccountId) -> DispatchResult {
    pallet_membership::Pallet::<Runtime>::add_member(
        frame_system::RawOrigin::Root.into(),
        account_id
    )
}

移除成员

fn remove_member(account_id: AccountId) -> DispatchResult {
    pallet_membership::Pallet::<Runtime>::remove_member(
        frame_system::RawOrigin::Root.into(),
        account_id
    )
}

交换成员

fn swap_member(old: AccountId, new: AccountId) -> DispatchResult {
    pallet_membership::Pallet::<Runtime>::swap_member(
        frame_system::RawOrigin::Root.into(),
        old,
        new
    )
}

3. 与其他pallet集成

pallet-membership常与pallet-collective一起使用,实现基于成员身份的治理:

impl pallet_collective::Config for Runtime {
    type Event = Event;
    type Proposal = Call;
    type Members = pallet_membership::Module<Runtime>;
    // 其他配置...
}

4. 查询成员信息

// 检查是否是成员
let is_member = pallet_membership::Module::<Runtime>::is_member(&account_id);

// 获取所有成员
let members = pallet_membership::Module::<Runtime>::members();

// 获取主成员(如果有设置)
let prime = pallet_membership::Module::<Runtime>::prime();

进阶用法

自定义成员权限

可以扩展pallet-membership来实现自定义权限逻辑:

impl<T: Config> SomeOtherPallet<T> {
    fn ensure_member(account: &T::AccountId) -> DispatchResult {
        ensure!(
            pallet_membership::Module::<T>::is_member(account),
            Error::<T>::NotAMember
        );
        Ok(())
    }
}

成员变更事件处理

可以监听成员变更事件:

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
    fn on_initialize(_n: T::BlockNumber) -> Weight {
        // 处理成员变更逻辑
        0
    }
}

完整示例demo

以下是一个完整的runtime集成示例:

// runtime/src/lib.rs

// 1. 添加依赖到Cargo.toml
/*
[dependencies.pallet-membership]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
branch = 'master'
*/

// 2. 在runtime中配置pallet
pub use pallet_membership;

impl pallet_membership::Config for Runtime {
    type Event = Event;
    type AddOrigin = frame_system::EnsureRoot<AccountId>;
    type RemoveOrigin = frame_system::EnsureRoot<AccountId>;
    type SwapOrigin = frame_system::EnsureRoot<AccountId>;
    type ResetOrigin = frame_system::EnsureRoot<AccountId>;
    type PrimeOrigin = frame_system::EnsureRoot<AccountId>;
    type MembershipInitialized = ();
    type MembershipChanged = ();
}

// 3. 在construct_runtime!宏中添加pallet
construct_runtime!(
    pub enum Runtime where
        Block = Block,
        NodeBlock = opaque::Block,
        UncheckedExtrinsic = UncheckedExtrinsic
    {
        // ... 其他pallet
        Membership: pallet_membership::{Module, Call, Storage, Event<T>},
    }
);

// 4. 示例调用代码
pub mod membership_examples {
    use super::*;
    
    // 添加成员示例
    pub fn example_add_member(account_id: AccountId) -> DispatchResult {
        pallet_membership::Pallet::<Runtime>::add_member(
            frame_system::RawOrigin::Root.into(),
            account_id
        )
    }
    
    // 移除成员示例
    pub fn example_remove_member(account_id: AccountId) -> DispatchResult {
        pallet_membership::Pallet::<Runtime>::remove_member(
            frame_system::RawOrigin::Root.into(),
            account_id
        )
    }
    
    // 查询成员示例
    pub fn example_check_membership(account_id: AccountId) -> bool {
        pallet_membership::Module::<Runtime>::is_member(&account_id)
    }
}

注意事项

  1. 成员管理通常需要严格的权限控制,确保设置合适的origin检查
  2. 成员数量过多可能会影响链性能
  3. 成员资格通常与治理功能相关,设计时要考虑经济模型

pallet-membership为Substrate链提供了一个灵活且安全的成员管理系统,可以满足大多数区块链项目的身份管理需求。

回到顶部