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(())
}
}
}
功能说明
-
成员管理:
- 添加成员 (
add_member
) - 移除成员 (
remove_member
)
- 添加成员 (
-
主要成员管理:
- 设置主要成员 (
set_prime
) - 清除主要成员 (
clear_prime
)
- 设置主要成员 (
-
事件通知:
- 成员添加/移除事件
- 主要成员变更事件
使用场景
该模块适用于需要管理特权账户或成员资格的区块链场景,例如:
- 治理委员会成员管理
- 特权操作账户管理
- 多签钱包成员管理
通过该模块,可以实现链上成员资格的透明管理,所有变更都会记录在区块链上,确保可审计性和不可篡改性。
1 回复
Rust区块链成员管理插件pallet-membership的使用
概述
pallet-membership
是Substrate框架中的一个FRAME pallet,用于管理区块链上的成员资格和权限系统。它提供了一套功能来添加、删除和修改链上成员,并可以与其他pallet(如集体pallet)结合使用来实现治理功能。
主要功能
- 添加和移除成员
- 设置和修改成员元数据
- 与其他治理模块集成
- 成员身份验证
使用方法
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)
}
}
注意事项
- 成员管理通常需要严格的权限控制,确保设置合适的origin检查
- 成员数量过多可能会影响链性能
- 成员资格通常与治理功能相关,设计时要考虑经济模型
pallet-membership
为Substrate链提供了一个灵活且安全的成员管理系统,可以满足大多数区块链项目的身份管理需求。