...
DAO 创建的时候,会同时发行一个 NFT,复用 DAO 的类型标识,DAOMemberNFT<X>。该 NFT 创建之后就立刻存入 IdentiferNFT 容器中,和用户绑定。成员加入 DAO 的过程就是领取 DAOMemberNFT 的过程,退出 DAO 的过程就是解除绑定并销毁 NFT 的过程。
关于 IdentiferNFT 的介绍参看 SIP22
DAO SBT
DAO 创建的时候,会同时发行一个 Token,复用 DAO 的类型标识,Token<X>。这个 Token 并不自由流通,而是锁在 DAOMemberNFT 的 Body 中,代表用户在 DAO 中治理投票的权重。不同的 DAO 可以根据自己的场景来映射 SBT,用来代表不同的含义。
...
代码块 | ||
---|---|---|
| ||
module GenesisDAO { struct DAO has key { id: u64, name: vector<u8>, dao_address: address, next_member_id: u64, } /// Configuration of the DAO. struct DAOConfig has copy, drop, store { /// after proposal created, how long use should wait before he can vote (in milliseconds) voting_delay: u64, /// how long the voting window is (in milliseconds). voting_period: u64, /// the quorum rate to agree on the proposal. /// if 50% votes needed, then the voting_quorum_rate should be 50. /// it should between (0, 100]. voting_quorum_rate: u8, /// how long the proposal should wait before it can be executed (in milliseconds). min_action_delay: u64, /// how many STC should be deposited to create a proposal. min_proposal_deposit: u128, } public fun withdraw_token<DAOT: store, PluginT, TokenT: store>(_cap: &DAOWithdrawTokenCap<DAOT, PluginT>, amount: u128): Token<TokenT>;: store>(_cap: &DAOWithdrawTokenCap<DAOT, PluginT>, amount: u128): Token<TokenT>; public fun join_member<DAOT: store, PluginT>(_cap: &DAOMemberCap<DAOT, PluginT>, to_address: address, init_sbt: u128); } |
DAOSBT
DAOMember NFT 的定义以及成员加入时分配 NFT 以及 SBT
代码块 | ||
---|---|---|
| ||
module GenesisDAO{ /// The Dao member NFT metadata struct DaoMember<phantom DaoT> has copy, store, drop { //Member id id: u64, } /// The Dao member NFT Body, hold the SBT token struct DaoMemberBody<phantom DaoT> has store { sbt: Token<DaoT>, } /// Join Dao and get a membership public fun join_member<DaoT: store, PluginT>( _cap: &DaoMemberCap<DaoT, PluginT>, to_address: address, init_sbt: u128) acquires DaoNFTMintCapHolder, DaoTokenMintCapHolder, Dao, MemberEvent { assert!(!is_member<DaoT>(to_address), Errors::already_published(ERR_NOT_ALREADY_MEMBER)); let member_id = next_member_id<DaoT>(); let meta = DaoMember<DaoT>{ id: member_id, }; let dao_address = dao_address<DaoT>(); let token_mint_cap = &borrow_global_mut<DaoTokenMintCapHolder<DaoT>>(dao_address).cap; let sbt = Token::mint_with_capability<DaoT>(token_mint_cap, init_sbt); let body = DaoMemberBody<DaoT>{ sbt, }; //TODO init base metadata let basemeta = NFT::empty_meta(); let nft_mint_cap = &mut borrow_global_mut<DaoNFTMintCapHolder<DaoT>>(dao_address).cap; let nft = NFT::mint_with_cap_v2(dao_address, nft_mint_cap, basemeta, meta, body); IdentifierNFT::grant_to(nft_mint_cap, to_address, nft); let memeber_event = borrow_global_mut<MemberEvent<DaoT>>(dao_address); Event::emit_event(&mut memeber_event.member_join_event_handler, MemberJoinEvent<DaoT> { id : member_id, addr:to_address, |
...
|
...
|
...
sbt: |
...
init_sbt, |
...
|
...
|
...
|
...
|
...
|
...
|
...
}); } } |
...
DAOTemplate
每个 DAO 初始化的时候都会根据这个模版生成一个命名为 XDAO 的 module,并且初始化插件。
...