You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: p2p/7.Voting-system/README.md
+58-11Lines changed: 58 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,7 +44,7 @@ Remove the files from `script/`, `src/` and `test` directories. Create `VotingSy
44
44
45
45
- Create a contract named `VotingSystem`
46
46
- Declare a structure named `Proposal`
47
-
>💡 The structure should have 2 variables, `name` and `voSteCount`. I let you guess their types.
47
+
>💡 The structure should have 2 variables, `name` and `voteCount`. I let you guess their types.
48
48
49
49
- On deployment, the contract should take an array of strings as parameters and store them in a `public` array of `Proposals`.
50
50
>💡 A constructor is an optional function that is executed upon contract deployment, you must create one to complete the previous task.
@@ -75,7 +75,8 @@ In this step you'll focus on the deployment and the integration part of your sma
75
75
- Using Anvil and forge, deploy your smart contract on a local testnet.
76
76
>💡 On a successful deployment, contract address appear next to the `deployed to` field.
77
77
78
-
- Paste the address of your deployed contract into the environment file at the root of the dApp folder named `VITE_ADDRESS`.
78
+
- In the `dApp` folder, create a `.env` file at the root (if it doesn't exist) and add the following line: `VITE_ADDRESS=<your_contract_address>`
79
+
> 💡 The contract address appears after deployment. Make sure to include the `0x` prefix when copying the address.
79
80
80
81
### ✔️ **Validation**:
81
82
@@ -90,23 +91,69 @@ Once you have done this, you should now be able to see the parameters you entere
90
91
91
92
### 📑 **Description**:
92
93
93
-
Crucial step! I'll leave you to code the rest of the contract yourself, so you can see the results bit by bit. Feel free to redeploy your contract whenever you like with forge!
94
+
Now that your contract is deployed and visible in the dApp, it's time to add the voting logic! In this step, you'll implement:
95
+
- A system to track who has already voted
96
+
- A function to vote for a proposal
97
+
- A function to determine which proposal has the most votes
98
+
99
+
Feel free to redeploy your contract with `forge` after each modification to test your changes in the dApp!
94
100
95
101
### 📌 **Tasks**:
96
102
97
-
- Create a structure `Voter` containing a boolean named `voted` and an uint `id`.
98
-
- Code the `vote` function. It should take the id of the proposal in parameter.
99
-
- Check if the voter had already voted and if the id is correct.
100
-
> 💡 If the voter had already voted, return the string 'Already Voted.'
101
-
- Add a `voteCount` for the proposal.
103
+
#### 1. Create the `Voter` structure and mapping
104
+
105
+
To prevent the same address from voting multiple times, we need to track each voter's state.
106
+
107
+
- Create a `Voter` structure containing:
108
+
- A boolean `hasVoted` (indicates if this person has already voted)
109
+
- A `uint``votedProposalId` (the identifier of the proposal this person voted for)
110
+
- Create a mapping to associate each address with its voter state
111
+
> 💡 A mapping allows you to store data associated with a key (here, the voter's address). Use `msg.sender` to get the address of the person calling the function.
112
+
113
+
#### 2. Configure authentication for the dApp
114
+
115
+
Before coding the `vote` function, you need to configure a private key so the dApp can send transactions.
116
+
117
+
- In the `dApp` folder, add the following line to your `.env` file: `VITE_PRIVATE_KEY_ACCOUNT=<an_anvil_private_key>`
118
+
> 💡 When you launch Anvil, several accounts with their private keys are displayed. Copy one of these private keys **with the `0x` prefix** and paste it into your `.env` file. The `viem` library requires the `0x` prefix. Restart the dApp after this modification.
102
119
103
-
> 💡 These functions require a wallet address. If you've did the previous step correctly, you have account available to use. Put one of the private keys in the `.env` file.
120
+
#### 3. Implement the `vote` function
104
121
105
-
- Code the `winningProposal` function, returning the proposal id with the most `voteCount`.
122
+
This function allows a user to vote for a proposal.
123
+
124
+
- Create a `vote` function that takes a `uint` as parameter (the proposal id)
125
+
- Check that the voter hasn't already voted:
126
+
- If `voters[msg.sender].hasVoted` is `true`, use `revert("Already Voted.")` to throw an error
127
+
> 💡 In Solidity, use `revert()` to signal errors. The error message will be caught by the frontend.
128
+
- Check that the proposal id is valid:
129
+
- The id must be greater than or equal to 0
130
+
- The id must be less than the length of the `proposals` array
131
+
> 💡 You can use `require()` to check these conditions
132
+
- If everything is valid:
133
+
- Mark the voter as having voted: `voters[msg.sender].hasVoted = true`
134
+
- Record the chosen proposal id: `voters[msg.sender].votedProposalId = <proposal_id>`
135
+
- Increment the vote counter: `proposals[<proposal_id>].voteCount++`
136
+
137
+
#### 4. Implement the `winningProposal` function
138
+
139
+
This function determines which proposal received the most votes.
140
+
141
+
- Create a `winningProposal` function that returns a `uint` (the winning proposal id)
142
+
- Loop through all proposals in the `proposals` array
143
+
- For each proposal, compare its `voteCount` with the current maximum
144
+
- Return the id of the proposal with the highest `voteCount`
145
+
> 💡 In case of a tie, you can return the first proposal with the maximum votes. Use a `for` loop to iterate through the array.
106
146
107
147
### ✔️ **Validation**:
108
148
109
-
If you can see all the proposals, vote for one and the winner is highlighted in green, congratulations, you have just made your first smart contract !
149
+
To verify that everything works correctly:
150
+
151
+
1.**Check the display**: In the dApp, you should see all the proposals you created during deployment
152
+
2.**Test voting**: Click on a proposal and vote for it. The vote counter should increment
153
+
3.**Test double-vote protection**: Try voting a second time with the same account. You should see the message "You have already voted."
154
+
4.**Check the winner**: After voting for several proposals, the proposal with the most votes should be highlighted in green
155
+
156
+
If all these steps work, congratulations, you've created your first smart contract! 🎉
0 commit comments