Rust联盟插件库pallet-alliance的使用:构建去中心化治理与协作的Substrate区块链模块
Rust联盟插件库pallet-alliance的使用:构建去中心化治理与协作的Substrate区块链模块
Alliance Pallet概述
Alliance Pallet提供了一个集体治理机制,维护由投票成员认定的不道德行为者的账户和URL列表,主要功能包括:
- 提供针对不良行为的道德准则
- 为生态系统贡献者提供认可和影响力
核心功能
联盟通过Root调用初始化后,具备以下特性:
- 任何拥有已批准身份和网站的账户可作为Ally加入
MembershipManager
origin可将Ally提升为Fellow(拥有投票权)- 投票成员维护账户和网站列表
- 成员可投票更新规则并发布公告
完整示例代码
以下是基于Substrate的pallet-alliance完整实现示例,包含详细注释:
//! 联盟模块实现
use frame_support::{
decl_module, decl_storage, decl_event, decl_error,
dispatch, traits::Get, ensure
};
use frame_system::{ensure_root, ensure_signed};
use sp_std::prelude::*;
use frame_support::traits::EnsureOrigin;
/// 联盟模块配置Trait
pub trait Trait: frame_system::Trait {
/// 事件类型
type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
/// 成员管理权限
type MembershipManager: EnsureOrigin<Self::Origin>;
/// 退休通知期(区块数)
type RetirementPeriod: Get<Self::BlockNumber>;
/// Ally加入押金
type AllyDeposit: Get<Self::Balance>;
}
// 存储项定义
decl_storage! {
trait Store for Module<T: Trait> as Alliance {
/// 成员状态存储
pub Members get(fn members):
map hasher(blake2_128_concat) T::AccountId => MemberStatus;
/// 联盟规则(IPFS CID)
pub Rule get(fn rule): Option<Vec<u8>>;
/// 公告列表(IPFS CID)
pub Announcements get(fn announcements): Vec<Vec<u8>>;
/// 不道德项目列表
pub UnscrupulousList get(fn unscrupulous_list): Vec<UnscrupulousItem>;
/// 退休通知
pub RetirementNotice get(fn retirement_notice):
map hasher(blake2_128_concat) T::AccountId => T::BlockNumber;
/// 动议列表
pub Motions get(fn motions): Vec<Motion<T::AccountId, T::BlockNumber>>;
}
}
// 事件定义
decl_event!(
pub enum Event<T> where AccountId = <T as frame_system::Trait>::AccountId {
/// 新成员加入(Ally)
NewAlly(AccountId),
/// Ally晋升为Fellow
AllyElevated(AccountId),
/// 成员退休
MemberRetired(AccountId),
/// 规则更新
RuleUpdated(Vec<u8>),
/// 新公告
AnnouncementAdded(Vec<u8>),
/// 不道德项目添加
UnscrupulousItemAdded(UnscrupulousItem),
/// 不道德项目移除
UnscrupulousItemRemoved(UnscrupulousItem),
}
);
// 错误类型
decl_error! {
pub enum Error for Module<T: Trait> {
/// 账户已是成员
AlreadyMember,
/// 账户不是成员
NotMember,
/// 账户不是Fellow
NotFellow,
/// 退休通知期未到
RetirementNoticeNotGiven,
/// 退休期未结束
RetirementPeriodNotPassed,
}
}
// 模块实现
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
type Error = Error<T>;
fn deposit_event() = default;
/// 初始化联盟成员(Root权限)
#[weight = 10_000]
pub fn init_members(
origin,
fellows: Vec<T::AccountId>,
allies: Vec<T::AccountId>
) -> dispatch::DispatchResult {
ensure_root(origin)?;
// 初始化Fellow成员
for fellow in fellows {
ensure!(!<Members<T>>::contains_key(&fellow), Error::<T>::AlreadyMember);
<Members<T>>::insert(&fellow, MemberStatus::Fellow);
Self::deposit_event(RawEvent::NewAlly(fellow));
}
// 初始化Ally成员
for ally in allies {
ensure!(!<Members<T>>::contains_key(&ally), Error::<T>::AlreadyMember);
<Members<T>>::insert(&ally, MemberStatus::Ally);
Self::deposit_event(RawEvent::NewAlly(ally));
}
Ok(())
}
/// 加入联盟(成为Ally)
#[weight = 10_000]
pub fn join_alliance(origin) -> dispatch::DispatchResult {
let who = ensure_signed(origin)?;
ensure!(!<Members<T>>::contains_key(&who), Error::<T>::AlreadyMember);
// 设置初始状态为Ally
<Members<T>>::insert(&who, MemberStatus::Ally);
Self::deposit_event(RawEvent::NewAlly(who));
Ok(())
}
/// 提升Ally为Fellow(需MembershipManager权限)
#[weight = 10_000]
pub fn elevate_ally(
origin,
ally: T::AccountId
) -> dispatch::DispatchResult {
T::MembershipManager::ensure_origin(origin)?;
ensure!(
<Members<T>>::get(&ally) == Some(MemberStatus::Ally),
Error::<T>::NotMember
);
<Members<T>>::insert(&ally, MemberStatus::Fellow);
Self::deposit_event(RawEvent::AllyElevated(ally));
Ok(())
}
/// 设置联盟规则(仅Fellow可调用)
#[weight = 10_000]
pub fn set_rule(
origin,
rule: Vec<u8>
) -> dispatch::DispatchResult {
let who = ensure_signed(origin)?;
ensure!(
<Members<T>>::get(&who) == Some(MemberStatus::Fellow),
Error::<T>::NotFellow
);
<Rule>::put(rule.clone());
Self::deposit_event(RawEvent::RuleUpdated(rule));
Ok(())
}
/// 添加不道德项目(仅Fellow可调用)
#[weight = 10_000]
pub fn add_unscrupulous_items(
origin,
items: Vec<UnscrupulousItem>
) -> dispatch::DispatchResult {
let who = ensure_signed(origin)?;
ensure!(
<Members<T>>::get(&who) == Some(MemberStatus::Fellow),
Error::<T>::NotFellow
);
for item in items {
<UnscrupulousList>::mutate(|list| {
if !list.contains(&item) {
list.push(item.clone());
Self::deposit_event(RawEvent::UnscrupulousItemAdded(item));
}
});
}
Ok(())
}
}
}
/// 成员状态枚举
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
pub enum MemberStatus {
/// 投票成员
Fellow,
/// 普通成员
Ally,
}
/// 不道德项目类型
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
pub enum UnscrupulousItem {
/// 不良账户
AccountId(Vec<u8>),
/// 不良网站
Website(Vec<u8>),
}
/// 动议结构
#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
pub struct Motion<AccountId, BlockNumber> {
/// 提案人
proposer: AccountId,
/// 提案区块
created: BlockNumber,
/// 赞成票
ayes: Vec<AccountId>,
/// 反对票
nays: Vec<AccountId>,
}
功能说明
-
成员管理:
- 通过
init_members
初始化创始成员 join_alliance
允许新成员加入elevate_ally
提升成员权限等级
- 通过
-
治理功能:
set_rule
更新联盟规则add_unscrupulous_items
管理不良行为列表
-
权限控制:
- Root权限执行初始化
- Fellow成员拥有治理权限
- MembershipManager控制成员晋升
集成说明
要使用此pallet,需要在runtime中配置:
impl alliance::Trait for Runtime {
type Event = Event;
type MembershipManager = EnsureRootOrHalfCouncil;
type RetirementPeriod = RetirementPeriod;
type AllyDeposit = AllyDeposit;
}
该实现提供了完整的联盟治理功能,包括成员管理、规则制定和不良行为监管,可作为Substrate区块链去中心化治理的基础模块。
1 回复
以下是基于您提供的内容整理的关于pallet-alliance的完整示例demo:
内容中提供的核心示例
- 提交提案示例
// 创建一个调用示例
let proposal = Box::new(Call::System(frame_system::Call::remark { remark: b"Hello Alliance".to_vec() }));
// 提交提案
Alliance::propose(
RuntimeOrigin::signed(member_account),
threshold, // 通过所需的票数
proposal,
proposal_len,
);
- 投票表决示例
// 成员对提案进行投票
Alliance::vote(
RuntimeOrigin::signed(member_account),
proposal_hash,
proposal_index,
true, // 赞成或反对
);
- 添加新成员示例
// 现有成员提议添加新成员
Alliance::add_member(
RuntimeOrigin::signed(existing_member_account),
new_member_account,
);
完整示例demo
// 1. 引入必要依赖和模块
use frame_support::{decl_module, decl_event, dispatch::DispatchResult};
use frame_system::{self as system, ensure_signed};
use sp_runtime::traits::{AccountIdConversion, Hash};
use sp_std::prelude::*;
// 2. 定义联盟模块
pub trait Config: system::Config {
type Event: From<Event<Self>> + Into<<Self as system::Config>::Event>;
}
decl_event!(
pub enum Event<T> where AccountId = <T as system::Config>::AccountId {
/// 新成员加入事件
MemberAdded(AccountId),
/// 提案提交事件
ProposalSubmitted(Hash, AccountId),
}
);
decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::Origin {
fn deposit_event() = default;
/// 添加新成员
#[weight = 10_000]
pub fn add_member(origin, new_member: T::AccountId) -> DispatchResult {
let sender = ensure_signed(origin)?;
// 验证发送者权限
Self::ensure_member(&sender)?;
// 添加新成员逻辑
Members::<T>::insert(&new_member, ());
// 触发事件
Self::deposit_event(RawEvent::MemberAdded(new_member));
Ok(())
}
/// 提交提案
#[weight = 10_000]
pub fn propose(
origin,
proposal: Box<<T as Config>::Proposal>,
proposal_len: u32,
) -> DispatchResult {
let sender = ensure_signed(origin)?;
// 验证发送者权限
Self::ensure_member(&sender)?;
// 生成提案哈希
let proposal_hash = T::Hashing::hash_of(&proposal);
// 存储提案
Proposals::<T>::insert(&proposal_hash, (sender.clone(), proposal));
// 触发事件
Self::deposit_event(RawEvent::ProposalSubmitted(proposal_hash, sender));
Ok(())
}
/// 对提案投票
#[weight = 10_000]
pub fn vote(
origin,
proposal_hash: T::Hash,
index: ProposalIndex,
approve: bool,
) -> DispatchResult {
let sender = ensure_signed(origin)?;
// 验证发送者权限
Self::ensure_member(&sender)?;
// 投票逻辑
Votes::<T>::insert((proposal_hash, sender), (index, approve));
Ok(())
}
}
}
// 3. 自定义投票权重实现
struct CustomVoteWeight;
impl VoteWeighting for CustomVoteWeight {
fn vote_weight(who: &AccountId) -> VoteWeight {
// 基于账户余额计算投票权重
Balances::free_balance(who)
}
}
// 4. 在runtime中配置
impl pallet_alliance::Config for Runtime {
type Event = Event;
type Proposal = Call;
type Currency = Balances;
type MembershipChanged = AllianceMembershipChanged;
type ProposalLifetime = ProposalLifetime;
type VoteWeighting = CustomVoteWeight;
}
// 5. 链初始配置示例
pub fn testnet_genesis() -> GenesisConfig {
GenesisConfig {
alliance: AllianceConfig {
members: vec![
// 初始成员列表
get_account_id_from_seed::<sr25519::Public>("Alice"),
get_account_id_from_seed::<sr25519::Public>("Bob"),
],
phantom: Default::default(),
},
// 其他pallet配置...
}
}
示例说明
- 成员管理:通过
add_member
函数实现成员添加,触发MemberAdded
事件 - 提案系统:
propose
函数处理提案提交,存储提案并触发ProposalSubmitted
事件 - 投票机制:
vote
函数实现投票功能,使用自定义的CustomVoteWeight
计算投票权重 - runtime配置:展示了如何在runtime中配置pallet-alliance
- 链初始化:提供了测试网初始成员配置示例
使用建议
- 在实际部署前,应充分测试所有治理流程
- 根据业务需求调整投票权重算法
- 合理设置提案生命周期参数
- 建议实现成员退出和惩罚机制作为补充