Rust区块链治理模块pallet-society的使用,实现去中心化社交网络与成员激励机制

Rust区块链治理模块pallet-society的使用,实现去中心化社交网络与成员激励机制

Society模块概述

Society模块是一个经济游戏,它激励用户参与并维护一个会员制社会。

用户类型

在任何时候,社会中的用户可以是以下类型之一:

  • 投标者(Bidder) - 已提交加入社会意向的用户
  • 候选人(Candidate) - 将被投票表决是否加入社会的用户
  • 被暂停的候选人(Suspended Candidate) - 未能赢得投票的用户
  • 成员(Member) - 社会的成员用户
  • 被暂停的成员(Suspended Member) - 积累了太多惩罚或未能通过成员资格挑战的成员

在非暂停成员中,总是有:

  • 首领(Head) - 免于暂停的成员
  • 辩护者(Defender) - 成员资格受到质疑并需要再次投票表决的成员

工作机制

奖励

成员通过社会金库支付的奖励来激励参与。这些支付有成熟期,用户必须等待才能访问资金。

惩罚

成员可以被惩罚,通过削减他们未领取的奖励支付。此外,成员可以积累"惩罚",当达到最大惩罚限制时,他们会被暂停。

质疑者

在投票期间,随机选择一组成员作为"质疑者"。这些质疑者需要对当前候选人进行投票。如果他们不投票,他们的质疑者状态被视为拒绝投票,成员被视为"懒惰",并每次未投票都会获得一次惩罚。

成员资格挑战

每个挑战轮换期,随机选择一个现有成员来捍卫他们在社会中的成员资格。然后,其他成员可以投票决定这个辩护者是否应该留在社会中。简单多数票决定用户的结果。

社会金库

会员社会由一个独立的金库资助,由该模块管理。这个金库的一部分被放入社会资金池,用于确定接受的投标数量。

增长率

会员社会可以以每个轮换期最多10个被接受的候选人的速度增长,直到达到最大成员阈值。一旦达到这个阈值,候选人选择就会停滞,直到有新成员加入的空间。

用户生命周期

用户可以通过以下阶段:

          +------->  User  <----------+
          |           +               |
          |           |               |
+----------------------------------------------+
|         |           |               |        |
|         |           v               |        |
|         |        Bidder <-----------+        |
|         |           +               |        |
|         |           |               +        |
|         |           v            Suspended   |
|         |       Candidate +----> Candidate  |
|         |           +               +        |
|         |           |               |        |
|         +           |               |        |
|   Suspended +-------+               |        |
|      Member         |               |        |
|         ^           |               |        |
|         |           v               |        |
|         +-------+ Member <----------+        |
|                                              |
|                                              |
+------------------Society---------------------+

接口

可调度函数

普通用户

  • bid - 用户可以通过预留押金来投标加入会员社会
  • unbid - 用户可以撤回他们的加入投标,押金将被退还

成员

  • vouch - 成员可以代表用户投标加入会员社会
  • unvouch - 成员可以撤销他们对用户的担保
  • vote - 成员可以投票批准或拒绝候选人加入社会的请求
  • defender_vote - 成员可以投票批准或拒绝辩护者继续会员资格
  • payout - 成员可以领取他们第一个成熟的支付
  • unfound - 允许创始人在他们是唯一成员时解散社会

超级用户

  • found - 创始人来源可以初始化这个社会
  • judge_suspended_member - 暂停判决来源能够对暂停成员做出判决
  • judge_suspended_candidate - 暂停判决来源能够对暂停候选人做出判决
  • set_max_membership - ROOT来源可以更新社会的最大成员数

完整示例代码

// 1. 添加依赖到Cargo.toml
// pallet-society = "42.0.0"

// 2. 示例代码
use frame_support::{decl_module, decl_event, decl_storage, dispatch::DispatchResult, ensure};
use frame_system::{self as system, ensure_signed};
use sp_runtime::traits::{Hash, Zero};
use pallet_society::{self as society, Trait as SocietyTrait};

pub trait Trait: SocietyTrait + system::Trait {
    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}

decl_event! {
    pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
        /// 新成员加入
        NewMember(AccountId),
        /// 成员被暂停
        MemberSuspended(AccountId),
    }
}

decl_storage! {
    trait Store for Module<T: Trait> as SocietyModule {
        /// 社交网络成员计数
        MemberCount get(fn member_count): u32;
    }
}

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

        /// 加入社交网络
        #[weight = 10_000]
        pub fn join_society(origin) -> DispatchResult {
            let who = ensure_signed(origin)?;
            
            // 投标加入社会
            <society::Module<T>>::bid(RawOrigin::Signed(who.clone()).into(), Default::default())?;
            
            Ok(())
        }

        /// 投票赞成候选人
        #[weight = 10_000]
        pub fn vote_candidate(origin, candidate: T::AccountId, approve: bool) -> DispatchResult {
            let who = ensure_signed(origin)?;
            
            // 确保调用者是成员
            ensure!(<society::Module<T>>::is_member(&who), "Only members can vote");
            
            // 投票
            <society::Module<T>>::vote(RawOrigin::Signed(who).into(), candidate, approve)?;
            
            Ok(())
        }

        /// 领取奖励
        #[weight = 10_000]
        pub fn claim_reward(origin) -> DispatchResult {
            let who = ensure_signed(origin)?;
            
            // 确保调用者是成员
            ensure!(<society::Module<T>>::is_member(&who), "Only members can claim rewards");
            
            // 领取支付
            <society::Module<T>>::payout(RawOrigin::Signed(who).into())?;
            
            Ok(())
        }
    }
}

// 实现社会事件处理
impl<T: Trait> society::OnSocietyEvent<T::AccountId> for Module<T> {
    fn on_new_member(member: &T::AccountId) {
        MemberCount::mutate(|count| *count += 1);
        Self::deposit_event(RawEvent::NewMember(member.clone()));
    }

    fn on_suspended_member(member: &T::AccountId) {
        MemberCount::mutate(|count| *count -= 1);
        Self::deposit_event(RawEvent::MemberSuspended(member.clone()));
    }
}

这个示例展示了如何使用pallet-society构建一个去中心化的社交网络:

  1. 用户可以通过join_society函数投标加入网络
  2. 现有成员可以通过vote_candidate函数投票决定新成员
  3. 成员可以通过claim_reward函数领取他们的奖励
  4. 实现了事件处理来跟踪成员变化

要使用这个模块,你还需要配置runtime并集成到你的区块链中。这个示例提供了基本功能,可以根据需要扩展更多治理功能。


1 回复

以下是基于您提供的内容整理的完整示例代码,展示了如何使用pallet-society实现去中心化社交网络与成员激励机制:

// runtime/src/lib.rs

// 1. 集成pallet-society到runtime
impl pallet_society::Config for Runtime {
    type Event = Event;
    type Currency = Balances;  // 使用Balances作为货币类型
    type Randomness = RandomnessCollectiveFlip;  // 随机性来源
    type CandidateDeposit = ConstU128<100>;  // 候选人押金100
    type WrongSideDeduction = ConstU128<10>;  // 错误判断扣除10
    type MaxStrikes = ConstU32<3>;  // 最大惩罚次数3次
    type PeriodSpend = ConstU128<1000>;  // 周期支出限额1000
    type MembershipChanged = ();  // 成员变更回调
    type RotationPeriod = ConstU32<7>;  // 7个区块为1个周期
    type MaxLockDuration = ConstU32<365>;  // 最大锁定365天
    type FounderSetOrigin = EnsureRoot<AccountId>;  // 仅root可设置创始人
    type SuspensionJudgementOrigin = EnsureRoot<AccountId>;  // 仅root可暂停成员
}

// 2. 自定义社交网络pallet
#[frame_support::pallet]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;
    
    #[pallet::config]
    pub trait Config: frame_system::Config + pallet_society::Config {
        type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
    }
    
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// 成员发布了消息
        MessagePosted(T::AccountId),
        /// 成员等级提升
        MemberPromoted(T::AccountId, u8),
    }
    
    #[pallet::storage]
    #[pallet::getter(fn messages)]
    pub(super) type Messages<T: Config> = StorageMap<
        _,
        Blake2_128Concat,
        T::AccountId,
        Vec<Vec<u8>>,
        ValueQuery
    >;
    
    #[pallet::storage]
    #[pallet::getter(fn member_rank)]
    pub(super) type MemberRank<T: Config> = StorageMap<
        _,
        Blake2_128Concat,
        T::AccountId,
        u8,
        ValueQuery
    >;
    
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        /// 发布社交消息
        #[pallet::weight(10_000)]
        pub fn post_message(origin: OriginFor<T>, message: Vec<u8>) -> DispatchResult {
            let who = ensure_signed(origin)?;
            
            // 验证是否为成员
            ensure!(
                pallet_society::Members::<T>::contains_key(&who),
                Error::<T>::NotMember
            );
            
            // 存储消息
            Messages::<T>::append(&who, message);
            
            // 奖励5个代币
            T::Currency::deposit_creating(&who, 5u32.into());
            
            // 触发事件
            Self::deposit_event(Event::MessagePosted(who));
            Ok(())
        }
        
        /// 提升成员等级
        #[pallet::weight(5_000)]
        pub fn promote_member(origin: OriginFor<T>, target: T::AccountId) -> DispatchResult {
            ensure_root(origin)?;
            
            // 获取当前等级
            let current_rank = MemberRank::<T>::get(&target);
            let new_rank = current_rank.saturating_add(1);
            
            // 更新等级
            MemberRank::<T>::insert(&target, new_rank);
            
            // 奖励10个代币
            T::Currency::deposit_creating(&target, 10u32.into());
            
            Self::deposit_event(Event::MemberPromoted(target, new_rank));
            Ok(())
        }
    }
}

// 3. 自定义奖励机制实现
impl<T: Config> OnReapAccount<T::AccountId> for Pallet<T> {
    fn on_reap_account(who: &T::AccountId) {
        // 检查是否是活跃成员
        if pallet_society::Members::<T>::contains_key(who) {
            // 根据活跃度和等级计算奖励
            let rank = MemberRank::<T>::get(who);
            let message_count = Messages::<T>::decode_len(who).unwrap_or(0);
            let reward = (rank as u32 * 2 + message_count as u32).into();
            
            // 发放奖励
            let _ = T::Currency::deposit_creating(who, reward);
        }
    }
}

// 4. 使用示例
#[cfg(test)]
mod tests {
    use super::*;
    use frame_support::{assert_ok, assert_noop};
    
    #[test]
    fn test_society_workflow() {
        new_test_ext().execute_with(|| {
            // 初始化
            let alice = 1;
            let bob = 2;
            
            // Alice申请成为候选人
            assert_ok!(Society::bid(
                Origin::signed(alice),
                100  // 押金100
            ));
            
            // Bob作为现有成员投票
            assert_ok!(Society::vote(
                Origin::signed(bob),
                alice,
                true  // 赞成
            ));
            
            // Alice成为成员后发布消息
            assert_ok!(SocialNetwork::post_message(
                Origin::signed(alice),
                b"Hello Society!".to_vec()
            ));
            
            // 验证消息存储
            assert_eq!(
                SocialNetwork::messages(alice),
                vec![b"Hello Society!".to_vec()]
            );
            
            // 提升Alice等级
            assert_ok!(SocialNetwork::promote_member(
                Origin::root(),
                alice
            ));
            
            // 验证等级提升
            assert_eq!(SocialNetwork::member_rank(alice), 1);
        });
    }
}

代码说明:

  1. runtime集成:配置了pallet-society的基本参数,包括押金金额、惩罚机制等

  2. 社交网络扩展

    • 实现了消息发布功能post_message
    • 添加了成员等级系统MemberRank
    • 每个社交行为都会获得代币奖励
  3. 奖励机制

    • 基础奖励:发布消息奖励5个代币
    • 等级奖励:升级奖励10个代币
    • 活跃度奖励:账户回收时根据等级和消息数发放奖励
  4. 治理功能

    • 成员投票机制
    • 只有root账户可以提升成员等级
    • 所有操作都需要成员身份验证
  5. 测试用例:展示了完整的从申请加入、投票、发消息到升级的流程

这个示例展示了如何基于pallet-society构建一个完整的去中心化社交网络,包含成员管理、激励机制和等级系统等核心功能。

回到顶部