Skip to content

Commit 4feefe5

Browse files
committed
contract setup
1 parent 3a4fa19 commit 4feefe5

File tree

11 files changed

+320
-157
lines changed

11 files changed

+320
-157
lines changed

Diff for: components/Sidebar.js

+67-47
Original file line numberDiff line numberDiff line change
@@ -3,97 +3,117 @@ import React from "react";
33
import Link from "next/link";
44
import logo from "../public/logo.png";
55
import Image from "next/image";
6-
import { TemplateIcon } from '@heroicons/react/outline'
7-
import { Settings, Moon, Clock, Edit, Menu, ToggleLeft, ToggleRight, LogOut, AlignLeft } from 'react-feather'
6+
import { TemplateIcon } from "@heroicons/react/outline";
7+
import {
8+
Settings,
9+
Moon,
10+
Clock,
11+
Edit,
12+
Menu,
13+
ToggleLeft,
14+
ToggleRight,
15+
LogOut,
16+
AlignLeft,
17+
} from "react-feather";
818
import SidebarItem from "./SidebarItem";
919
import { CreatePoll, FillPoll, History } from "./Icons";
1020
import Header from "./Header";
1121
import Toggler from "./Toggler";
1222

1323
export const routes = [
1424
{
15-
name:"Dashboard",
16-
path:"/dashboard",
25+
name: "Dashboard",
26+
path: "/dashboard",
1727
icon: <TemplateIcon width={20} height={20} strokeWidth={1} />,
18-
toggle:null
28+
toggle: null,
1929
},
2030
{
21-
name:"Create a Poll",
22-
path:"/create-poll",
23-
icon:CreatePoll,
24-
toggle:null
31+
name: "Create a Poll",
32+
path: "/create-poll",
33+
icon: CreatePoll,
34+
toggle: null,
2535
},
2636
{
27-
name:"Fill a Poll",
28-
path:"/fill-poll",
37+
name: "Fill a Poll",
38+
path: "/fill-poll",
2939
icon: FillPoll,
30-
toggle:null
40+
toggle: null,
3141
},
3242
{
33-
name:"Poll History",
34-
path:"/poll-history",
35-
icon:History,
36-
toggle:null
43+
name: "Poll History",
44+
path: "/poll-history",
45+
icon: History,
46+
toggle: null,
3747
},
3848
{
39-
name:"Settings",
40-
path:"/settings",
41-
icon:<Settings strokeWidth={1} />,
42-
toggle:null
49+
name: "Settings",
50+
path: "/settings",
51+
icon: <Settings strokeWidth={1} />,
52+
toggle: null,
4353
},
4454
{
45-
name:"Dark Mode",
46-
path:"#",
47-
icon:<Moon strokeWidth={1} />,
48-
toggle: <Toggler/>
49-
}
50-
]
55+
name: "Dark Mode",
56+
path: "#",
57+
icon: <Moon strokeWidth={1} />,
58+
toggle: <Toggler />,
59+
},
60+
];
5161

52-
export default function Sidebar() {
62+
function Sidebar() {
5363
const [collapseShow, setCollapseShow] = React.useState(false);
5464
return (
5565
<>
56-
<nav className={(collapseShow && 'active ')+" transition-all sidebar justify-between flex flex-col left-0 fixed top-0 bottom-0 overflow-hidden shadow-xl bg-white w-74 z-10 py-4 px-6 pr-16"}>
66+
<nav
67+
className={
68+
(collapseShow && "active ") +
69+
" transition-all sidebar justify-between flex flex-col left-0 fixed top-0 bottom-0 overflow-hidden shadow-xl bg-white w-74 z-10 py-4 px-6 pr-16"
70+
}
71+
>
5772
<div>
58-
59-
6073
{/* Brand */}
6174
<div className="flex justify-between">
6275
<Link href="/">
6376
<a className="text-primary flex items-center font-bold">
64-
<Image src={logo} width={80} height={80}/>
77+
<Image src={logo} width={80} height={80} />
6578
Votechain
6679
</a>
6780
</Link>
68-
81+
6982
{/* Toggler */}
7083
<button
7184
className="cursor-pointer text-black ml-3 mt-2 fixed left-64 top-8 left lg:hidden"
7285
type="button"
73-
onClick={() => setCollapseShow(!collapseShow)}>
74-
<AlignLeft className="text-gray-400" width={30} height={30}/>
86+
onClick={() => setCollapseShow(!collapseShow)}
87+
>
88+
<AlignLeft className="text-gray-400" width={30} height={30} />
7589
</button>
7690
{/* Toggler */}
7791
</div>
7892
{/* Brand */}
79-
80-
{/* Collapse */}
81-
<ul className="md:min-w-full list-none">
82-
{routes.map((route,i) => (
83-
<SidebarItem route={route} key={route.name}/>
84-
))}
85-
</ul>
86-
{/* Collapse */}
8793

88-
</div>
8994
{/* Collapse */}
90-
<ul className="md:min-w-full list-none">
91-
<SidebarItem route={{name:"Log out", path:"/logout", icon:<LogOut color="red" strokeWidth={1}/>}}/>
92-
</ul>
95+
<ul className="md:min-w-full list-none">
96+
{routes.map((route, i) => (
97+
<SidebarItem route={route} key={route.name} />
98+
))}
99+
</ul>
93100
{/* Collapse */}
94-
101+
</div>
102+
{/* Collapse */}
103+
<ul className="md:min-w-full list-none">
104+
<SidebarItem
105+
route={{
106+
name: "Log out",
107+
path: "/logout",
108+
icon: <LogOut color="red" strokeWidth={1} />,
109+
}}
110+
/>
111+
</ul>
112+
{/* Collapse */}
95113
</nav>
96114
<Header />
97115
</>
98116
);
99117
}
118+
119+
export default Sidebar;

Diff for: contracts/Voting.sol

+36-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
//SPDX-License-Identifier: Unlicense
22
pragma solidity ^0.8.0;
33

4-
import "hardhat/console.sol";
5-
64
// TODO: Ensure options count from one
75
contract Voting {
86
// structs
9-
struct VoteOptions{
7+
struct VoteOption{
108
string name;
9+
uint count;
1110
}
1211
struct Poll {
1312
address owner;
@@ -17,7 +16,7 @@ contract Voting {
1716
uint end_time;
1817
uint fee;
1918
uint option_count; // Number of options
20-
mapping(uint => VoteOptions ) options; // mapping of index+1(option_id) to options (should start from 1)
19+
mapping(uint => VoteOption ) options; // mapping of index+1 to options (should start from 1)
2120
mapping(address => uint ) votes; // mapping of address to option_id (should start from 1)
2221
}
2322

@@ -34,28 +33,51 @@ contract Voting {
3433
address public owner;
3534

3635
// events
37-
event createPollEvt(uint pollId, address owner, string name, string description, uint start_time, uint end_time, uint fee);
36+
event createPollEvt(uint pollId, address owner, string name, string description, uint start_time, uint end_time, uint fee, string[] options);
3837

3938
constructor() {
4039
owner = msg.sender;
4140
}
4241

42+
// Private Functions
43+
function validStr(string memory str) private pure returns(bool isValid) {
44+
return bytes(str).length >= 1;
45+
}
46+
4347
// Public Functions
44-
function createPoll(string memory name, string memory description, uint start_time, uint end_time, uint fee) public {
45-
// check end time after start time
48+
function createPoll(string memory name, string memory description, uint start_time, uint end_time, uint fee, string[] memory options) public {
49+
// Check string length
50+
assert(validStr(name) && validStr(description));
51+
// Check end time after start time
52+
assert(end_time >= start_time);
4653
// Check more than one option
47-
emit createPollEvt(polls_created, msg.sender, name, description, start_time, end_time, fee);
54+
assert(options.length >= 2);
55+
// Check that options have valid names
56+
for (uint i=0; i<options.length; i++) {
57+
assert(validStr(options[i]));
58+
}
59+
60+
// Adding the poll
4861
Poll storage newPoll = polls[polls_created];
4962
newPoll.owner = msg.sender;
5063
newPoll.name = name;
5164
newPoll.description = description;
5265
newPoll.start_time = start_time;
5366
newPoll.end_time = end_time;
5467
newPoll.fee = fee;
68+
newPoll.option_count = options.length;
69+
70+
// Adding the poll options
71+
for (uint i=0; i<options.length; i++) {
72+
VoteOption storage option = newPoll.options[newPoll.option_count+1];
73+
option.name = options[i];
74+
}
75+
76+
77+
emit createPollEvt(polls_created, msg.sender, name, description, start_time, end_time, fee, options);
5578

5679
// Increment poll id
5780
polls_created++;
58-
console.log("New pollId is '%s'", polls_created);
5981
}
6082

6183
function getUser() public view returns(string memory username) {
@@ -64,6 +86,7 @@ contract Voting {
6486

6587
function createUser(string memory username) public{
6688
// Make checks to ensure user name is not empty && not taken && address not registered
89+
assert(validStr(username));
6790
address_to_username[msg.sender] = username;
6891
username_to_address[username] = msg.sender;
6992
}
@@ -88,4 +111,8 @@ contract Voting {
88111
}
89112
return (names, descriptions, start_times, end_times, fees);
90113
}
114+
115+
function recentPoll() public view returns(uint num){
116+
return polls_created;
117+
}
91118
}

Diff for: hardhat.config.js

+12
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
1616
/**
1717
* @type import('hardhat/config').HardhatUserConfig
1818
*/
19+
const privateKey = "";
1920
module.exports = {
2021
solidity: "0.8.4",
22+
defaultNetwork: "hardhat",
23+
networks: {
24+
hardhat: {
25+
chainId: 1337,
26+
},
27+
mumbai: {
28+
url: "https://rpc-mumbai.maticvigil.com/",
29+
chainId: 80001,
30+
accounts: [privateKey],
31+
},
32+
},
2133
};

Diff for: hooks/useRedirectLogin.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { useRouter } from "next/router";
2+
import { useEffect, useState } from "react";
3+
import routeNames from "../routes";
4+
5+
export const useRedirectLogin = () => {
6+
const [pageLoading, setPageLoading] = useState(true);
7+
const router = useRouter();
8+
const isAuthRoute = router.pathname === routeNames.login;
9+
10+
useEffect(() => {
11+
const connectedWallet = !window.ethereum.selectedAddress === null;
12+
if (!isAuthRoute && !connectedWallet) {
13+
router.push(routeNames.login);
14+
setPageLoading(false);
15+
} else {
16+
setPageLoading(false);
17+
}
18+
}, []);
19+
return { pageLoading };
20+
};

Diff for: hooks/useVoting.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { ethers } from "ethers";
2+
import Web3Modal from "web3modal";
3+
import Voting from "../artifacts/contracts/Voting.sol/Voting.json";
4+
5+
const useVoting = async () => {
6+
const web3Modal = new Web3Modal({
7+
network: "mumbai",
8+
});
9+
10+
const connection = await web3Modal.connect();
11+
12+
const provider = new ethers.providers.Web3Provider(connection);
13+
14+
const signer = provider.getSigner();
15+
16+
const contract = new ethers.Contract(
17+
"0x750f58AE83885b2f6Fe2Fb709d7A1aD37107Fc27",
18+
Voting.abi,
19+
signer
20+
);
21+
return { contract };
22+
};
23+
24+
export default useVoting;

Diff for: package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
7-
"build": "next build",
7+
"build": "npx hardhat compile && next build",
88
"start": "next start",
9-
"lint": "next lint"
9+
"lint": "next lint",
10+
"test": "hardhat test"
1011
},
1112
"dependencies": {
1213
"@headlessui/react": "^1.4.0",

0 commit comments

Comments
 (0)