ethereum(以太坊)(十二)--应用(二)__投票(基础总和)

Posted on 2018-11-20 10:48  eilinge  阅读(312)  评论(0编辑  收藏  举报
编写应用合约之前,先弄清它的逻辑,有助于我们更好的部署合约 

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