跳转到主要内容

概述

Council 选举允许代币持有者为候选人投票。得票最多的候选人成为 Council 成员。投票需要锁定代币到 Council 合约中。

选举流程

1

选举开始

选举被发起(需要平台的 EIP-712 签名)。选举有固定的持续时间。
2

投票期

代币持有者授权代币给 Council 合约,然后调用 voteElection() 为候选人投票。代币在选举结束前一直锁定。
3

选举结束

endTime 过后,任何人都可以调用 claimElectionTokens()。第一个调用者触发结算——得票最高的候选人成为 Council 成员。
4

领回代币

所有投票者调用 claimElectionTokens() 取回锁定的代币。

读取选举状态

const council = new ethers.Contract(councilAddress, CouncilV1ABI, provider);

const state = await council.getElectionState(tokenAddress);

console.log("进行中:", state.active);
console.log("结束时间:", new Date(Number(state.endTime) * 1000));
console.log("已结算:", state.finalized);
console.log("席位数:", state.councilSize.toString());
console.log("届期:", state.epoch.toString());

选举状态字段

字段类型说明
activebool选举是否正在进行
endTimeuint256选举结束时间戳(unix 秒)
lastElectionEnduint256上一次选举结束时间
finalizedbool当前/上次选举结果是否已结算
councilSizeuint256Council 席位数
epochuint256选举届期计数器

在选举中投票

投票前,必须先 approve Council 合约转移你的代币。
const tokenContract = new ethers.Contract(tokenAddress, [
  "function approve(address spender, uint256 amount) returns (bool)",
], signer);

const council = new ethers.Contract(councilAddress, CouncilV1ABI, signer);

// 1. 授权代币
const amount = ethers.parseEther("10000");
await (await tokenContract.approve(councilAddress, amount)).wait();

// 2. 为候选人投票
// 可以将代币分配给多个候选人
const votes = [
  { candidate: "0xCandidate1...", amount: ethers.parseEther("6000") },
  { candidate: "0xCandidate2...", amount: ethers.parseEther("4000") },
];

const tx = await council.voteElection(tokenAddress, votes);
await tx.wait();

查看候选人

// 获取前 20 名候选人,按得票数降序排列
const [candidates, voteAmounts] = await council.getTop20Candidates(tokenAddress);

for (let i = 0; i < candidates.length; i++) {
  if (candidates[i] === ethers.ZeroAddress) break;
  console.log(`${candidates[i]}: ${ethers.formatEther(voteAmounts[i])} 票`);
}

// 查询特定候选人的得票数
const votes = await council.getCandidateVotes(tokenAddress, candidateAddress);

选举结束后领回代币

选举结束后(block.timestamp > endTime):
// 第一个调用者触发结算 + 领回
// 后续调用者直接领回代币
const tx = await council.claimElectionTokens(tokenAddress);
await tx.wait();

查看 Council 成员

// 选举结算后
const members = await council.getCouncilMembers(tokenAddress);
console.log("Council 成员:", members);

// 检查某地址是否为 Council 成员
const isMember = await council.isCouncilMember(tokenAddress, someAddress);

事件

事件说明
ElectionStarted(token, endTime, councilSize)选举开始
ElectionVoted(token, voter, totalLocked, candidates, amounts)投出选票
ElectionFinalized(token, councilMembers)选举结果结算
ElectionTokensClaimed(token, voter, amount)投票者领回锁定代币