solidity学习-投票

// 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;
    }





}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值