DEV Community

Cover image for Ethereum Voting Machine
Sandeep Kumar Patel
Sandeep Kumar Patel

Posted on

Ethereum Voting Machine

Remix-IDE Or Hardhat

  • You can use Remix IDE if you want to test.

  • Create a folder and open VS Code.

    npm init
    npm install --dev hardhat
Enter fullscreen mode Exit fullscreen mode
  • Select * Create javaScript project *

  • Then create a new file Voting.sol inside contracts folder

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;

contract Voting {
    uint totalCandidate;
    uint totalVoter;
    uint totalVoted;
 }
Enter fullscreen mode Exit fullscreen mode
  • Inside the contract
 // create candidate struct to store candidate name , party name, number of votes
struct Candidate {
        bytes32 candidateName;
        bytes32 partyName;
        uint votes;
 }


 // create voter struct
struct Voter {
        uint candidateVoteId;
        bytes32 votedTo;
        bool voted;
        bool eligible;
}

      mapping(uint => Candidate) public candidates;

      mapping(address => Voter) public voters;

Enter fullscreen mode Exit fullscreen mode
  • Only Owner of the contract or Chief of the Election can verify the Voters to vote. So first make the owner
    function VotOwner() public {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function showOwner() public view returns (address) {
        return owner;
    }
Enter fullscreen mode Exit fullscreen mode
  • Chief can also add the Candidates
 function addCandidate(bytes32 _name, bytes32 _party) public onlyOwner {
        uint i = totalCandidate++;
        candidates[i] = Candidate(_name, _party, 0);
 }
Enter fullscreen mode Exit fullscreen mode
  • Verify the Voters by passing the address or wallet address of the voter
function getRightToVote(address voterID) public {
        // check eligible
        require(!voters[voterID].eligible, "Already Eligible");
        require(!voters[voterID].voted, "The voter already voted");
        voters[voterID].eligible = true;
        totalVoter++;
}
Enter fullscreen mode Exit fullscreen mode
  • Verified voters can now vote
 function toVote(uint candidateID) public {
        Voter storage sender = voters[msg.sender];
        require(sender.eligible, "Not Eligible to Vote");
        require(!sender.voted, "Already Voted");

        sender.voted = true;
        sender.votedTo = candidates[candidateID].partyName;
        candidates[candidateID].votes += 1;
        totalVoted += 1;
 }
Enter fullscreen mode Exit fullscreen mode
  • Some view functions
    function votersLeftTOVote() public view returns (uint) {
        return totalVoter - totalVoted;
    }

    function voterVotedTo() public view returns (bytes32) {
        Voter storage sender = voters[msg.sender];
        return sender.votedTo;
    }

    function getNumOfCandidates() public view returns (uint) {
        return totalCandidate;
    }

    function getNumOfVoters() public view returns (uint) {
        return totalVoter;
    }
Enter fullscreen mode Exit fullscreen mode
  • Check the Winner
    function checkWinner() public view returns (uint wins) {
        uint winCount = 0;
        for (uint i = 0; i <= totalCandidate; i++) {
            if (winCount < candidates[i].votes) {
                winCount = candidates[i].votes;
                wins = i;
            }
        }
    }

    function winnerVotes() public view returns (uint vot) {
        vot = candidates[checkWinner()].votes;
    }

    function winnerName() public view returns (bytes32 name) {
        name = candidates[checkWinner()].candidateName;
    }
Enter fullscreen mode Exit fullscreen mode
  • open deploy.js inside scripts folder
const { ethers } = require("hardhat");
require("dotenv").config({ path: ".env" });

async function main() {
  /*
  A ContractFactory in ethers.js is an abstraction used to deploy new smart contracts,
  so verifyContract here is a factory for instances of our Verify contract.
  */
  const verifyContract = await ethers.getContractFactory("Voting");

  // deploy the contract
  const deployedVerifyContract = await verifyContract.deploy();

  await deployedVerifyContract.deployed();

  // print the address of the deployed contract
  console.log("Verify Contract Address:", deployedVerifyContract.address);

  console.log("Sleeping.....");
  // Wait for etherscan to notice that the contract has been deployed
  await sleep(50000);

  // Verify the contract after deploying
  await hre.run("verify:verify", {
    address: deployedVerifyContract.address,
    constructorArguments: [],
  });
}

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// Call the main function and catch if there is any error
main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

Enter fullscreen mode Exit fullscreen mode
  • hardhatconfig.js
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config({ path: ".env" });

const QUICKNODE_HTTP_URL = process.env.QUICKNODE_HTTP_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const POLYGONSCAN_KEY = process.env.POLYGONSCAN_KEY;

module.exports = {
  solidity: "0.8.4",
  networks: {
    mumbai: {
      url: QUICKNODE_HTTP_URL,
      accounts: [PRIVATE_KEY],
    },
  },
  etherscan: {
    apiKey: {
      polygonMumbai: POLYGONSCAN_KEY,
    },
  },
};
Enter fullscreen mode Exit fullscreen mode
  • Compile and Deploy
npx hardhat compile
npx hardhat run scripts/deploy.js --network mumbai
Enter fullscreen mode Exit fullscreen mode
  • If everything goes okay you will get the link to Mumbai PolygonScan in the terminal

Note

  • You can modify the contract as you want.
  • You can add a timer (Election start -> end).
  • github

Top comments (0)