一、整体结构
文档参考: Move版 Snapshot 1.0需求列表
space:空间,一个空间可以理解为一个运营方,负责跟踪提案、投票的全局设置,其包含多个提案,空间中有一些Meta data(头像,描述,主站信息等),DaoSpace用以负责描述空间信息,每个项目方均可通过调用DaoSpace::add来对其进行注册Space。
// DaoSpace.move module DaoSpace { struct Space { voting_delay: u128, // The delay between when a proposal is created, and when the voting starts. A voting_delay of 0 means that as soon as the proposal is created, anyone can vote. A voting_delay of 3600 means that voting will start 3600 seconds after the proposal is created. voting_duration: u128, // The duration of the voting period, i.e. how long people will be able to vote for a proposal. meta_data: vector<u8>, // 空间元数据,编码后存储在链上(可考虑存在链下) } struct NFTMeta { user: address, } struct NFTBody { weight: u128 } struct SpaceCapability { } // 创建 space,一个账号只能创建一个(是否只能一个账户创建一个,待讨论) public fun create(signer: &signer, voting_delay: u128, voting_duration: u128, meta_data: &vector<u8>): SpaceCapability; // 查询 space public fun query(broker: address) : (u128, u128, u128); // 非托管账号 register public fun register(signer: &signer, space_broker: address, cap: &SpaceCapability) : NFT<NFTMeta, NFTBody>; // 非托管账号 unregister public fun unregister(signer: &signer, nft: NFT<NFTMeta, NFTBody>); // NFT 添加权重 public fun add_weight(signer: &signer, nft: &mut NFT<NFTMeta, NFTBody>); // NFT 减少权重 public fun reduce_weight(signer: &signer, nft: &mut NFT<NFTMeta, NFTBody>); }
proposal:提案,即一个提案代表一次投票过程,该部分跟原有的流程类似,但是去掉了TokenType。
// DaoProposal.move module DaoProposal { struct ProposalCapability { proposal_id: u64, } struct Proposal<Action> { ... // 现有的一些结构 proposal_id: u64, voting_system: u8, // 投票类型有单选投票、二次投票、排名投票、加权投票等投票类型 voting_start_time: u64, voting_end_time: u64, voting_block_num: u64, // 投票快照高度 voting_block_root: vector<u8>, // 投票快照高度的root hash action: Option::Option<Action>, // 执行策略的结构参数 } struct Vote { /// vote for the proposal under the `proposer`. proposer: address, /// proposal id. id: u64, choie: u8, // 同意,反对,拒绝 weight: u128, // 投票权重 } public fun create_proposal<Action>(..., space_broker: address, space_id: u64, root_hash: &vector<u8>): ProposalCapability; public fun cast_vote( signer: &signer, proposer_broker: address, id: u64, amount: u128, choice: u8, cap: &ProposalCapability ); public fun extract_strategy<Action>(id: u64) : Action; };
// Dao.move module Dao { use DaoSpace; struct DaoSignerDelegate { cap: SignerCapability, // 托管的签名(这里一旦放进来,就没法再还回去了,且只有一份,没想好是放在space还是放在这里,暂时放这里) } struct DaoSpace { cap: SpaceCapability } struct DaoProposal { cap: ProposalCapability } struct DaoProposalSet { proposal_set: HashSet<u64, DaoProposal> } // 执行策略:转账 struct ExecutionTransferStrategy<phontem TokenT> { amount: u128, to: address, } // 项目方创建space public fun new_space( signer: &signer, voting_delay: u64, voting_period: u64, min_action_delay: u64) { // 项目方托管 SignerCapability 到该合约 // 通过DaoSpace合约创建对应的结构 // 将DaoSpace权限存到当前合约 } // 参与投票方/创建投票方注册到space public fun register_to_space( signer: &signer, broker: address) { // 创建对应的NFT } // 参与投票方/创建投票方注册到space // 方便再上一层的DAO调用 public fun regiter_to_space_get_nft( signer: &signer, broker: address) : Option::Option<NFT<DaoSpace::NFTMeta, DaoSpace::NFTData>> { } // 根据 space_broker 来创建对应的proposal public fun create_proposal<ExecutionStrategy>( signer: &signer, // 创建者 space_broker: u64, // space 代理人 block_num: u64, // 快照高度 root_hash: vector<u8> // 快照根hash ); // 投票 public fun do_vote( signer: &signer, broker: address, id: u64, amount: u128, choice: u8, proof: &vector<u8>, side_nodes: &vector<u8>) { // 证明... // 取本地NFT // 用NFT投票 do_vote_with_nft(broker, id, choice, ); } // 用NFT来投票 // 方便上层DAO来调用 public fun do_vote_with_nft( broker: address, id: u64, choice: u8, nft: Option::Option<NFT<DaoSpace::NFTMeta, DaoSpace::NFTData>> ) { } }
二、流程
参考:
https://github.com/snapshot-labs/sx-core/blob/develop/docs/milestones/1.md snapshot x 合约架构图