Building a Decentralized Voting DApp with Ganache, Truffle, and Web3.js
This tutorial walks through creating a decentralized voting application on Ethereum using Solidity contracts, Ganache for local blockchain simulation, Web3.js for RPC interaction, and Truffle for compilation, migration, and front‑end integration, covering setup, contract code, deployment, and both console and web UI interactions.
The article introduces a decentralized voting system architecture where each client node holds a full copy of the blockchain, emphasizing the need for lightweight development tools like Ganache to avoid full node synchronization.
Project Framework Overview
Images illustrate the peer‑to‑peer voting network and the overall application architecture, showing that the web front‑end communicates with the blockchain via HTTP RPC calls using web3.js .
Using Node.js for the First Iteration
2.1 Install Ganache
On macOS, install Ganache CLI with:
sudo npm install -g ganache-cliRun ganache-cli to start a private chain with ten pre‑funded accounts.
2.2 Voting Contract Code
The Solidity contract Voting.sol includes a constructor, a Vote() function, and a totalVotesFor() query:
pragma solidity ^0.4.18;
contract Voting {
mapping (bytes32 => uint8) public votesReceived;
bytes32[] public candidateList;
function Voting(bytes32[] candidateNames) public {
candidateList = candidateNames;
}
function totalVotesFor(bytes32 candidate) view public returns (uint8) {
require(validCandidate(candidate));
return votesReceived[candidate];
}
function voteForCandidate(bytes32 candidate) public {
require(validCandidate(candidate));
votesReceived[candidate] += 1;
}
function validCandidate(bytes32 candidate) view public returns (bool) {
for (uint i = 0; i < candidateList.length; i++) {
if (candidateList[i] == candidate) { return true; }
}
return false;
}
}2.3 Compile and Deploy with Node.js
Compile using solc and deploy via Web3.js:
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
var compiled = solc.compile(code);
var abi = JSON.parse(compiled.contracts[':Voting'].interface);
var bytecode = compiled.contracts[':Voting'].bytecode;
var VotingContract = web3.eth.contract(abi);
var deployed = VotingContract.new(['Rama','Nick','Jose'], {data: bytecode, from: web3.eth.accounts[0], gas: 4700000});Interact with the contract using methods like totalVotesFor.call('Rama') and voteForCandidate('Rama') , observing transaction IDs and immutable state changes.
Web Front‑End Interaction
A simple HTML page lists candidates and their vote counts; users input a name and click a button, which triggers JavaScript calling voteForCandidate() via Web3.js. The page includes the necessary scripts ( web3.js , index.js ) and connects to the local node.
Second Iteration with Truffle
Truffle streamlines development by providing project scaffolding, automatic compilation, and migration scripts.
3.1 Project Setup
Create a Truffle project with truffle unbox webpack , then copy Voting.sol , index.html , and custom index.js into the generated directories.
3.2 Migration Scripts
Define deployment in 2_deploy_contracts.js :
var Voting = artifacts.require("./Voting.sol");
module.exports = function(deployer) {
deployer.deploy(Voting, ['Rama','Nick','Jose'], {gas: 290000});
};Configure the development network in truffle.js with host localhost , port 8545 , and a suitable gas limit.
3.3 Compile and Migrate
Run truffle compile to generate artifacts in build/contracts , then truffle migrate to deploy the contract.
3.4 Interaction via Truffle Console and Web UI
In the console, use:
Voting.deployed().then(function(instance){
return instance.voteForCandidate('Rama');
}).then(function(){
return instance.totalVotesFor.call('Rama');
}).then(console.log);Build the front‑end with webpack , serve it (e.g., python -m SimpleHTTPServer 8000 ), and verify voting through the browser.
Conclusion
The guide demonstrates a complete workflow from raw Solidity code to a functional DApp using both manual Node.js scripts and the Truffle framework, laying the foundation for further extensions such as token integration.
Hujiang Technology
We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.