-
Notifications
You must be signed in to change notification settings - Fork 0
/
cammands.txt
255 lines (193 loc) · 6.88 KB
/
cammands.txt
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
Commands:
truffle init
Optional: ganache // start ganache via npm or start via UI
truffle compile
truffle migrate --reset
next.js command
npm run dev
Details:
Sure, here's a streamlined version of the instructions:
# Setting Up Truffle and Ganache:
1. Initialize Truffle Project:
cd voting-app
truffle init
2. Configure `truffle-config.js`:
Replace the contents with:
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 7545, // Use 7545 for Ganache UI, 8545 for Ganache CLI
network_id: "*",
},
},
compilers: {
solc: {
version: "0.8.14",
}
}
};
3. Create and Deploy a Contract:
- Create `Voting.sol` in the `contracts` folder.
- Create `1_deploy_contracts.js` in the `migrations` folder:
const Voting = artifacts.require("Voting");
module.exports = function(deployer) {
deployer.deploy(Voting);
};
4. Start Ganache:
Start Ganache via npm:
ganache
Note the port used (8545 for CLI, 7545 for UI).
5. Compile and Migrate Contracts:
truffle compile
truffle migrate --reset
# Setting Up Next.js:
1. Create Next.js Project:
npx create-next-app@latest voting-app-next
cd voting-app-next
2. Install Dependencies:
npm install web3 truffle-contract
3. Configure Web3:
Create `utils/web3.js`:
import Web3 from "web3";
let web3;
if (typeof window !== "undefined" && typeof window.ethereum !== "undefined") {
window.ethereum.request({ method: "eth_requestAccounts" });
web3 = new Web3(window.ethereum);
} else {
const provider = new Web3.providers.HttpProvider(
"http://127.0.0.1:8545" // Use 8545 for Ganache CLI, 7545 for UI
);
web3 = new Web3(provider);
}
export default web3;
4. Setup Voting Contract:
Create `utils/votingApp.js`:
import web3 from "./web3";
import VotingContract from "../voting-app/build/contracts/Voting.json";
let contractInstance;
try {
const { abi, networks } = VotingContract;
const networkId = Object.keys(networks)[0];
const contractAddress = networks[networkId]?.address;
if (!contractAddress) {
throw new Error(`No contract address found for network ID ${networkId}.`);
}
contractInstance = new web3.eth.Contract(abi, contractAddress);
console.log(`Connected to contract at address: ${contractAddress}`);
} catch (error) {
console.error("Failed to initialize contract instance:", error);
alert(`Failed to initialize contract instance: ${error.message}`);
}
export default contractInstance;
5. Create Homepage:
- Next.js 14 page.jsx or react js app.js`:
import HomePage from "../components/HomePage";
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<HomePage />
</main>
);
}
- Create `components/HomePage.jsx`:
jsx
import { useEffect, useState } from "react";
import web3 from "../utils/web3";
import voting from "../utils/voting";
export default function HomePage() {
const [candidates, setCandidates] = useState([]);
const [candidateName, setCandidateName] = useState('');
const [accounts, setAccounts] = useState([]);
const [totalVotes, setTotalVotes] = useState(0);
useEffect(() => {
const init = async () => {
try {
const accounts = await web3.eth.getAccounts();
setAccounts(accounts);
await fetchCandidates();
await fetchTotalVotes();
} catch (error) {
console.error("Error initializing:", error);
}
};
init();
}, []);
const fetchCandidates = async () => {
try {
const candidateCount = await voting.methods.candidatesCount().call();
const candidatesArray = [];
for (let i = 0; i < candidateCount; i++) {
const candidate = await voting.methods.candidates(i).call();
candidatesArray.push(candidate);
}
setCandidates(candidatesArray);
} catch (error) {
console.error("Error fetching candidates:", error);
}
};
const fetchTotalVotes = async () => {
try {
const total = await voting.methods.totalVotes().call();
setTotalVotes(total);
} catch (error) {
console.error("Error fetching total votes:", error);
}
};
const addCandidate = async () => {
try {
await voting.methods.addCandidate(candidateName).send({ from: accounts[0] });
await fetchCandidates();
setCandidateName('');
} catch (error) {
console.error("Error adding candidate:", error);
}
};
const vote = async (candidateId) => {
try {
await voting.methods.vote(candidateId).send({ from: accounts[0] });
await fetchCandidates();
await fetchTotalVotes();
} catch (error) {
console.error("Error voting:", error);
}
};
return (
<div className="container">
<h1 className="my-4">Voting DApp</h1>
<div className="mb-3">
<input
type="text"
className="form-control"
value={candidateName}
onChange={(e) => setCandidateName(e.target.value)}
placeholder="Enter candidate name"
/>
<button className="btn btn-primary mt-2" onClick={addCandidate}>Add Candidate</button>
</div>
<div className="row">
{candidates.map((candidate, index) => (
<div className="col-md-4" key={index}>
<div className="card mb-4">
<div className="card-body">
<h5 className="card-title">{candidate.name}</h5>
<p className="card-text">Votes: {candidate.voteCount}</p>
<button
className="btn btn-primary"
onClick={() => vote(candidate.id)}
disabled={candidate.hasVoted}
>
Vote
</button>
</div>
</div>
</div>
))}
</div>
<div>Total Votes: {totalVotes}</div>
</div>
);
}
6. Run Next.js App:
npm run dev
This setup guides you through setting up Truffle for contract development, Ganache for a local blockchain, and integrating it with a Next.js frontend using Web3 for blockchain interaction. Adjust port numbers based on whether you're using Ganache CLI or Ganache UI.