pragma solidity ^ 0.4.26;
contract Ballot {
string public name; //投票的名称,name of the Ballot
address public chairman; //合约拥有者的地址
bool public closed; // 记录投票是否结束
// 获胜票数比例
uint public proportion; // 获胜时得票数占总票数的最低比例, 例如50%就赋值为50
uint public totalVotes; // 总票数
// 加投票权集合, 表示哪些人有投票权
address[] voters;
struct Proposal { // 候选人信息的结构体
bytes32 name;
uint voteCount; // 候选人的得票数
}
Proposal[] public proposals; // 候选人的结构体(可变长)数组
mapping(address => bool) voteRecords; // 投票者是否投票(默认false)
uint[] winningProposals = [0];
bytes32[] winningProposalsName; // 记录winning候选人名字的数组
constructor(string _name, bytes32[] _proposals, uint _proportion, address[] _voters) public { // 合约的构造函数
chairman = msg.sender; // 记录合约的拥有者
closed = false; // 合约默认处于打开
name = _name; // 投票的名称,如 "选举学生会主席"
for(uint i = 0; i < _proposals.length; i++) {
proposals.push(Proposal({
name: _proposals[i],
voteCount: 0
}));
}
proportion = _proportion;
voters = _voters;
totalVotes = voters.length;
}
function setChairman(address _chairman) external { // 更换合约拥有者时用
chairman = _chairman;
}
function vote(uint proposal) public { //给候选人投票, 需传入候选人的序号及投票者的地址
address voterAddress = msg.sender;
require(!closed, "the ballot is already closed."); // 保证合约没有关闭,即投票没有结束
// 看投票者的地址是否在合法名单中
bool legal = false;
for(uint i = 0; i < voters.length; i++){
if(voters[i] == voterAddress){
legal = true;
break;
}
}
require(legal, "the voter is illeagal!");
require(proposal < proposals.length, "the prosal is invalid!");
require(!voteRecords[voterAddress], "Already voted."); // 保证投票者没有投过票
voteRecords[voterAddress] = true;
proposals[proposal].voteCount += 1; // 候选人得票数加一
}
function closeBallot() public { // 关闭投票
require(chairman == msg.sender, "only the chairman can close the ballot."); // 只有拥有者可以关闭投票
closed = true;
}
function getWinningProposals() internal { //统计投票的获胜者
winningProposals.length = 0;
uint winningVoteCount = 0;
for(uint i = 0; i < proposals.length; i++) {
if(proposals[i].voteCount * 100 / totalVotes >= proportion) {
winningProposals.push(i);
}
}
if(winningProposals.length == 0){
for(i = 0; i < proposals.length; i++){
if(proposals[i].voteCount > winningVoteCount){
winningVoteCount = proposals[i].voteCount;
}
}
for(i = 0; i < proposals.length; i++){
if(proposals[i].voteCount == winningVoteCount){
winningProposals.push(i);
}
}
}
}
function winnerName() public view returns (bytes32[]) { // 返回得票数最高的候选人的名字
require(closed, "only when the ballot is closed can you examine the winner");
getWinningProposals();
for(uint i = 0; i < winningProposals.length; i++){
winningProposalsName.push(proposals[winningProposals[i]].name);
}
return winningProposalsName;
}
function getProposalNumber() public view returns (uint){
return proposals.length;
}
}
04-27
09-03
838
