pragma solidity ^0.4.18; // We have to specify what version of compiler this code will compile with
contract Voting { /* mapping field below is equivalent to an associative array or hash. The key of the mapping is candidate name stored as type bytes32 and value is an unsigned integer to store the vote count */ mapping (bytes32 => uint8) public votesReceived; /* Solidity doesn't let you pass in an array of strings in the constructor (yet). We will use an array of bytes32 instead to store the list of candidates */ bytes32[] public candidateList;
/* This is the constructor which will be called once when you deploy the contract to the blockchain. When we deploy the contract, we will pass an array of candidates who will be contesting in the election */ functionVoting(bytes32[] candidateNames)public{ candidateList = candidateNames; }
// This function returns the total votes a candidate has received so far functiontotalVotesFor(bytes32 candidate)viewpublicreturns(uint8){ require(validCandidate(candidate)); return votesReceived[candidate]; }
// This function increments the vote count for the specified candidate. This // is equivalent to casting a vote functionvoteForCandidate(bytes32 candidate)public{ require(validCandidate(candidate)); votesReceived[candidate] += 1; }
functionvalidCandidate(bytes32 candidate)viewpublicreturns(bool){ for(uint i = 0; i < candidateList.length; i++) { if (candidateList[i] == candidate) { returntrue; } } returnfalse; } }
/* * When you compile and deploy your Voting contract, * truffle stores the abi and deployed address in a json * file in the build directory. We will use this information * to setup a Voting abstraction. We will use this abstraction * later to create an instance of the Voting contract. * Compare this against the index.js from our previous tutorial to see the difference * https://gist.github.com/maheshmurthy/f6e96d6b3fff4cd4fa7f892de8a1a1b4#file-index-js */
let candidates = {"Rama": "candidate-1", "Nick": "candidate-2", "Jose": "candidate-3"}
window.voteForCandidate = function(candidate) { let candidateName = $("#candidate").val(); try { $("#msg").html("Vote has been submitted. The vote count will increment as soon as the vote is recorded on the blockchain. Please wait.") $("#candidate").val("");
/* Voting.deployed() returns an instance of the contract. Every call * in Truffle returns a promise which is why we have used then() * everywhere we have a transaction call */ Voting.deployed().then(function(contractInstance) { contractInstance.voteForCandidate(candidateName, {gas: 140000, from: web3.eth.accounts[0]}).then(function() { let div_id = candidates[candidateName]; return contractInstance.totalVotesFor.call(candidateName).then(function(v) { $("#" + div_id).html(v.toString()); $("#msg").html(""); }); }); }); } catch (err) { console.log(err); } }
$( document ).ready(function() { if (typeof web3 !== 'undefined') { console.warn("Using web3 detected from external source like Metamask") // Use Mist/MetaMask's provider window.web3 = new Web3(web3.currentProvider); } else { console.warn("No web3 detected. Falling back to http://localhost:8545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask"); // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail) window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); }
Voting.setProvider(web3.currentProvider); let candidateNames = Object.keys(candidates); for (var i = 0; i < candidateNames.length; i++) { let name = candidateNames[i]; Voting.deployed().then(function(contractInstance) { contractInstance.totalVotesFor.call(name).then(function(v) { $("#" + candidates[name]).html(v.toString()); }); }) } });