///! # 投票系统 ///! ///! Voting System ///! 提供提案投票、权重计算和委托投票功能 ///! ///! **版本**: v1.0 ///! **模块**: charter-std/governance/voting.ch use utils::math::{safe_add, safe_sub, safe_mul, safe_div}; use utils::crypto::sha3_384_hash; // ============================================================================ // 投票枚举 // ============================================================================ /// 投票选项 pub enum VoteOption { /// 赞成 For, /// 反对 Against, /// 弃权 Abstain } /// 投票状态 pub enum VoteStatus { /// 待开始 Pending, /// 进行中 Active, /// 已结束 Ended, /// 已取消 Cancelled } /// 投票结果 pub enum VoteResult { /// 未决定 Undecided, /// 通过 Passed, /// 未通过 Failed, /// 法定人数不足 QuorumNotReached } // ============================================================================ // 投票结构 // ============================================================================ /// 投票信息 struct Vote { /// 投票ID vote_id: Hash, /// 提案ID proposal_id: Hash, /// 标题 title: String, /// 描述 description: String, /// 创建者 creator: Address, /// 开始时间 start_time: Timestamp, /// 结束时间 end_time: Timestamp, /// 赞成票数 votes_for: u256, /// 反对票数 votes_against: u256, /// 弃权票数 votes_abstain: u256, /// 总投票权重 total_weight: u256, /// 法定人数(基点) quorum: u16, /// 通过阈值(基点) threshold: u16, /// 投票状态 status: VoteStatus, /// 投票结果 result: VoteResult, /// 是否允许委托 allow_delegation: bool } /// 投票记录 struct VoteRecord { /// 投票者 voter: Address, /// 投票ID vote_id: Hash, /// 投票选项 option: VoteOption, /// 投票权重 weight: u256, /// 投票时间 timestamp: Timestamp, /// 是否通过委托 is_delegated: bool, /// 委托人(如果是委托投票) delegator: Option
} /// 委托记录 struct Delegation { /// 委托人 delegator: Address, /// 被委托人 delegate: Address, /// 委托权重 weight: u256, /// 委托时间 delegated_at: Timestamp, /// 过期时间(可选) expires_at: Option } /// 投票权重快照 struct WeightSnapshot { /// 地址 address: Address, /// 权重 weight: u256, /// 快照时间 snapshot_at: Timestamp } // ============================================================================ // 投票事件 // ============================================================================ /// 投票创建事件 event VoteCreated { vote_id: Hash, proposal_id: Hash, title: String, creator: Address, start_time: Timestamp, end_time: Timestamp, quorum: u16, threshold: u16 } /// 投票提交事件 event VoteCast { vote_id: Hash, voter: Address, option: VoteOption, weight: u256, timestamp: Timestamp } /// 投票结束事件 event VoteEnded { vote_id: Hash, result: VoteResult, votes_for: u256, votes_against: u256, votes_abstain: u256, timestamp: Timestamp } /// 委托事件 event DelegationCreated { delegator: Address, delegate: Address, weight: u256, timestamp: Timestamp } /// 取消委托事件 event DelegationRevoked { delegator: Address, delegate: Address, timestamp: Timestamp } // ============================================================================ // 投票系统 // ============================================================================ /// 投票系统 certificate VotingSystem { /// 投票 (vote_id => vote) let _votes: Map; /// 投票记录 (vote_id => voter => record) let _vote_records: Map>; /// 委托 (delegator => delegate => delegation) let _delegations: Map>; /// 权重快照 (vote_id => address => snapshot) let _weight_snapshots: Map>; /// 治理代币地址 let _governance_token: Address; /// 管理员地址 let _admin: Address; /// 默认法定人数(基点) let _default_quorum: u16; /// 默认通过阈值(基点) let _default_threshold: u16; /// 最小投票期限(秒) let _min_voting_period: Duration; /// 最大投票期限(秒) let _max_voting_period: Duration; // ========== 构造函数 ========== constructor( governance_token: Address, default_quorum: u16, default_threshold: u16, min_period: Duration, max_period: Duration ) { require(!governance_token.is_zero(), "Invalid governance token"); require(default_quorum <= 10000, "Invalid quorum"); require(default_threshold <= 10000, "Invalid threshold"); require(min_period > 0, "Min period must be positive"); require(max_period > min_period, "Max period must be > min period"); self._governance_token = governance_token; self._admin = msg.sender; self._default_quorum = default_quorum; self._default_threshold = default_threshold; self._min_voting_period = min_period; self._max_voting_period = max_period; } // ========== 投票管理 ========== /// 创建投票 /// /// # 参数 /// - `proposal_id`: 提案ID /// - `title`: 标题 /// - `description`: 描述 /// - `duration`: 投票期限(秒) /// - `quorum`: 法定人数(基点,0表示使用默认值) /// - `threshold`: 通过阈值(基点,0表示使用默认值) /// - `allow_delegation`: 是否允许委托 /// /// # 返回 /// - `Hash`: 投票ID pub fn create_vote( proposal_id: Hash, title: String, description: String, duration: Duration, quorum: u16, threshold: u16, allow_delegation: bool ) -> Hash { require(!title.is_empty(), "Title required"); require(duration >= self._min_voting_period, "Duration too short"); require(duration <= self._max_voting_period, "Duration too long"); let final_quorum = if quorum == 0 { self._default_quorum } else { require(quorum <= 10000, "Invalid quorum"); quorum }; let final_threshold = if threshold == 0 { self._default_threshold } else { require(threshold <= 10000, "Invalid threshold"); threshold }; // 生成投票ID let vote_id = self._generate_vote_id(proposal_id, msg.sender); let start_time = block.timestamp; let end_time = block.timestamp + duration; let vote = Vote { vote_id: vote_id, proposal_id: proposal_id, title: title.clone(), description: description, creator: msg.sender, start_time: start_time, end_time: end_time, votes_for: 0, votes_against: 0, votes_abstain: 0, total_weight: 0, quorum: final_quorum, threshold: final_threshold, status: VoteStatus::Active, result: VoteResult::Undecided, allow_delegation: allow_delegation }; self._votes[vote_id] = vote; emit VoteCreated { vote_id: vote_id, proposal_id: proposal_id, title: title, creator: msg.sender, start_time: start_time, end_time: end_time, quorum: final_quorum, threshold: final_threshold }; return vote_id; } /// 投票 /// /// # 参数 /// - `vote_id`: 投票ID /// - `option`: 投票选项 /// /// # 返回 /// - `bool`: 是否成功 pub fn cast_vote(vote_id: Hash, option: VoteOption) -> bool { require(self._votes.contains_key(vote_id), "Vote not found"); let mut vote = self._votes[vote_id]; require(vote.status == VoteStatus::Active, "Vote not active"); require(block.timestamp >= vote.start_time, "Vote not started"); require(block.timestamp < vote.end_time, "Vote ended"); // 检查是否已投票 if let Some(records) = self._vote_records.get(vote_id) { require(!records.contains_key(msg.sender), "Already voted"); } // 获取投票权重(实际需要查询治理代币余额) let weight = self._get_voting_weight(msg.sender, vote_id); require(weight > 0, "No voting power"); // 记录投票 let record = VoteRecord { voter: msg.sender, vote_id: vote_id, option: option, weight: weight, timestamp: block.timestamp, is_delegated: false, delegator: None }; if !self._vote_records.contains_key(vote_id) { self._vote_records[vote_id] = Map::new(); } self._vote_records[vote_id][msg.sender] = record; // 更新投票统计 match option { VoteOption::For => { vote.votes_for = safe_add(vote.votes_for, weight); }, VoteOption::Against => { vote.votes_against = safe_add(vote.votes_against, weight); }, VoteOption::Abstain => { vote.votes_abstain = safe_add(vote.votes_abstain, weight); } } vote.total_weight = safe_add(vote.total_weight, weight); self._votes[vote_id] = vote; emit VoteCast { vote_id: vote_id, voter: msg.sender, option: option, weight: weight, timestamp: block.timestamp }; return true; } /// 结束投票 /// /// # 参数 /// - `vote_id`: 投票ID /// /// # 返回 /// - `VoteResult`: 投票结果 pub fn end_vote(vote_id: Hash) -> VoteResult { require(self._votes.contains_key(vote_id), "Vote not found"); let mut vote = self._votes[vote_id]; require(vote.status == VoteStatus::Active, "Vote not active"); require(block.timestamp >= vote.end_time, "Vote not ended yet"); // 计算结果 let result = self._calculate_result(vote_id); vote.status = VoteStatus::Ended; vote.result = result; self._votes[vote_id] = vote; emit VoteEnded { vote_id: vote_id, result: result, votes_for: vote.votes_for, votes_against: vote.votes_against, votes_abstain: vote.votes_abstain, timestamp: block.timestamp }; return result; } /// 取消投票 /// /// # 参数 /// - `vote_id`: 投票ID /// /// # 返回 /// - `bool`: 是否成功 pub fn cancel_vote(vote_id: Hash) -> bool { require(self._votes.contains_key(vote_id), "Vote not found"); let mut vote = self._votes[vote_id]; require( msg.sender == vote.creator || msg.sender == self._admin, "Not authorized" ); require(vote.status == VoteStatus::Active, "Vote not active"); vote.status = VoteStatus::Cancelled; self._votes[vote_id] = vote; return true; } // ========== 委托投票 ========== /// 委托投票权 /// /// # 参数 /// - `delegate`: 被委托人 /// - `expires_at`: 过期时间(可选) /// /// # 返回 /// - `bool`: 是否成功 pub fn delegate_vote( delegate: Address, expires_at: Option ) -> bool { require(!delegate.is_zero(), "Invalid delegate"); require(delegate != msg.sender, "Cannot delegate to self"); if let Some(expiry) = expires_at { require(expiry > block.timestamp, "Invalid expiry time"); } // 获取委托权重(实际需要查询治理代币余额) let weight = self._get_base_voting_weight(msg.sender); require(weight > 0, "No voting power"); let delegation = Delegation { delegator: msg.sender, delegate: delegate, weight: weight, delegated_at: block.timestamp, expires_at: expires_at }; if !self._delegations.contains_key(msg.sender) { self._delegations[msg.sender] = Map::new(); } self._delegations[msg.sender][delegate] = delegation; emit DelegationCreated { delegator: msg.sender, delegate: delegate, weight: weight, timestamp: block.timestamp }; return true; } /// 撤销委托 /// /// # 参数 /// - `delegate`: 被委托人 /// /// # 返回 /// - `bool`: 是否成功 pub fn revoke_delegation(delegate: Address) -> bool { require(self._delegations.contains_key(msg.sender), "No delegation"); require( self._delegations[msg.sender].contains_key(delegate), "Delegation not found" ); self._delegations[msg.sender].remove(delegate); emit DelegationRevoked { delegator: msg.sender, delegate: delegate, timestamp: block.timestamp }; return true; } /// 使用委托权投票 /// /// # 参数 /// - `vote_id`: 投票ID /// - `option`: 投票选项 /// - `delegator`: 委托人 /// /// # 返回 /// - `bool`: 是否成功 pub fn cast_delegated_vote( vote_id: Hash, option: VoteOption, delegator: Address ) -> bool { require(self._votes.contains_key(vote_id), "Vote not found"); let mut vote = self._votes[vote_id]; require(vote.allow_delegation, "Delegation not allowed"); require(vote.status == VoteStatus::Active, "Vote not active"); require(block.timestamp >= vote.start_time, "Vote not started"); require(block.timestamp < vote.end_time, "Vote ended"); // 检查委托 require(self._delegations.contains_key(delegator), "No delegation"); require( self._delegations[delegator].contains_key(msg.sender), "Not delegated to you" ); let delegation = self._delegations[delegator][msg.sender]; // 检查是否过期 if let Some(expiry) = delegation.expires_at { require(block.timestamp < expiry, "Delegation expired"); } // 检查委托人是否已投票 if let Some(records) = self._vote_records.get(vote_id) { require(!records.contains_key(delegator), "Delegator already voted"); } let weight = delegation.weight; // 记录投票 let record = VoteRecord { voter: msg.sender, vote_id: vote_id, option: option, weight: weight, timestamp: block.timestamp, is_delegated: true, delegator: Some(delegator) }; if !self._vote_records.contains_key(vote_id) { self._vote_records[vote_id] = Map::new(); } self._vote_records[vote_id][delegator] = record; // 更新投票统计 match option { VoteOption::For => { vote.votes_for = safe_add(vote.votes_for, weight); }, VoteOption::Against => { vote.votes_against = safe_add(vote.votes_against, weight); }, VoteOption::Abstain => { vote.votes_abstain = safe_add(vote.votes_abstain, weight); } } vote.total_weight = safe_add(vote.total_weight, weight); self._votes[vote_id] = vote; emit VoteCast { vote_id: vote_id, voter: delegator, option: option, weight: weight, timestamp: block.timestamp }; return true; } // ========== 查询函数 ========== /// 获取投票信息 /// /// # 参数 /// - `vote_id`: 投票ID /// /// # 返回 /// - `Vote`: 投票信息 pub fn get_vote(vote_id: Hash) -> Vote { require(self._votes.contains_key(vote_id), "Vote not found"); return self._votes[vote_id]; } /// 获取投票记录 /// /// # 参数 /// - `vote_id`: 投票ID /// - `voter`: 投票者地址 /// /// # 返回 /// - `Option`: 投票记录 pub fn get_vote_record(vote_id: Hash, voter: Address) -> Option { return self._vote_records.get(vote_id) .and_then(|m| m.get(voter)); } /// 获取委托信息 /// /// # 参数 /// - `delegator`: 委托人 /// - `delegate`: 被委托人 /// /// # 返回 /// - `Option`: 委托信息 pub fn get_delegation( delegator: Address, delegate: Address ) -> Option { return self._delegations.get(delegator) .and_then(|m| m.get(delegate)); } /// 获取投票权重 /// /// # 参数 /// - `voter`: 投票者地址 /// - `vote_id`: 投票ID /// /// # 返回 /// - `u256`: 投票权重 pub fn get_voting_weight(voter: Address, vote_id: Hash) -> u256 { return self._get_voting_weight(voter, vote_id); } /// 检查是否已投票 /// /// # 参数 /// - `vote_id`: 投票ID /// - `voter`: 投票者地址 /// /// # 返回 /// - `bool`: 是否已投票 pub fn has_voted(vote_id: Hash, voter: Address) -> bool { return self._vote_records.get(vote_id) .map(|m| m.contains_key(voter)) .unwrap_or(false); } // ========== 内部函数 ========== /// 生成投票ID fn _generate_vote_id(proposal_id: Hash, creator: Address) -> Hash { let mut data = Bytes::new(); data.extend(proposal_id.as_bytes()); data.extend(creator.as_bytes()); data.extend(block.timestamp.to_bytes()); data.extend(tx.hash.as_bytes()); return sha3_384_hash(data); } /// 获取基础投票权重(不包括委托) fn _get_base_voting_weight(voter: Address) -> u256 { // 实际需要查询治理代币余额 // 这里简化处理 return 100; } /// 获取投票权重(包括委托) fn _get_voting_weight(voter: Address, vote_id: Hash) -> u256 { // 检查是否有快照 if let Some(snapshots) = self._weight_snapshots.get(vote_id) { if let Some(snapshot) = snapshots.get(voter) { return snapshot.weight; } } // 获取基础权重 let base_weight = self._get_base_voting_weight(voter); // 计算委托给该投票者的权重 let mut delegated_weight = 0u256; // 实际需要遍历所有委托记录 // 这里简化处理 return safe_add(base_weight, delegated_weight); } /// 计算投票结果 fn _calculate_result(vote_id: Hash) -> VoteResult { let vote = self._votes[vote_id]; // 检查法定人数 // 实际需要查询治理代币总供应量 let total_supply = 10000u256; // 简化 let participation = safe_mul(vote.total_weight, 10000) / total_supply; if participation < vote.quorum as u256 { return VoteResult::QuorumNotReached; } // 计算赞成票比例 let valid_votes = safe_add(vote.votes_for, vote.votes_against); if valid_votes == 0 { return VoteResult::Failed; } let approval_rate = safe_mul(vote.votes_for, 10000) / valid_votes; if approval_rate >= vote.threshold as u256 { return VoteResult::Passed; } else { return VoteResult::Failed; } } // ========== 管理函数 ========== /// 设置默认法定人数 pub fn set_default_quorum(quorum: u16) -> bool { require(msg.sender == self._admin, "Only admin"); require(quorum <= 10000, "Invalid quorum"); self._default_quorum = quorum; return true; } /// 设置默认通过阈值 pub fn set_default_threshold(threshold: u16) -> bool { require(msg.sender == self._admin, "Only admin"); require(threshold <= 10000, "Invalid threshold"); self._default_threshold = threshold; return true; } }