-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathapp_backend_final.js
147 lines (126 loc) · 4.64 KB
/
app_backend_final.js
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
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const Web3 = require('web3');
const contractABI = require('./contractABI.json'); // Replace with your actual contract ABI
const contractAddress = '0xA72D8d4c4611c702dE430124A240E54fC78fA905'; // Replace with your actual contract address
const Voter = require('./voterModel');
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/voting', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// Mongoose models
const voterSchema = new mongoose.Schema({
address: { type: String, required: true, unique: true },
isRegistered: { type: Boolean, default: false },
hasVoted: { type: Boolean, default: false },
});
const VoterModel = mongoose.model('Voter', voterSchema);
// Express app setup
const app = express();
app.use(bodyParser.json());
// Web3 setup
// Connect to Remix Web3 provider
const web3 = new Web3('https://remix.ethereum.org/#web3-provider');
const contract = new web3.eth.Contract(contractABI, contractAddress);
// API endpoints
const registeredAccountNumberHashes = new Set();
app.post('/register', async (req, res) => {
const { username, accountNumberHash } = req.body;
try {
if (registeredAccountNumberHashes.has(accountNumberHash)) {
throw new Error('Account number hash is already registered');
}
// Check if the account number hash is already registered in the database
const existingVoter = await Voter.findOne({ accountNumberHash });
if (existingVoter) {
throw new Error('Account number hash is already registered');
}
// Register the voter in the smart contract
await contract.methods.registerVoter().send({ from: web3.eth.defaultAccount });
// Save the voter details in the database
await new Voter({ username, accountNumberHash }).save();
registeredAccountNumberHashes.add(accountNumberHash);
res.json({ message: 'Voter registered successfully' });
} catch (error) {
res.status(400).json({ error: error.message });
}
});
app.post('/vote', async (req, res) => {
const { address, candidateName } = req.body;
try {
if (!web3.utils.isAddress(address) || !candidateName) {
throw new Error('Invalid address or candidate name');
}
const voter = await VoterModel.findOne({ address });
if (!voter || !voter.isRegistered) {
throw new Error('Voter is not registered');
}
if (voter.hasVoted) {
throw new Error('Voter has already voted');
}
const candidates = await contract.methods.getCandidateList().call();
if (!candidates.includes(candidateName)) {
throw new Error('Candidate does not exist');
}
await contract.methods.castVote(candidateName).send({ from: address });
voter.hasVoted = true;
await voter.save();
res.json({ message: 'Vote cast successfully' });
} catch (error) {
res.status(400).json({ error: error.message });
}
});
app.get('/candidates', async (req, res) => {
try {
const candidates = await contract.methods.getCandidateList().call();
res.json(candidates);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Start listening for events emitted by the smart contract
contract.events.allEvents()
.on('data', event => {
console.log('Event:', event.event, event.returnValues);
})
.on('error', error => {
console.error('Event error:', error);
});
// Server setup
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
// Documentation endpoint
app.get('/', (req, res) => {
res.json({
endpoints: {
register: {
description: 'Register a voter',
method: 'POST',
path: '/register',
body: {
address: 'String (Ethereum address)',
},
},
vote: {
description: 'Cast a vote',
method: 'POST',
path: '/vote',
body: {
address: 'String (Ethereum address)',
candidateName: 'String (Candidate name)',
},
},
candidates: {
description: 'Get the list of candidates',
method: 'GET',
path: '/candidates',
},
},
});
});