Coding a Smart World Series
A Voting Smart Contract using Solidity in Ethereum
A voting smart contract application running on the Ethereum network can solve many problems of electronic voting or paper ballot voting, where assigning voting rights to correct persons and prevent manipulation is still a big challenge.
The Voting smart contract I used here is available here but I have made slight changes so as the code runs fine in Remix IDE.
bytes32 vs string
Remix doesn’t allow implicit conversion between
But this still works if you use other development tools like Truffle!
Why Solidity prefers bytes32 to string?
The type bytes32 can hold 32 (raw) bytes. In the assignment bytes32 somevar = “stringliteral”;, the string literal is interpreted in its raw byte form and if you inspect somevar and see a 32-byte hex value, this is just “stringliteral” in hex. The type bytes is similar, only that it can change its length.
string type is basically identical to bytes only that it is assumed to hold the UTF-8 encoding of a real string. Since string stores the data in UTF-8 encoding it is quite expensive to compute the number of characters in the string (the encoding of some characters takes more than a single byte). This just means more gas cost in the Ethereum network and hence not recommended for the efficiency of the code. I have replaced bytes32 type with string in the code below for convenience.
More about the Voting Smart Contract
All the generic attributes of blockchain easily come with the Voting Smart Contract like consensus, provenance, immutability, and finality to name a few.
Every single address in the Ethereum network only gets one voting right other than the delegated voting rights. So if the address in Ethereum Network can be tied to a unique social id of the voter this will prevent any voting manipulation.
Two important components or state variables of Voting Contract are Proposal and Voter
Proposal- Proposal is a complex type of Struct that has a string type which gives a short description of the proposal to vote for. This can be anything from a candidate name to a political party to anything you would like the voters to vote for. Proposal also has a uint type which gives the total accumulated vote for that proposal
Voter- Voter is another complex Struct type with variables:
uint weight- The value is added by one whenever the voter gets delegated to vote for someone else.
bool voted- True or False value based on his/her voting status. A voter can only vote once for a proposal.
address delegate- Address of the person the voter is delegated to vote
uint vote- The index of the voted proposal. This will keep track of the proposal voted by the voter.
Important functionalities of Voting smart contract
constructor(string memory proposalNames) public:- The Ballot contract has a constructor that loads a string array of proposalNames which can be candidate list, items for voting, etc.
function giveRightToVote(address voter) public:- This function give the ‘voter’ to right on this Ballot contract. The function can only be executed by the chairperson or technically — the contract owner. Once the right is given to the voter ‘weight’ attribute is incremented by one.
function delegate(address to) public:- This is a key function where a valid voter can delegate his voting right to someone else so that he can vote for him. The way it is implemented in this contract is the delegator will lose his/her voting rights once he/she delegates and the vote will be counted as an additional vote for the item which the delegate votes for.
function vote(uint proposal) public:- This is the function where the actual casting of vote occurs and every address can only cast the vote one time. This will help to prevent double-voting.
function winningProposal() public view:- This function is a read-only function that gives the voting results and the proposal which got the maximum vote. If there is a tie situation there is no winning proposal.
function winnerName() public view:- This function is derived from the winningProposal()and gives the name of the winning candidate and the number of votes he/she got.
This is the entire code here. Copy-paste to a remix browser window and follow the screenshots to run.
This is how Remix Screen looks
Pick up the first account address from Account drop-down and Deploy the smart contract by providing an argument. For E.g. [“Ted”,”Beto”]
This is a string array of proposalNames.
Note: Always ensure to put double quotes for string, address arguments, and separate arguments with commas.
You can see the contract is deployed with the first Account and hence that will become the smart contract owner account or in this case the chairperson account. You have four other voter accounts left. You can invoke any of the functions below by clicking on the respective function buttons and providing the required arguments.
Let me know if you have any questions! I will try to answer it.