09 voting case practice


Article directory

Introduction to voting needs

The following contracts are somewhat complex, but show many of the language features of Solidity. It implements a voting contract. Of course, the main problem of electronic voting is how to allocate voting rights to the right people and how to prevent manipulation. We won't solve all the problems here, but at least we will show how to vote by proxy, and at the same time, the counting is automatic and completely transparent.

Our idea is to create a contract for each vote and provide a short name for each option. Then as the creator of the contract, the chairman, will give each individual address a vote.

The person following the address can choose to vote by themselves or delegate to someone they trust, and at the end of the voting time, winningProposal() will return the proposal with the most votes.

Voting initialization

contract VoteDemo{
    
    // Create voter structure (once cast)
    struct Voter{
        address addr;  // Address of voter
        bool vote;  // Store status of votes
        uint amount;   // The default weight is 1
    }
    
    // Create a candidate's structure
    struct Candidate{
        address addr;   // Candidate address
        uint get;   // Votes received
        bool win;   // Does the candidate win
    }
    
    // Mapping to store multiple voters and candidates
    mapping (address => Voter) public voters;
    mapping (address => Candidate) public candidates;
    
    event showData(address);
    
    function initCandidate(address addr) public{
        candidates[addr] = Candidate(addr,0,false);
    }
    
    // Initialize voters
    function initVote(address addr) public{
        // Avoid duplicate initialization
        if(voters[addr].addr != address(0)){
            emit showData(voters[addr].addr);
            // This person has been initialized
            return;
        }
        voters[addr] = Voter({addr:addr,vote:false,amount:1});
    }
}

Voting logic implementation

  1. Smart contract voting: create voters and candidates. By default, everyone can only vote and cannot vote repeatedly
  2. Candidates cannot vote
pragma solidity >=0.6.0 <0.7.0;

contract VoteDemo{
    
    address internal _owner;
    
    // Create constructor
    constructor()public{
       _owner = msg.sender;
    }
    
    // Create voter structure: use bool to represent voting status
    struct Voter{
        address addr; // Address of voter
        bool vote;  //Voting status (limit duplicate voting)
        uint amount;  // The number of votes is 1 by default
    }
    
    // Create a candidate chart
    struct Candidate{
        address addr;   // Candidate address
        uint get;    // Votes received
        bool win;   // Does the candidate win
    }
    
    // A voter can only vote for one candidate, but a candidate can receive more than one voter
    
    // Use mapping to store voters and candidates
    mapping (address => Voter) public voters;
    // Candidate mapping
    mapping (address => Candidate) public candidates;
    
    // Initialize candidates
    function initCandidate(address addr) public{
        candidates[addr] = Candidate(addr,0,false);
    }
    
    event showData(string);
    
    // Initialize voters
    function initVote(address addr) public{
        // Avoid duplicate initialization
        if(voters[addr].addr != address(0)){
            emit showData("This person has been initialized");
            return;
        }
        voters[addr] = Voter({addr:addr,vote:false,amount:1});
    }
    
    // The current function completes the business logic of voting
    // The person who calls the function is the voter. When voting, the address of the candidate needs to be passed in
    function vote(address candidate)public{
         Voter storage v =  voters[msg.sender];
         // Judge that this person did not vote repeatedly and is not a candidate
         if(v.vote || v.addr == candidate){
             emit showData('This person is not eligible to vote!');
             return;
         }
         // Vote for candidates
         candidates[candidate].get += v.amount;
         // Update voter status
         v.vote = true;
    }
    
    // Create decorator
    modifier checkOwner{
        if(msg.sender!=_owner){
            revert();
        }
        _;
    }
    
    // Judge successful voters
    function success(address addr1,address addr2) public checkOwner returns (address) {
        if(candidates[addr1].get > candidates[addr2].get){
            candidates[addr1].win = true;
            return addr1;
        }else{
            candidates[addr2].win = true;
            return addr2;
        }
    }
    
}

Published 137 original articles, won praise 19, visited 20000+
Private letter follow

Posted by ame12 on Tue, 10 Mar 2020 23:10:52 -0700