Solidity 投票案例

 

demo.sol(投票合约案例):

pragma solidity ^0.4.21;
pragma experimental ABIEncoderV2;

contract VoteContract {
    
    // 投票人
    struct Voter {
        uint voteNumber;  // 投票给第几个候选人
        bool isVoted;  // 是否投过票
        uint weight;   // 投票权重,初始值为1,被委托后,权重增加
        address delegate;  // 指定代理人(委托别人帮自己投票)。 (帮自己投票的人)
    }
    
    // 候选人
    struct Candidate {
        string name;   // 候选人名字
        uint voteCount;  // 获得的投票数
    }
    
    address public admin;  // 管理员,负责创建合约,授权地址为投票人。
    
    Candidate[] public candidates;   // 候选人集合。 数组下标表示第几号候选人。
    mapping(address => Voter)  public voters;  // 投票人集合
    
    
    // 构造函数。  (部署合约时,需要传入候选人的姓名列表)
    constructor(string[] candidatesNames) public {
        admin = msg.sender;   // 初始化管理员
        
        // 通过传入的候选人名字,初始化候选人集合。
        for(uint i=0; i<candidatesNames.length; i++){
            Candidate memory tmp = Candidate({name:candidatesNames[i], voteCount:0});
            candidates.push(tmp);  // 数组下标表示第几号候选人。
        }
    }
    
    // 定义修饰器
    modifier adminOnly() {
        require(admin == msg.sender);  // 只有管理员才可以执行修饰的函数
        _;
    }
    
    // 授予投票权限(添加投票人)。 (修饰器,只有管理员才能授权)
    function grantVoteRightTo(address addr) adminOnly 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.isVoted) {
            revert();  // 如果没有投票权限或已经投过票,就直接结束执行。
        }
        // 投票
        voter.isVoted = true;
        voter.voteNumber = voteNum;
        candidates[voteNum].voteCount += voter.weight;  // 数组下标表示第几号候选人。
    }
    
    // 投票结果
    function whoWin() view public returns (string, uint) {
        
        string memory winner;
        uint winnerVoteCount;
        
        for(uint i=0; i<candidates.length; i++) {
            if(candidates[i].voteCount > winnerVoteCount) {
                winner = candidates[i].name;
                winnerVoteCount = candidates[i].voteCount;
            }
        }
        return (winner, winnerVoteCount);
    }
    
    // 投票委托
    function delegateFunc(address to) public {
        Voter storage voter = voters[msg.sender];
        
        if(voter.weight<=0 || voter.isVoted) {
            revert();  // 如果没有投票权限或已经投过票,就直接结束执行。
        }
        
        while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) {
            to = voters[to].delegate;  // "递归"代理,寻找最终的代理人
        }
        
        require(msg.sender != to);  // 自己不能代理给自己。
        
        // 进行委托
        voter.isVoted = true;
        voter.delegate = to;
        
        Voter storage finalDelegateVoter = voters[to];
        
        if (finalDelegateVoter.isVoted) {
            candidates[finalDelegateVoter.voteNumber].voteCount += voter.weight;
        } else {
            finalDelegateVoter.weight += voter.weight;
        }
    }
    
    
}

 

相关文章:

  • 2022-12-23
  • 2022-02-26
  • 2022-02-03
  • 2021-08-13
  • 2022-12-23
  • 2021-11-28
  • 2021-09-23
猜你喜欢
  • 2023-02-18
  • 2021-11-19
  • 2021-10-02
  • 2021-12-31
  • 2021-04-16
  • 2022-03-07
  • 2021-12-21
相关资源
相似解决方案