Building the SolidVote Decentralized Voting Application
By Jonathan Johnston
Posted on April 20, 2023
*This post was written with extensive help from GPT4, lets just say the notes in my lab book were... overly concise.*
I discuss creating SolidVote, a decentralized voting app on Ethereum. The journey involved smart contracts, Truffle, Ganache, web3.js, Node.js, and Metamask integration, leading to a functional and secure voting application.
Introduction
In this blog post, I will discuss my development journey of the SolidVote decentralized voting application built on the Ethereum blockchain. I will cover the process from drafting the contract in Remix to setting up the front-end using web3.js and eventually implementing Metamask for user authentication. Throughout the post, I will also address some challenges faced and lessons learned during the development process.
SolidVote Draft Contract
The SolidVote project began with me drafting a contract using the Remix IDE. Remix is an excellent tool for quickly developing, testing, and debugging Solidity smart contracts.
Setting Up the Development Environment
To set up my local development environment, I installed Truffle and Ganache. Truffle is a development framework for Ethereum, while Ganache is a personal blockchain for Ethereum development. I then migrated the contract to Ganache, enabling me to test the contract locally.
Integrating Web3.js and Node.js
To interact with the Ethereum blockchain, I used the web3.js library, which is essential for integrating smart contracts with a web front-end.
Dealing with Web3.js Challenges
During development, I encountered challenges related to including the web3.min.js file in the project. After much trial and error, I realized that including the file in the HTML file resolved the issue, as the script tag would automatically include the necessary dependencies when running in the browser.
Metamask Integration
I successfully integrated Metamask, a popular Ethereum wallet, into the application to enable user authentication. Initially, the application used a hardcoded private key, but I replaced it with Metamask to make it more secure and user-friendly. By doing so, I was able to extract the private key directly from Metamask without the need for manual input.
Improving Functionality
Initially, the application allowed a user to create a ballot and immediately vote, with only one vote per ballot. I later extended the functionality to allow multiple users to set up and create ballots and enable multiple people to link to the created ballots and cast their votes. This was achieved by implementing functions like createNewBallotApp, voteOnBallotApp, and submitVote. Fetching ABI from JSON File To optimize the development process, I decided to fetch the contract's ABI (Application Binary Interface) from a JSON file instead of manually copying and reformatting it each time the contract changed. I used the fetch function to accomplish this and struggled a bit with handling asynchronous promises. Eventually, I was able to disable the "connectEthereumWalletButton" until all promises were resolved.
Deploying onto the Sepolia Test Network
Deployment was fairly strait forward, but once it was on the network, half of the contract quit working correctly. After many hours of debugging I discovered my error. To call a contract function doesn't use any gas, but I was using the account number as an ID so I still needed send it. When I ran it locally, MetaMask would send the account I was using as a default, and that changed after deployment onto the network so the contract wasn't getting an account.
Conclusion
Though not quite over, with the end of this project in sight, developing the SolidVote decentralized voting application was an exciting and challenging journey. Throughout the process, I learned valuable lessons about Solidity, web3.js, and Metamask integration. As the application continues to grow and evolve, I am optimistic about its potential to enable secure and transparent voting processes on the Ethereum blockchain.