A Simple Voting Smart Contract – Step‑by‑Step
Follow each step. Use your local chain from Ganache. Keep screenshots of the key actions and outputs.
Reference material
GitHub: Chapter 5 (Voting)
1. Install and Set Up MetaMask
Why: MetaMask manages accounts and signs transactions. It bridges your browser to Ethereum networks (Ganache in this HW).
- Install the MetaMask browser extension from the official site/store.
- Open MetaMask → create a new wallet → securely store the recovery phrase.
- After setup, you will see your first account (e.g., Account 1).
Expected Outcome: MetaMask is installed and your first Ethereum account is created.
2. Set Up Ganache
Why: Ganache simulates an Ethereum network locally. No real money needed.
- Download and install Ganache (GUI) from Truffle Suite.
- Open Ganache → Quickstart Ethereum.
- Ganache creates 10 accounts with 100 ETH each. RPC runs at
http://127.0.0.1:7545
.
Expected Outcome: Ganache is running locally with 10 funded accounts.
3. Connect MetaMask to Ganache
Why: MetaMask must point to your local blockchain to deploy and send transactions.
- In MetaMask, open the network selector → Add Network → Add a network manually.
- Fill in:
- Network Name:
Ganache
- New RPC URL:
http://127.0.0.1:7545
- Chain ID:
1337
- Currency Symbol:
ETH
- Network Name:
- Save, then switch MetaMask to the Ganache network.
Expected Outcome: MetaMask is now connected to your local Ganache network.
4. Import a Ganache Account into MetaMask
Why: Use a prefunded Ganache account to pay for deployments.
- In Ganache, click the key icon for the first account → copy its private key.
- In MetaMask: account icon → Import Account → paste the private key → Import.
Expected Outcome: The 100‑ETH Ganache account appears in MetaMask.
5–7. Open Remix, Write, Compile, and Deploy
5. Open Remix and Write the Contract
- Open Remix IDE in your browser.
- New file →
Voting.sol
→ paste the code below.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Voting {
string[] public candidateList;
mapping(string => uint256) public votesReceived;
constructor(string[] memory candidateNames) {
candidateList = candidateNames;
}
function voteForCandidate(string memory candidate) public {
require(validCandidate(candidate), "Candidate does not exist");
votesReceived[candidate] += 1;
}
function totalVotesFor(string memory candidate) public view returns (uint256) {
require(validCandidate(candidate), "Candidate does not exist");
return votesReceived[candidate];
}
function validCandidate(string memory candidate) public view returns (bool) {
for (uint i = 0; i < candidateList.length; i++) {
if (keccak256(abi.encodePacked(candidateList[i])) == keccak256(abi.encodePacked(candidate))) {
return true;
}
}
return false;
}
}
Expected Outcome:
Voting.sol
is ready in Remix.6. Compile the Contract
- Click Solidity Compiler in Remix sidebar.
- Set compiler to 0.8.0 or higher.
- Click Compile Voting.sol. Look for the green checkmark.
Expected Outcome: Compilation succeeds.
7. Deploy to Ganache
- Click Deploy & Run Transactions in Remix.
- Environment: choose Injected Web3 (connects to MetaMask). (Alternatively, you may use Remix VM (Cancun) for practice, but homework requires Ganache.)
- Ensure MetaMask is on the Ganache network.
- Constructor args:
["Alice", "Bob", "Charlie"]
- Click Deploy → confirm the MetaMask transaction.
Expected Outcome: Contract is deployed and appears under Deployed Contracts.
8–10. Interact with the Contract
8. Cast a Vote
- Expand the deployed Voting instance in Remix.
- Find
voteForCandidate
. Enter"Alice"
(quotes included; case‑sensitive). - Click the function → confirm in MetaMask.
Expected Outcome: A vote transaction is confirmed for "Alice".
9. Validate a Candidate
- Find
validCandidate
. - Enter
"Bob"
and click. Result appears below:true
orfalse
.
Expected Outcome: You can verify whether a name exists.
10. Count Votes
- Find
totalVotesFor
. - Enter
"Alice"
and click to read the current vote count.
Expected Outcome: You see the number of votes recorded for a candidate.
Troubleshooting
- MetaMask not connecting: Ensure the network RPC URL is
http://127.0.0.1:7545
and Chain ID1337
. Switch accounts if needed. - Deployment fails: Confirm MetaMask is on Ganache and Ganache is running. Check Injected Web3 is selected in Remix.
- Wrong constructor input: Ensure array syntax and quotes are correct:
["Alice", "Bob", "Charlie"]
. - Function calls revert: Names are case‑sensitive; run
validCandidate
first to verify. - Out of gas / high gas: Use default Remix gas limits; Ganache has ample balance.
Submission Checklist
- Screenshot: MetaMask showing the Ganache network selected.
- Screenshot: Ganache workspace with accounts and RPC
7545
. - Screenshot: Remix deployment panel (Injected Web3) and successful deploy.
- Screenshot: Transaction confirmation for
voteForCandidate("Alice")
. - Screenshot:
totalVotesFor("Alice")
showing a non‑zero number.
File naming:
HW2_FirstnameLastname.pdf
with all screenshots in order.