801 lines
21 KiB
Plaintext
801 lines
21 KiB
Plaintext
///! # 投票系统
|
||
///!
|
||
///! 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<Address>
|
||
}
|
||
|
||
/// 委托记录
|
||
struct Delegation {
|
||
/// 委托人
|
||
delegator: Address,
|
||
|
||
/// 被委托人
|
||
delegate: Address,
|
||
|
||
/// 委托权重
|
||
weight: u256,
|
||
|
||
/// 委托时间
|
||
delegated_at: Timestamp,
|
||
|
||
/// 过期时间(可选)
|
||
expires_at: Option<Timestamp>
|
||
}
|
||
|
||
/// 投票权重快照
|
||
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<Hash, Vote>;
|
||
|
||
/// 投票记录 (vote_id => voter => record)
|
||
let _vote_records: Map<Hash, Map<Address, VoteRecord>>;
|
||
|
||
/// 委托 (delegator => delegate => delegation)
|
||
let _delegations: Map<Address, Map<Address, Delegation>>;
|
||
|
||
/// 权重快照 (vote_id => address => snapshot)
|
||
let _weight_snapshots: Map<Hash, Map<Address, WeightSnapshot>>;
|
||
|
||
/// 治理代币地址
|
||
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<Timestamp>
|
||
) -> 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<VoteRecord>`: 投票记录
|
||
pub fn get_vote_record(vote_id: Hash, voter: Address) -> Option<VoteRecord> {
|
||
return self._vote_records.get(vote_id)
|
||
.and_then(|m| m.get(voter));
|
||
}
|
||
|
||
/// 获取委托信息
|
||
///
|
||
/// # 参数
|
||
/// - `delegator`: 委托人
|
||
/// - `delegate`: 被委托人
|
||
///
|
||
/// # 返回
|
||
/// - `Option<Delegation>`: 委托信息
|
||
pub fn get_delegation(
|
||
delegator: Address,
|
||
delegate: Address
|
||
) -> Option<Delegation> {
|
||
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;
|
||
}
|
||
}
|