Blockchain 20 min read

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.

Hujiang Technology
Hujiang Technology
Hujiang Technology
Building a Decentralized Voting DApp with Ganache, Truffle, and Web3.js

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-cli

Run 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.

Smart ContractTruffleGanachevoting dappweb3.js
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.