Writing of Voting DAPP

pragma solidity ^ 0.4.26;
pragma experimental ABIEncoderV2;
contract Ballot {
    
    
    string public name; //投票的名称,name of the Ballot
    address public chairman; //合约拥有者的地址
    bool public closed; // 记录投票是否结束
 
    // 获胜票数比例
    uint public proportion; // 获胜时得票数占总票数的最低比例, 例如50%就赋值为50
    uint public totalVotes; // 总票数
 
    // 加投票权集合, 表示哪些人有投票权
    address[] voters;
    struct Proposal {
    
     // 候选人信息的结构体
        string name;
        uint voteCount;  // 候选人的得票数
    }
    Proposal[] public proposals;  // 候选人的结构体(可变长)数组
    mapping(address => bool) voteRecords; // 投票者是否投票(默认false)
    uint[] winningProposals = [0];
    string [] winningProposalsName; // 记录winning候选人名字的数组
 
    constructor(string _name, string[] _proposals, uint _proportion, address[] _voters) public {
    
     // 合约的构造函数
        chairman = msg.sender; // 记录合约的拥有者
        closed = false; // 合约默认处于打开
        name = _name; // 投票的名称,如 "选举学生会主席"
        for(uint i = 0; i < _proposals.length; i++) {
    
    
            proposals.push(Proposal({
    
    
                name: _proposals[i],
                voteCount: 0
            }));
        }
        proportion = _proportion;
        voters = _voters;
        totalVotes = voters.length;
    }
 
 
    function setChairman(address _chairman) external {
    
     // 更换合约拥有者时用
        chairman = _chairman;
    }
 
    function vote(uint proposal) public {
    
     //给候选人投票, 需传入候选人的序号及投票者的地址
        address voterAddress = msg.sender;
        require(!closed, "the ballot is already closed."); // 保证合约没有关闭,即投票没有结束
        // 看投票者的地址是否在合法名单中
        bool legal = false;
        for(uint i = 0; i < voters.length; i++){
    
    
            if(voters[i] == voterAddress){
    
    
                legal = true;
                break;
            }
        }
        require(legal, "the voter is illeagal!");
        require(proposal < proposals.length, "the prosal is invalid!");
        require(!voteRecords[voterAddress], "Already voted."); // 保证投票者没有投过票
        voteRecords[voterAddress] = true;
 
        proposals[proposal].voteCount += 1; // 候选人得票数加一
    }
 
    function closeBallot() public {
    
     // 关闭投票
        require(chairman == msg.sender, "only the chairman can close the ballot."); // 只有拥有者可以关闭投票
        closed = true;
    }
 
    function getWinningProposals() internal {
    
     //统计投票的获胜者
        winningProposals.length = 0;
        uint winningVoteCount = 0;
        for(uint i = 0; i < proposals.length; i++) {
    
    
            if(proposals[i].voteCount * 100 / totalVotes >= proportion) {
    
    
                winningProposals.push(i);
            }
        }
        if(winningProposals.length == 0){
    
    
        for(i = 0; i < proposals.length; i++){
    
    
            if(proposals[i].voteCount > winningVoteCount){
    
    
                winningVoteCount = proposals[i].voteCount;
            }
        }
        for(i = 0; i < proposals.length; i++){
    
    
            if(proposals[i].voteCount == winningVoteCount){
    
    
                winningProposals.push(i);
            }
        }
    }
    }
 
    function winnerName() public view returns (string[] ) {
    
     // 返回得票数最高的候选人的名字
        require(closed, "only when the ballot is closed can you examine the winner");
        getWinningProposals();
        for(uint i = 0; i < winningProposals.length; i++){
    
    
            winningProposalsName.push(proposals[winningProposals[i]].name);
        }
        return winningProposalsName;
    }
 
    function getProposalNumber() public view returns (uint){
    
    
        return proposals.length;
    }
}

Demonstration:
1) Deploy the contract and fill in the parameters: voting name, candidate, voter and winning vote ratio.
insert image description here

2) Voters call the vote function and pass in the candidate's id to vote.
insert image description here

3) After the voting ends, the administrator ends the voting.
insert image description here

4) The winners can be viewed by calling the winnerName function.
insert image description here

Guess you like

Origin blog.csdn.net/mlynb/article/details/127816709