{"id":20008286,"url":"https://github.com/bethanyuo/voting-system","last_synced_at":"2026-06-06T18:32:08.105Z","repository":{"id":116556843,"uuid":"278899581","full_name":"bethanyuo/voting-system","owner":"bethanyuo","description":"Create a Simple Voting System application.","archived":false,"fork":false,"pushed_at":"2020-07-12T16:45:00.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-12T14:24:47.244Z","etag":null,"topics":["app","dapp","voting-system"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bethanyuo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-11T16:28:18.000Z","updated_at":"2020-07-12T16:46:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"185e725c-db5d-4e98-adac-8dd19e3ac174","html_url":"https://github.com/bethanyuo/voting-system","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bethanyuo%2Fvoting-system","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bethanyuo%2Fvoting-system/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bethanyuo%2Fvoting-system/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bethanyuo%2Fvoting-system/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bethanyuo","download_url":"https://codeload.github.com/bethanyuo/voting-system/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241446641,"owners_count":19964202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["app","dapp","voting-system"],"created_at":"2024-11-13T07:09:08.164Z","updated_at":"2026-06-06T18:32:08.077Z","avatar_url":"https://github.com/bethanyuo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simple Voting System\nBuild a voting application where you will initialize a set of candidates who will be contesting in the election and then vote for the candidates. The votes will be stored on the blockchain. You will go through the process of implementing the voting contract, deploying to the local test blockchain, and interacting with the contract methods.\n\n## Requirements\n*\t[NodeJS](https://nodejs.org/en/) v13.5.0\n*\tGanache CLI v6.9.1\n*\tTruffle v5.1.17\n*\tSolc v0.5.8\n*\tWindows Build Tools\n```\nnpm install --global --production windows-build-tools\n```\n## Source Code\n[Sample Contract](https://github.com/kingsland-innovation-center/voting-contract/blob/master/voting.sol)\n\n## Create the Smart Contract\n1.\tCreate a new folder named “Voting System”.\n*\tOpen your command prompt and go in the folder. We will now refer to this as your workspace.\n\n2.\tIn your workspace, initialize a truffle and node project:\n```bash\n$ truffle init\n$ npm init\n```\n\n3.\tInstall solc and web3 on your workspace.\n```bash\n$ npm install solc@0.5.8\n$ npm install web3@1.2.6\n```\n4.\tCreate a new contract called Voting.sol and put it in the `contracts/` folder.\n\na.\tImplement a `public` field, which will keep track of each candidate’s votes.\nb.\tImplement a `public array` to store every candidate.\nc.\tImplement a `addCandidate(string)` function, which adds the candidate to an array.\nd.\tImplement a `validCandidate(string)` function, which checks whether the given candidate is contained in the array.\ne.\tImplement a `voteForCandidate(string)` function, which votes for a given candidate.\nf.\tImplement a `totalVotesFor(string)` function, which returns the count of votes for a candidate.\ng.\tTo be able to compare strings we can first hash them with `keccak256()` and compare their hashes. \n\n5.\tIn the migrations folder create file 2_deploy_contracts.js and add the deployment code which will deploy the smart contract.\n \n## Setup the Development Environment\n1.\tInstall `ganache-cli`:\nRemember, you may need administrator permissions if errors occur.\n```bash\n$ npm install –g ganache-cli@6.9.1\n```\n\n2.\tRun `ganache-cli`:\nDo not close this terminal. Let it run in the background as we continue with other tasks.\n```bash\n$ ganache-cli\n```\n \n3.\tOn a new terminal in your workspace, run `node`:\n```bash\n$ node\n```\n  \n## Compiling the Contract\n1.\tRequire the `web3` library:\n```bash\n\u003e Web3 = require('web3')\n```\n\n2.\tInitialize the provider:\n```bash\n\u003e web3 = new Web3(new Web3.providers.HttpProvider(\"http://localhost:8545\"))\n```\nTip: If the console gets messy due to long outputs, press `CTRL + L` to clear the console.\n\n\n3.\tRetrieve and store all our available accounts. We can do that with `web3.eth.getAccounts()`. This returns a promise, so what we are going to do is to store the data in an `accounts` array for easy access.\n```bash\n\u003e web3.eth.getAccounts().then(web3Accounts =\u003e {accounts = web3Accounts})\n\u003e accounts\n```\n4.\tRead the contract and store it as a variable so we can have an easy access for later use:\n```bash\n\u003e code = fs.readFileSync('contracts/Voting.sol').toString()\n```\n5.\tRequire solidity compiler (solc):\n```bash\n\u003e solc = require('solc')\n```\n \n6.\tCompile the code. At this point, you would already have the `bytecode`, `metadata`, `interface`, and so on:\n```bash\n\u003e compiledCode = solc.compile(code)\n```\n\nIf you run into `solc` compiler issues, copy the code below (otherwise, disregard and continue):\n```bash\n\u003e var solcInput = {\n  language: \"Solidity\",\n  sources: {\n    contract: {\n      content: code\n    }\n  },\n  settings: {\n    optimizer: {\n      enabled: true\n    },\n    evmVersion: \"byzantium\",\n    outputSelection: {\n      \"*\": {\n        \"\": [\"legacyAST\", \"ast\"],\n        \"*\": [\n          \"abi\",\n          \"evm.bytecode.object\",\n          \"evm.bytecode.sourceMap\",\n          \"evm.deployedBytecode.object\",\n          \"evm.deployedBytecode.sourceMap\",\n          \"evm.gasEstimates\"\n        ]\n      }\n    }\n  }\n};\n\u003e solcInput = JSON.stringify(solcInput);\n\u003e compiledCode = solc.compile(solcInput);\n```\nIf you’re curious on what each property does, see the docs here:\nhttps://solidity.readthedocs.io/en/v0.5.0/using-the-compiler.html#compiler-input-and-output-json-description\n\n## Deploy the Contract\n1.\tRetrieve the `abiDefinition` in JSON format by calling the command: \n```bash\n\u003e abiDefinition = JSON.parse(compiledCode)['contracts']['contract']['Voting']['abi']\n```\n2.\tCreate the instance of the contract.\n\nNotice that we first pass the `ABI definition` then we pass an object where we specify the account that we want to deploy from and the `gas limit`. In our case, we have a previous `accounts` array with all available accounts and we use the one at `index 0` (the first account).\n```bash\n\u003e VotingContract = new web3.eth.Contract(abiDefinition, {from: accounts[0], gas: 4700000})\n```\n\n3.\tLastly, we need the byteCode of the contract. Use this code to retrieve it:\n```bash\n\u003e byteCode = JSON.parse(compiledCode)['contracts']['contract']['Voting']['evm']['bytecode']['object']\n```\n\n4.\tNow we will `deploy` the contract and store the instance of the contract in `contractInstance`:\n```bash\n\u003e VotingContract.deploy({data: byteCode}).send({from: accounts[0], gas: 4700000}).then(instance =\u003e {contractInstance = instance}\n\u003e contractInstance\n```\n## Interact with the Contract\n1.\tInteract with the deployed contract starting with adding candidates (Tristan and Rave) and sending the transactions from a different account (Account 1). \n\nRemember, we have all accounts in our `accounts[]` variable declared previously.\n```bash\n\u003e contractInstance.methods.addCandidate('Tristan').send({from: accounts[1]}).then(result =\u003e console.log(result))\n\u003e contractInstance.methods.addCandidate('Rave').send({from: accounts[1]}).then(result =\u003e console.log(result))\n```\nWe can see the information about the transactions that happened during the method executions and we can see that as well in our ganache terminal.\n \n2.\tVote for Candidates:\n```bash\n\u003e contractInstance.methods.voteForCandidate('Tristan').send({from: accounts[1]}).then(result =\u003e console.log(result))\n\u003e contractInstance.methods.voteForCandidate('Rave').send({from: accounts[2]}).then(result =\u003e console.log(result))\n\u003e contractInstance.methods.voteForCandidate('Tristan').send({from: accounts[3]}).then(result =\u003e console.log(result))\n```\nLet’s check Ganache again and see what happened there \nIt should have some new transactions as writing to the contract costs ether.\n\n3.\tCheck the votes for the candidates. Notice that we don’t use the `.send()` function here as reading from contracts is `free`, so we use `.call()` instead.\n\nBefore we proceed, check the balances first:\n```bash\n\u003e balances = accounts.map(account =\u003e web3.eth.getBalance(account))\n```\n\nCheck the total votes using `Account at index 5`:\n```bash\n\u003e contractInstance.methods.totalVotesFor('Rave').call({from: accounts[5]}).then(result =\u003e console.log(result.toString()))\nPromise { \u003cpending\u003e }\n\u003e 1\n\n\u003e contractInstance.methods.totalVotesFor('Tristan').call({from: accounts[5]}).then(result =\u003e console.log(result.toString()))\nPromise { \u003cpending\u003e }\n\u003e 2\n```\nCheck our balances again to make sure that this reading didn’t take any ETH from us.\n```bash\n\u003e balances = accounts.map(account =\u003e web3.eth.getBalance(account))\n```\nAnd, it seems that there have been no new transactions.\nWe have determined that `reading from a contract is free`.\n\n\n## Module\nMI4: Module 5: E1\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbethanyuo%2Fvoting-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbethanyuo%2Fvoting-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbethanyuo%2Fvoting-system/lists"}