智能合约经典综合案例--投票

描述

主席可以赋予其他人投票权,每个人只有一张选票,每个人可以将自己的票授予委托人。

pragma solidity ^0.5.10;

contract Ballot{
    // 投票人结构体
    struct Voter{
        uint weight;  // 权重,1为有一张选票,0为没有
        bool voted;  // 是否投票
        uint voteTo;  // 投给哪个提案(序号)
        address delegate;  // 委托人地址
    }
    // 提案结构体
    struct Proposal{
        uint voteCount; // 该提案获得的选票数量
    }
    
    mapping(address => Voter) voters;  // 映射 voters: 将地址与投票人联系起来
    Proposal[] proposals;  // 定义变长数组proposals,存储不同的提案
    address public chairperson;  // 主席,可以赋予投票权
    
    // 构造函数,传入提案数量
    constructor(uint _proposalCount) public{
        chairperson = msg.sender;  // 构造函数的调用者是主席,也就是合约的调用者
        voters[chairperson].weight = 1;  // 赋予主席投票权
        proposals.length = _proposalCount;  // 设置变长数组的长度等于提案数量
    }
    
    // 主席赋予投票权
    function giveRightToVote(address voter) public{
        require(msg.sender == chairperson);
        require(voters[voter].voted == false);  // 需要没有投过票
        require(voters[voter].weight == 0);  // 需要没有投票权
        voters[voter].weight = 1;
    }
    
    // 将选票委托其他人
    function delegate(address delegateTo) public{
        Voter storage sender = voters[msg.sender];
        require(!sender.voted);  // 需要没有投过票
        require(delegateTo != address(0));  // 被委托人的地址不能为0
        while(voters[delegateTo].delegate != address(0) && voters[delegateTo].delegate != msg.sender){
            delegateTo = voters[delegateTo].delegate;  // 被委托人的委托人也是我的委托人
        }
        require(delegateTo != msg.sender);
        sender.voted = true;
        sender.delegate = delegateTo;
        Voter storage to = voters[delegateTo];
        // 如果委托人投过票
        if(to.voted){
            proposals[to.voteTo].voteCount += sender.weight;  // 将自己的选票加到给委托人投的提案选票上
        // 如果委托人没投过票   
        }else{
            proposals[to.voteTo].voteCount += to.weight;
            // to.weight += sender.weight;
        }
        
    }
    
    // 投票,to代表被投的提案序号
    function vote(uint _voteTo) public{
        Voter storage sender = voters[msg.sender];
        require(!sender.voted);  // 判断是否投过票
        sender.voted = true;  // 已投票
        sender.voteTo = _voteTo;
        proposals[_voteTo].voteCount += sender.weight;
    }
    
    // 计算选票,选出获胜提案
    function winningPro() public view returns(uint _winPro){
        uint winProNum = 0;
        for (uint proNum = 1; proNum < proposals.length; proNum++){
            if(proposals[proNum].voteCount > proposals[winProNum].voteCount){
                winProNum = proNum;
            }
        }
        return winProNum;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值