// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Ballot2{
struct Voter{
uint weight; //投票权重
bool voted; //标志位,标志是否投过票
uint vote; //投票投给谁
address delegate; //投票对象的地址
}
struct Proposal{ //提案
bytes32 name; // 提案名称(最多 32 个字节)
uint voteCount; //提案获得的票数
}
address public chairperson; //定义一个主席
Proposal[] proposals; //保存所有的提案数组
//地址和投票的映射
mapping(address=>Voter) voters;
constructor(bytes32[] memory proposalNames) {
chairperson=msg.sender; //初始化主席是创建人
voters[chairperson].weight=1; //初始化主席的权重为1
for (uint i = 0; i < proposalNames.length; i++) {
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
function giveRightToVote(address voter) public{ //主席投票权函数
require(msg.sender==chairperson); //要求函数调用人是主席
require(voters[voter].voted==false); //要求他的投票标志位为false,没有投过票给别人
require(voters[voter].weight==0); //没有投票权
voters[voter].weight=1; //?初始时已经是1了啊? 赋给投票权
}
function delegate(address to) public{ //代理函数,将自己的投票委托给“to”选民
Voter storage sender = voters[msg.sender];
require(!sender.voted); //自己没有投过票
require(to !=msg.sender); //委托对象不能是自己
while(voters[to].delegate!=address(0)&&voters[to].delegate!=msg.sender){ //被委托人不能是0地址,被委托人不能再委托给第一个委托人
to=voters[to].delegate;
}
sender.voted=true; //投票标志为真
sender.delegate=to; //投票地址为to
Voter storage delegateTo=voters[to]; //??
if(delegateTo.voted){ //如果委托人已经投过票
proposals[delegateTo.vote].voteCount+=sender.weight; //委托人的票数增加,票数加上他的权重
}else{
delegateTo.weight += sender.weight; //没有投过票,增加委托人的投票权重
}
}
function vote(uint proposal)public{ //对提案投票函数,投自己和被委托的票
Voter storage sender = voters[msg.sender];
require(sender.weight!=0); //有投票权重
require(!sender.voted); //没有投过票
sender.voted=true;
sender.vote=proposal;
//注意:proposal是数组 不能溢出 否则会回滚
proposals[proposal].voteCount+=sender.weight; //提案增加票数
}
function winningProposal() public view returns(uint winningProposal_){ //胜利的方案 只读 加view
uint winningCount=0; //winning提案票数 初始为0
//循环所有提案,找出票数大于winning的提案,并赋值给winning
for(uint p=0;p<proposals.length;p++){
if(proposals[p].voteCount > winningCount){
winningCount=proposals[p].voteCount;
winningProposal_=p;
}
}
}
function winnerName() public view returns(bytes32 winnerName_){ //胜利的方案名
winnerName_ = proposals[winningProposal()].name;
}
}
solidity学习-投票
最新推荐文章于 2024-05-31 09:44:20 发布