From 63d8afe82f41b98c21bd45ea18b4c1b98acecc8c Mon Sep 17 00:00:00 2001
From: sacharbon
Date: Wed, 28 Aug 2024 20:50:23 +0200
Subject: [PATCH 1/7] feat(p2p/voting-system): add v1
---
p2p/7.Voting-system/README.md | 119 ++++++++++++++++++
p2p/7.Voting-system/dApp/.env | 2 +
p2p/7.Voting-system/dApp/.eslintrc.cjs | 15 +++
p2p/7.Voting-system/dApp/.gitignore | 30 +++++
p2p/7.Voting-system/dApp/.prettierrc.json | 8 ++
p2p/7.Voting-system/dApp/env.d.ts | 1 +
p2p/7.Voting-system/dApp/index.html | 13 ++
p2p/7.Voting-system/dApp/package.json | 35 ++++++
p2p/7.Voting-system/dApp/public/favicon.ico | Bin 0 -> 4286 bytes
p2p/7.Voting-system/dApp/src/App.vue | 114 +++++++++++++++++
p2p/7.Voting-system/dApp/src/abi.ts | 1 +
p2p/7.Voting-system/dApp/src/assets/base.css | 86 +++++++++++++
p2p/7.Voting-system/dApp/src/assets/main.css | 1 +
.../dApp/src/components/Card.vue | 48 +++++++
p2p/7.Voting-system/dApp/src/interact.ts | 79 ++++++++++++
p2p/7.Voting-system/dApp/src/main.ts | 7 ++
p2p/7.Voting-system/dApp/tsconfig.app.json | 14 +++
p2p/7.Voting-system/dApp/tsconfig.json | 11 ++
p2p/7.Voting-system/dApp/tsconfig.node.json | 19 +++
p2p/7.Voting-system/dApp/vite.config.ts | 16 +++
p2p/7.Voting-system/setup.md | 82 ++++++++++++
p2p/7.Voting-system/util/VotingSystem.t.sol | 38 ++++++
22 files changed, 739 insertions(+)
create mode 100644 p2p/7.Voting-system/README.md
create mode 100644 p2p/7.Voting-system/dApp/.env
create mode 100644 p2p/7.Voting-system/dApp/.eslintrc.cjs
create mode 100644 p2p/7.Voting-system/dApp/.gitignore
create mode 100644 p2p/7.Voting-system/dApp/.prettierrc.json
create mode 100644 p2p/7.Voting-system/dApp/env.d.ts
create mode 100644 p2p/7.Voting-system/dApp/index.html
create mode 100644 p2p/7.Voting-system/dApp/package.json
create mode 100644 p2p/7.Voting-system/dApp/public/favicon.ico
create mode 100644 p2p/7.Voting-system/dApp/src/App.vue
create mode 100644 p2p/7.Voting-system/dApp/src/abi.ts
create mode 100644 p2p/7.Voting-system/dApp/src/assets/base.css
create mode 100644 p2p/7.Voting-system/dApp/src/assets/main.css
create mode 100644 p2p/7.Voting-system/dApp/src/components/Card.vue
create mode 100644 p2p/7.Voting-system/dApp/src/interact.ts
create mode 100644 p2p/7.Voting-system/dApp/src/main.ts
create mode 100644 p2p/7.Voting-system/dApp/tsconfig.app.json
create mode 100644 p2p/7.Voting-system/dApp/tsconfig.json
create mode 100644 p2p/7.Voting-system/dApp/tsconfig.node.json
create mode 100644 p2p/7.Voting-system/dApp/vite.config.ts
create mode 100644 p2p/7.Voting-system/setup.md
create mode 100644 p2p/7.Voting-system/util/VotingSystem.t.sol
diff --git a/p2p/7.Voting-system/README.md b/p2p/7.Voting-system/README.md
new file mode 100644
index 00000000..db2a173e
--- /dev/null
+++ b/p2p/7.Voting-system/README.md
@@ -0,0 +1,119 @@
+# Workshop 6 - Voting System
+
+✔️ Write a decentralized voting system
+
+✔️ Deploy your smart contract on a local testnet using [Anvil](https://book.getfoundry.sh/anvil/) shipped with [Foundry](https://book.getfoundry.sh/)
+
+✔️ Display your smart contract on a dApp
+
+## Introduction
+
+A smart contract is a self-executing program that runs on a blockchain, automatically enforcing the terms of an agreement when predefined conditions are met. With smart contracts, it's possible to build decentralized systems, such as a transparent and secure voting system, where the rules are coded into the contract, and the results are immutable and verifiable by everyone.
+
+In this workshop we'll learn the basics of solidity with a classic use case: a voting system. At once, we'll use Foundry coupled with Anvil to deploy our contract on a local testnet and gradually integrate it on a front-end template.
+
+## Step 0: Initialization
+
+All the required information to install the workshop's dependencies are given in the [SETUP.md](./SETUP.md). To launch the dApp :
+
+- Clone the "dApp" folder, afterward:
+
+```bash
+cd dApp
+npm install
+npm run dev
+```
+
+If everything went well, you should read "No proposals yet.", now let's code !
+
+## Step 1 : Create the contract
+
+### 📑 **Description**:
+
+First, we need to create the core smart contract that will power our decentralized voting system. For now, you're just going to focus on the base of the smart contract: the constructor.
+
+### 📌 **Tasks**:
+
+Remove the files from `script/`, `src/` and `test` directories. Create `VotingSystem.sol` in the `src/` folder.
+
+- Create a structure named `Proposal`
+>💡 The structure should have 2 variables, `name` and `voteCount`. I let you guess their types.
+
+- On deployment, the contract should take an array of strings as parameters and store them in a `public` array of `Proposals`.
+
+### ✔️ **Validation**:
+
+After implementing this correctly, paste the `VotingSystem.t.sol` file from the `util/` folder from the repository and write:
+
+```bash
+forge test
+```
+
+if the two tests are good, you can move on the second step !
+
+## Step 2: Deploy and integrate it
+
+### 📑 **Description**:
+
+In this step you'll focus on the deployment and the integration part of your smart contract. For quick and easy deployment, you'll use [Anvil](https://book.getfoundry.sh/anvil/) to create a local testnet.
+
+### 📌 **Tasks**:
+
+- Using Anvil and forge, deploy your smart contract on a local testnet.
+- Paste the address of your deployed contract into the environment file at the root of the dApp folder.
+
+### ✔️ **Validation**:
+
+Once you have done this, you should now be able to see the parameters you entered when deploying the contract in the dApp.
+
+## Step 4: Code the contract
+
+### 📑 **Description**:
+
+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!
+
+### 📌 **Tasks**:
+
+- Create a structure `Voter`
+
+- Code the `vote` function. It should take an id in parameter.
+ - Check if the voter had already voted and if the id is correct.
+ - Add a `voteCount` for the proposal.
+
+> 💡 These functions require a wallet address. If you've written `anvil` before, you have account available to use. Put one of the private keys in the `.env` file.
+
+- Code the `winningProposal` function, returning the proposal with the most `voteCount`.
+
+### ✔️ **Validation**:
+
+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 !
+
+## Authors
+
+| [ Sacha Dujardin](https://github.com/Sacharbon) |
+| :------------------------------------------------------------------------------------------------------------------------: |
+
+
+
+
\ No newline at end of file
diff --git a/p2p/7.Voting-system/dApp/src/interact.ts b/p2p/7.Voting-system/dApp/src/interact.ts
new file mode 100644
index 00000000..f32e7de4
--- /dev/null
+++ b/p2p/7.Voting-system/dApp/src/interact.ts
@@ -0,0 +1,79 @@
+import {createPublicClient, createWalletClient, http} from 'viem'
+import { localhost } from 'viem/chains'
+import { abi } from "./abi"
+import {privateKeyToAccount} from "viem/accounts";
+
+let address = null
+let account = null
+
+if (import.meta.env.VITE_ADDRESS) {
+ address = import.meta.env.VITE_ADDRESS
+}
+
+if (import.meta.env.VITE_PRIVATE_KEY_ACCOUNT) {
+ account = privateKeyToAccount(import.meta.env.VITE_PRIVATE_KEY_ACCOUNT)
+}
+
+const chain = {
+ ...localhost,
+ id: 31337
+}
+
+const publicClient = createPublicClient({
+ chain,
+ transport: http()
+})
+
+const client = createWalletClient({
+ chain,
+ transport: http()
+})
+
+export async function win() {
+ try {
+ const result = await publicClient.readContract({
+ address,
+ abi,
+ functionName: "winningProposal",
+ })
+ return Number(result)
+ } catch (error) {
+ return null
+ }
+}
+
+async function retrieveProposal(id: number) {
+ return await publicClient.readContract({
+ address,
+ abi,
+ functionName: 'proposals',
+ args: [id]
+ })
+}
+
+export async function getProposals() {
+ const proposals = [];
+ let proposalCount = 0;
+
+ while (true) {
+ try {
+ const proposal = await retrieveProposal(proposalCount)
+ proposals.push(proposal)
+ proposalCount++
+ } catch (error) {
+ break;
+ }
+ }
+ return proposals;
+}
+
+export async function vote(id: number) {
+ const { request } = await publicClient.simulateContract({
+ account,
+ address,
+ abi,
+ functionName: 'vote',
+ args: [id]
+ }) as { request: any }
+ await client.writeContract(request)
+}
diff --git a/p2p/7.Voting-system/dApp/src/main.ts b/p2p/7.Voting-system/dApp/src/main.ts
new file mode 100644
index 00000000..98c094e0
--- /dev/null
+++ b/p2p/7.Voting-system/dApp/src/main.ts
@@ -0,0 +1,7 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+// @ts-ignore
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/p2p/7.Voting-system/dApp/tsconfig.app.json b/p2p/7.Voting-system/dApp/tsconfig.app.json
new file mode 100644
index 00000000..e14c754d
--- /dev/null
+++ b/p2p/7.Voting-system/dApp/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/p2p/7.Voting-system/dApp/tsconfig.json b/p2p/7.Voting-system/dApp/tsconfig.json
new file mode 100644
index 00000000..66b5e570
--- /dev/null
+++ b/p2p/7.Voting-system/dApp/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/p2p/7.Voting-system/dApp/tsconfig.node.json b/p2p/7.Voting-system/dApp/tsconfig.node.json
new file mode 100644
index 00000000..f0940630
--- /dev/null
+++ b/p2p/7.Voting-system/dApp/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/p2p/7.Voting-system/dApp/vite.config.ts b/p2p/7.Voting-system/dApp/vite.config.ts
new file mode 100644
index 00000000..5c45e1d9
--- /dev/null
+++ b/p2p/7.Voting-system/dApp/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/p2p/7.Voting-system/setup.md b/p2p/7.Voting-system/setup.md
new file mode 100644
index 00000000..a9e54fbc
--- /dev/null
+++ b/p2p/7.Voting-system/setup.md
@@ -0,0 +1,82 @@
+# Setup - Foundry, VSCode extension & Node
+
+[Foundry](https://book.getfoundry.sh/) is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust. We will need it throughout the workshop.
+
+## NodeJS
+
+To run the DApp locally, you need to install:
+- [nodejs](https://github.com/nodejs/node): JavaScript runtime
+- [npm](https://www.npmjs.com/): node package manager
+- [yarn](https://yarnpkg.com/): a better npm
+
+## Download foundry
+
+- Open your terminal and type
+
+```bash
+curl -L https://foundry.paradigm.xyz | bash
+```
+
+This will download foundryup.
+
+- Then, you can download foundry by running `foundryup`
+- If everything went fine you should be able to use `forge`, `anvil`, `chisel` and `cast`.
+- If you are on macos you will need to install `libusb` with
+
+```bash
+brew install libusb
+```
+
+After the installation, run the following command to ensure it has been properly installed on your computer:
+
+```bash
+forge --version
+```
+
+It should print your current version.
+
+If you have some troubles during the installation, you can refer to the [official documentation](https://book.getfoundry.sh/getting-started/installation).
+
+## Create a foundry project
+
+Once everything is done, you can create a new project using
+
+```bash
+forge init new_project
+cd new_project
+```
+
+This should create a new directory with a brand new foundry project
+
+If you already have a repository, you might need to add
+
+```bash
+--no-commit
+```
+
+The first thing you wants to do is set the solidity version of this project in the `foundry.toml` file wich is the configuration file of foundry.
+
+You can do this by adding in the "[profile.default]" section:
+
+```toml
+solc_version = "0.8.20"
+```
+
+## VSCode Integration
+
+I recommand you to install [solidity vscode extension](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity), it is an extension that simplifies development in Solidity.
+
+Also, I recommand you to use the extension formatter. It will format your code on save, which allows you to have a clean codebase. To do so:
+
+- Create a `.vscode/settings.json` file with this content
+
+```json
+{
+ "editor.formatOnSave": true,
+ "[solidity]": {
+ "editor.defaultFormatter": "NomicFoundation.hardhat-solidity"
+ }
+}
+```
+
+then [go back to the exercises](./README.md) 🚀
\ No newline at end of file
diff --git a/p2p/7.Voting-system/util/VotingSystem.t.sol b/p2p/7.Voting-system/util/VotingSystem.t.sol
new file mode 100644
index 00000000..3bff6848
--- /dev/null
+++ b/p2p/7.Voting-system/util/VotingSystem.t.sol
@@ -0,0 +1,38 @@
+pragma solidity 0.8.26;
+
+import "forge-std/Test.sol";
+import "../src/VotingSystem.sol";
+
+contract VotingSystemTest is Test {
+ VotingSystem public votingSystem;
+ string[] public proposalNames;
+
+ function setUp() public {
+ proposalNames = new string[](3);
+ proposalNames[0] = "Proposal 1";
+ proposalNames[1] = "Proposal 2";
+ proposalNames[2] = "Proposal 3";
+
+ votingSystem = new VotingSystem(proposalNames);
+ }
+
+ function testProposalCreation() public view {
+ for (uint i = 0; i < proposalNames.length; i++) {
+ (string memory name, uint voteCount) = votingSystem.proposals(i);
+ assertEq(name, proposalNames[i]);
+ assertEq(voteCount, 0);
+ }
+ }
+
+ function testProposalCount() public view {
+ uint proposalCount = 0;
+ while (true) {
+ try votingSystem.proposals(proposalCount) returns (string memory, uint) {
+ proposalCount++;
+ } catch {
+ break;
+ }
+ }
+ assertEq(proposalCount, proposalNames.length);
+ }
+}
\ No newline at end of file
From 2e746947c0238cede14077b5908a05be1b907d84 Mon Sep 17 00:00:00 2001
From: Sacha Dujardin
Date: Thu, 5 Sep 2024 07:03:18 +0200
Subject: [PATCH 2/7] feat(README.md): add documentation
---
p2p/7.Voting-system/README.md | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/p2p/7.Voting-system/README.md b/p2p/7.Voting-system/README.md
index db2a173e..40924a3c 100644
--- a/p2p/7.Voting-system/README.md
+++ b/p2p/7.Voting-system/README.md
@@ -51,6 +51,10 @@ forge test
if the two tests are good, you can move on the second step !
+### 📚 **Documentation**:
+
+ - [Constructors](https://docs.soliditylang.org/en/v0.8.27/contracts.html#constructors)
+
## Step 2: Deploy and integrate it
### 📑 **Description**:
@@ -60,12 +64,16 @@ In this step you'll focus on the deployment and the integration part of your sma
### 📌 **Tasks**:
- Using Anvil and forge, deploy your smart contract on a local testnet.
-- Paste the address of your deployed contract into the environment file at the root of the dApp folder.
+- Paste the address of your deployed contract into the environment file at the root of the dApp folder named `VITE_ADDRESS`.
### ✔️ **Validation**:
Once you have done this, you should now be able to see the parameters you entered when deploying the contract in the dApp.
+### 📚 **Documentation**:
+
+- [Anvil](https://book.getfoundry.sh/anvil/)
+
## Step 4: Code the contract
### 📑 **Description**:
@@ -80,7 +88,7 @@ Crucial step! I'll leave you to code the rest of the contract yourself, so you c
- Check if the voter had already voted and if the id is correct.
- Add a `voteCount` for the proposal.
-> 💡 These functions require a wallet address. If you've written `anvil` before, you have account available to use. Put one of the private keys in the `.env` file.
+> 💡 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.
- Code the `winningProposal` function, returning the proposal with the most `voteCount`.
@@ -88,6 +96,10 @@ Crucial step! I'll leave you to code the rest of the contract yourself, so you c
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 !
+## To go further
+
+You've just created a simple voting system smart contract ! If you want to go further you can add some feature to your contract and styling the dApp !
+
## Authors
| [ Sacha Dujardin](https://github.com/Sacharbon) |
@@ -116,4 +128,4 @@ Organization
-> 🚀 Don't hesitate to follow us on our different networks, and put a star 🌟 on `PoC's` repositories.
\ No newline at end of file
+> 🚀 Don't hesitate to follow us on our different networks, and put a star 🌟 on `PoC's` repositories.
From f8018c81d2be8f4487d1b3902b8ff45fea2a233a Mon Sep 17 00:00:00 2001
From: Sacha Dujardin
Date: Thu, 5 Sep 2024 07:35:25 +0200
Subject: [PATCH 3/7] fix(setup.md): end with a single newline character
---
p2p/7.Voting-system/setup.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/p2p/7.Voting-system/setup.md b/p2p/7.Voting-system/setup.md
index a9e54fbc..6ce7eacb 100644
--- a/p2p/7.Voting-system/setup.md
+++ b/p2p/7.Voting-system/setup.md
@@ -79,4 +79,4 @@ Also, I recommand you to use the extension formatter. It will format your code o
}
```
-then [go back to the exercises](./README.md) 🚀
\ No newline at end of file
+then [go back to the exercises](./README.md) 🚀
From 8451116f3bf955c2ef1aacc89b488c8c279aff30 Mon Sep 17 00:00:00 2001
From: Sacha Dujardin
Date: Thu, 5 Sep 2024 07:37:25 +0200
Subject: [PATCH 4/7] fix(README.md): fix dead link
---
p2p/7.Voting-system/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/p2p/7.Voting-system/README.md b/p2p/7.Voting-system/README.md
index 40924a3c..ec623d74 100644
--- a/p2p/7.Voting-system/README.md
+++ b/p2p/7.Voting-system/README.md
@@ -14,7 +14,7 @@ In this workshop we'll learn the basics of solidity with a classic use case: a v
## Step 0: Initialization
-All the required information to install the workshop's dependencies are given in the [SETUP.md](./SETUP.md). To launch the dApp :
+All the required information to install the workshop's dependencies are given in the [setup.md](./setup.md). To launch the dApp :
- Clone the "dApp" folder, afterward:
From f72d0bb8d102a7053a22e22955cbbee57bb3eb06 Mon Sep 17 00:00:00 2001
From: Sacha Dujardin
Date: Fri, 27 Sep 2024 23:55:57 +0200
Subject: [PATCH 5/7] Update README.md
---
p2p/7.Voting-system/README.md | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/p2p/7.Voting-system/README.md b/p2p/7.Voting-system/README.md
index ec623d74..9d3412f8 100644
--- a/p2p/7.Voting-system/README.md
+++ b/p2p/7.Voting-system/README.md
@@ -36,10 +36,18 @@ First, we need to create the core smart contract that will power our decentraliz
Remove the files from `script/`, `src/` and `test` directories. Create `VotingSystem.sol` in the `src/` folder.
-- Create a structure named `Proposal`
->💡 The structure should have 2 variables, `name` and `voteCount`. I let you guess their types.
+- Setup the file by adding this header
+ ```solidity
+ // SPDX-License-Identifier: UNLICENSED
+ pragma solidity ^0.8.26;
+ ```
+
+- Create a contract named `VotingSystem`
+- Declare a structure named `Proposal`
+>💡 The structure should have 2 variables, `name` and `voSteCount`. I let you guess their types.
- On deployment, the contract should take an array of strings as parameters and store them in a `public` array of `Proposals`.
+>💡 A constructor is an optional function that is executed upon contract deployment, you must create one to complete the previous task.
### ✔️ **Validation**:
@@ -53,7 +61,8 @@ if the two tests are good, you can move on the second step !
### 📚 **Documentation**:
- - [Constructors](https://docs.soliditylang.org/en/v0.8.27/contracts.html#constructors)
+- [Header](https://docs.soliditylang.org/en/latest/layout-of-source-files.html)
+- [Constructors](https://docs.soliditylang.org/en/v0.8.27/contracts.html#constructors)
## Step 2: Deploy and integrate it
From 67df9d1e6b1fefac50c398f35ff8a46b2219baef Mon Sep 17 00:00:00 2001
From: Sacha Dujardin
Date: Sat, 28 Sep 2024 00:13:02 +0200
Subject: [PATCH 6/7] Update README.md
---
p2p/7.Voting-system/README.md | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/p2p/7.Voting-system/README.md b/p2p/7.Voting-system/README.md
index 9d3412f8..ca5e6a35 100644
--- a/p2p/7.Voting-system/README.md
+++ b/p2p/7.Voting-system/README.md
@@ -73,6 +73,8 @@ In this step you'll focus on the deployment and the integration part of your sma
### 📌 **Tasks**:
- Using Anvil and forge, deploy your smart contract on a local testnet.
+>💡 On a successful deployment, contract address appear next to the `deployed to` field.
+
- Paste the address of your deployed contract into the environment file at the root of the dApp folder named `VITE_ADDRESS`.
### ✔️ **Validation**:
@@ -82,6 +84,7 @@ Once you have done this, you should now be able to see the parameters you entere
### 📚 **Documentation**:
- [Anvil](https://book.getfoundry.sh/anvil/)
+- [Deploy a Smart Contract local on Anvil with Foundry in 2 min](https://youtu.be/e5QmJaamdPE)
## Step 4: Code the contract
@@ -91,9 +94,8 @@ Crucial step! I'll leave you to code the rest of the contract yourself, so you c
### 📌 **Tasks**:
-- Create a structure `Voter`
-
-- Code the `vote` function. It should take an id in parameter.
+- Create a structure `Voter` containing a boolean named `voted` and an uint `id`.
+- Code the `vote` function. It should take the id of the proposal in parameter.
- Check if the voter had already voted and if the id is correct.
- Add a `voteCount` for the proposal.
From 78929b7d690e8c3904618c9e495d60043ee966fe Mon Sep 17 00:00:00 2001
From: sacharbon
Date: Sat, 28 Sep 2024 00:49:36 +0200
Subject: [PATCH 7/7] fix(voting-system): enhance ui
---
p2p/7.Voting-system/dApp/src/App.vue | 2 +-
p2p/7.Voting-system/dApp/src/components/Card.vue | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/p2p/7.Voting-system/dApp/src/App.vue b/p2p/7.Voting-system/dApp/src/App.vue
index 7836a0ba..7db9b891 100644
--- a/p2p/7.Voting-system/dApp/src/App.vue
+++ b/p2p/7.Voting-system/dApp/src/App.vue
@@ -67,7 +67,7 @@ const voting = async () => {
:winnerIndex="winner"
/>
-