-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender.html
More file actions
207 lines (161 loc) Β· 10.1 KB
/
render.html
File metadata and controls
207 lines (161 loc) Β· 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!DOCTYPE html>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
h1 {
text-align: center;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/texme@1.2.2"></script>
<textarea>
# π³οΈ Blockchain Voting System - Project Overview
## π Introduction
This is a **Decentralized Voting Application (DApp)** built on the Ethereum Blockchain. It ensures that votes are **secure, immutable, and transparent**. Unlike traditional databases, once a vote is cast on the blockchain, it cannot be deleted or altered by anyone, not even the admin.
---
## ποΈ Architecture (How it Works)
The project consists of three main layers:
### 1. The Blockchain Layer (Smart Contracts) βοΈ
* **Role:** The "Trust Layer". It stores the election rules, candidates, and the actual vote counts.
* **Technology:** **Solidity** (Programming Language), **Hardhat** (Development Framework).
* **Key Files:**
* `Election.sol`: The logic for a single election (voting, counting).
* `ElectionFactory.sol`: A "factory" that creates new Election contracts.
### 2. The Backend Layer (Server) βοΈ
* **Role:** The "Manager". It handles things that are too expensive or complex to put on the blockchain.
* **Responsibilities:**
* **Voter Registration:** Generates "Passkeys" (Wallets) for voters.
* **Merkle Tree Generation:** Compresses the list of valid voters into a single "Root Hash" to save gas fees.
* **API:** Provides data to the frontend.
* **Technology:** **Node.js**, **Express.js**, **MerkleTree.js**.
### 3. The Frontend Layer (User Interface) π¨
* **Role:** The "Face". It's what the user interacts with.
* **Responsibilities:**
* **Admin Dashboard:** Create elections, register voters.
* **Voting Booth:** Connects to the blockchain (via Ethers.js) to cast votes.
* **Results:** Displays real-time charts.
* **Technology:** **React**, **Tailwind CSS** (Styling), **Ethers.js** (Blockchain Connection).
---
## π§ Key Concepts (For Viva/Questions)
### Q: Why use Blockchain?
**A:** For **Immutability**. In a normal SQL database, an admin could run `UPDATE votes SET count = 100`. On the blockchain, the code is immutable. Once deployed, the rules cannot change, and votes cannot be faked.
### Q: What is a Merkle Tree?
**A:** Storing thousands of voters on the blockchain is very expensive (Gas fees). Instead, we create a **Merkle Tree** (a hash tree) of all valid voters off-chain (Backend). We only store the **Merkle Root** (a single string) on the smart contract.
* When a user votes, they provide a **Merkle Proof** (a path) to prove they are in the tree.
* The contract verifies this proof against the Root.
* **Benefit:** Massive gas savings.
### Q: How does Voting Work?
1. **Registration:** Admin enters email -> Backend creates a Wallet (Private Key) -> Backend adds wallet to Merkle Tree.
2. **Start:** Admin sends the Merkle Root to the Smart Contract.
3. **Vote:** User logs in with Passkey -> Frontend gets Proof from Backend -> Frontend sends `vote(candidateId, proof)` transaction to Blockchain.
4. **Count:** The Smart Contract checks the proof, checks if `hasVoted` is false, increments the count, and marks `hasVoted` as true.
---
## π οΈ Tech Stack Summary
| Component | Technology | Purpose |
| :--- | :--- | :--- |
| **Blockchain** | **Solidity** | Smart Contract Code |
| | **Hardhat** | Local Blockchain & Testing |
| **Backend** | **Node.js / Express** | API Server |
| | **MerkleTree.js** | Whitelisting Logic |
| **Frontend** | **React (Vite)** | UI Framework |
| | **Tailwind CSS** | Styling (Dark/Light Mode) |
| | **Ethers.js** | Connecting to Blockchain |
| | **Recharts** | Visualizing Results |
---
## π User Flow (Step-by-Step)
1. **Admin** logs in and creates an Election (deploys a new Contract).
2. **Admin** registers Voters. Each voter gets a unique **Passkey**.
3. **Admin** clicks "Auto-Setup" to generate the Merkle Root and **Start** the election.
4. **Voter** goes to the Voting Booth and pastes their **Passkey**.
5. **Voter** selects a candidate and clicks **Vote**.
6. **MetaMask** (or the background wallet) signs the transaction.
7. **Everyone** can see the live results update instantly on the Home page.
## π Comprehensive Master Guide: Blockchain Voting System
This guide explains **every single part** of the project in detail. It is designed to help you understand the code "from scratch" so you can answer any question about it.
---
## π 1. Project Structure
The project is split into 3 folders, each acting as a separate "layer":
* **`contracts/` (The Blockchain Layer):** Contains the Solidity code that runs on the Ethereum network. This is the "Database" and "Logic" that cannot be hacked.
* **`backend/` (The Server Layer):** A Node.js API that manages user registration, generates "Passkeys", and creates Merkle Trees. It bridges the gap between the user and the blockchain.
* **`frontend/` (The User Interface):** A React website where users click buttons. It connects to the Blockchain (via MetaMask/Ethers) and the Backend (via Axios).
---
## βοΈ 2. Smart Contracts (`contracts/`)
### [Election.sol](file:///d:/voting2.0/contracts/contracts/Election.sol) (The Core Logic)
This is the heart of the system. Each election (e.g., "Class President") is a separate deployment of this contract.
* **`struct Candidate`:** Defines what a candidate looks like ([id](file:///d:/voting2.0/frontend/src/pages/Guide.jsx#3-71), `name`, `voteCount`). *Note: We don't store photos here to save gas.*
* **`mapping(address => bool) public hasVoted`:** A ledger that tracks who has voted. If `hasVoted[user] == true`, they cannot vote again.
* **`bytes32 public merkleRoot`:** The "Fingerprint" of all allowed voters.
* **`function vote(candidateId, proof)`:**
1. **Check:** Has this user voted? (`require(!hasVoted[msg.sender])`)
2. **Verify:** Is this user allowed? (`MerkleProof.verify(proof, root, leaf)`)
3. **Action:** Increment candidate votes (`candidates[id].voteCount++`)
4. **Mark:** Set `hasVoted[msg.sender] = true`.
### [ElectionFactory.sol](file:///d:/voting2.0/contracts/contracts/ElectionFactory.sol) (The Generator)
Instead of deploying [Election.sol](file:///d:/voting2.0/contracts/contracts/Election.sol) manually every time, we use a Factory.
* **[createElection(title)](file:///d:/voting2.0/frontend/src/pages/AdminDashboard.jsx#112-167):** Deploys a NEW [Election](file:///d:/voting2.0/frontend/src/pages/AdminDashboard.jsx#284-302) contract and saves its address.
* **Why?** It allows the Admin to create unlimited elections from the Dashboard without touching code.
---
## βοΈ 3. Backend (`backend/`)
### [server.js](file:///d:/voting2.0/backend/server.js) (The Entry Point)
Starts the Express server on Port 3000. It loads all the routes.
### [routes/auth.js](file:///d:/voting2.0/backend/routes/auth.js) (Admin Login)
* Uses **JWT (JSON Web Tokens)**.
* When Admin logs in, they get a "Token". This token proves they are the admin for future requests.
### [routes/voter.js](file:///d:/voting2.0/backend/routes/voter.js) (Registration)
* **`POST /register`:**
1. Takes an Email.
2. Creates a **New Ethereum Wallet** (Random Private Key).
3. Saves this wallet to the database (Mock DB).
4. Returns the **Private Key** to the user as their "Passkey".
* *Crucial:* The user MUST save this Passkey. It's their login.
### [routes/election.js](file:///d:/voting2.0/backend/routes/election.js) (Merkle Logic)
* **`POST /:id/generate-merkle`:**
1. Gets all registered wallet addresses for an election.
2. Hashes them into a **Merkle Tree**.
3. Returns the **Root Hash**.
* **`GET /:id/proof`:**
1. When a user wants to vote, they ask the backend: "Give me my proof".
2. The backend calculates the "path" from their address to the Root.
3. The frontend sends this path to the Smart Contract.
---
## π¨ 4. Frontend (`frontend/`)
### [contractConfig.js](file:///d:/voting2.0/frontend/src/contractConfig.js)
* Stores the **Address** of the deployed Factory.
* Stores the **ABI** (Application Binary Interface) - a JSON file that tells React how to talk to Solidity.
### [pages/AdminDashboard.jsx](file:///d:/voting2.0/frontend/src/pages/AdminDashboard.jsx)
* **Create Election:** Calls `factory.createElection()`.
* **Register Voter:** Calls Backend API (`/register`).
* **Start Election:**
1. Calls Backend to get Merkle Root.
2. Calls Contract [setMerkleRoot(root)](file:///d:/voting2.0/frontend/src/pages/AdminDashboard.jsx#257-283).
3. Calls Contract [startElection()](file:///d:/voting2.0/frontend/src/pages/AdminDashboard.jsx#284-302).
### [pages/VotingBooth.jsx](file:///d:/voting2.0/frontend/src/pages/VotingBooth.jsx)
* **Login:** User pastes Passkey -> `new ethers.Wallet(passkey)`.
* **Vote:**
1. Checks if user has ETH (Gas). If not, asks Faucet.
2. Gets Merkle Proof from Backend.
3. Calls `contract.vote(id, proof)`.
---
## π 5. The "Life of a Vote" (Data Flow)
1. **Registration:**
* User gives Email -> Backend generates Wallet (`0xABC...`) -> Backend saves to DB.
2. **Setup:**
* Admin clicks "Start" -> Backend hashes all Wallets -> Root Hash (`0x123...`) sent to Blockchain.
3. **Voting:**
* User logs in with Passkey (Private Key for `0xABC...`).
* Frontend asks Backend: "Proof for `0xABC`?".
* Backend replies: "Here is your proof array".
* Frontend sends Transaction: "I am `0xABC`, here is my proof, I vote for Candidate 1".
4. **Verification (On-Chain):**
* Contract hashes `0xABC`.
* Contract combines hash with Proof.
* If result == Root Hash (`0x123...`), the vote counts!
---
## β Common Questions (Viva)
* **Q: Is the vote secret?**
* A: The *count* is public, but the *voter's identity* is pseudo-anonymous (linked to a wallet address, not their name).
* **Q: Can the Admin fake votes?**
* A: No. The Admin cannot generate a valid Merkle Proof for a wallet they don't have the private key for.
* **Q: What happens if the server goes down?**
* A: Users can't register or get proofs, but the *existing votes* on the blockchain are safe forever.
</textarea>