pragma solidity ^0.4.21;
pragma experimental ABIEncoderV2;
contract voter1{
//voter candidate
//["eilinge", "lin" ,"meimei"]
//admin 0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB
//0x14723a09acff6d2a60dcdf7aa4aff308fddc160c 2
//0x583031d1113ad414f02576bd6afabfb302140225 1
//0xdd870fa1b7c4700f2bd7f44238821c26f7392148 0
//投票人
struct Voter{
uint _voterAddr;
uint _weight;
bool _voted;
address delegate;
}
//候选人
struct Candidate{
string candidateName;
uint voterNum;
}
address public admin;
//候选人集合
Candidate[] public candidates;
//投票人集合
mapping(address=>Voter) public voters;
//添加候选人
constructor(string[] candidateNames)public{
admin = msg.sender;
for(uint i;i<candidateNames.length;i++){
Candidate memory canNum = Candidate(candidateNames[i],0);
candidates.push(canNum);
}
}
modifier OnlyAdmin(){
require(admin == msg.sender);
_;
}
//赋予投票权
function giveVoteRight(address addr) OnlyAdmin() public{
if (voters[addr]._weight > 0){
revert();
}
voters[addr]._weight = 1;
}
//进行投票
function vote(uint voteNum) public{
Voter storage voter = voters[msg.sender];
if(voter._weight <= 0 || voter._voted ==true){
revert();
}
voter._voted = true;
voter._voterAddr = voteNum;
candidates[voteNum].voterNum += voter._weight;
}
//设置代理人
function delegateFunc(address to) public{
Voter storage voter = voters[msg.sender];
if(voter._weight <= 0 || voter._voted ==true){
revert();
}
//设置代理人的地址不为空,且不能是自己
while (voters[to].delegate != address(0) && voters[to].delegate !=msg.sender){
to = voters[to].delegate;//新代理人地址
}
//代理人的地址不能是自己
require(msg.sender != to);
voter._voted = true;
voter.delegate = to;
//代理人
Voter storage finalDelegateVoter = voters[to];
//代理人投过票,则在代理人投票的候选人票数上加上自己的权重
if(finalDelegateVoter._voted){
candidates[finalDelegateVoter._voterAddr].voterNum += voter._weight;
}
//代理人未投过票,则在代理人权重加上自己的权重
else{
finalDelegateVoter._weight += voter._weight;
}
}
//查看谁胜出
function whoWin() public constant returns(string,uint){
string winner;
uint winnerVoteCounts;
for (uint i;i>candidates.length;i++){
if (candidates[i].voterNum > winnerVoteCounts){
winnerVoteCounts = candidates[i].voterNum;
winner = candidates[i].candidateName;
}
}
return(winner,winnerVoteCounts);
}
}