-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from ShivRaiGithub/login_voting_result_db
Created Blockchain Smart Contracts
- Loading branch information
Showing
9 changed files
with
292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "Foundry_contracts/lib/forge-std"] | ||
path = Foundry_contracts/lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
pull_request: | ||
workflow_dispatch: | ||
|
||
env: | ||
FOUNDRY_PROFILE: ci | ||
|
||
jobs: | ||
check: | ||
strategy: | ||
fail-fast: true | ||
|
||
name: Foundry project | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Install Foundry | ||
uses: foundry-rs/foundry-toolchain@v1 | ||
with: | ||
version: nightly | ||
|
||
- name: Show Forge version | ||
run: | | ||
forge --version | ||
- name: Run Forge fmt | ||
run: | | ||
forge fmt --check | ||
id: fmt | ||
|
||
- name: Run Forge build | ||
run: | | ||
forge build --sizes | ||
id: build | ||
|
||
- name: Run Forge tests | ||
run: | | ||
forge test -vvv | ||
id: test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Compiler files | ||
cache/ | ||
out/ | ||
|
||
# Ignores development broadcast logs | ||
!/broadcast | ||
/broadcast/*/31337/ | ||
/broadcast/**/dry-run/ | ||
|
||
# Docs | ||
docs/ | ||
|
||
# Dotenv file | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
## Voting.sol | ||
User deploys a contract as owner. User can add candidates for Voting who will be provided with array index as their id. Other users can vote once on a candidate of their choice. | ||
|
||
## Foundry | ||
|
||
**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** | ||
|
||
Foundry consists of: | ||
|
||
- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). | ||
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. | ||
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. | ||
- **Chisel**: Fast, utilitarian, and verbose solidity REPL. | ||
|
||
|
||
## Useful Commands For this Project | ||
|
||
### Compiling | ||
|
||
```shell | ||
forge compile | ||
``` | ||
|
||
### Test | ||
|
||
```shell | ||
forge test | ||
``` | ||
|
||
### Anvil | ||
|
||
```shell | ||
anvil | ||
``` | ||
|
||
### Deploy | ||
|
||
```shell | ||
forge script script/Deploy.s.sol --rpc-url <your_rpc_url> --private-key <your_private_key> | ||
``` | ||
|
||
### Sample execution (Be within `Foundry_contracts`) | ||
|
||
1) Compile using : | ||
```shell | ||
forge compile | ||
``` | ||
2) (Optional) Test using : | ||
```shell | ||
forge test | ||
``` | ||
Note: It will automatically compile on test if not done so. | ||
|
||
3) Split terminal into 2. | ||
4) Use following command to spin up a local-chain to work on: | ||
```shell | ||
anvil | ||
``` | ||
5) Make sure anvil is working. | ||
6) Deploy using : | ||
```shell | ||
forge script script/Deploy.s.sol --rpc-url <your_rpc_url> --private-key <your_private_key> --broadcast | ||
``` | ||
Note: Sample command provided in script/Deploy.s.sol as comment. You can get private key and rpc url from anvil itself. | ||
|
||
|
||
## Documentation | ||
|
||
https://book.getfoundry.sh/ | ||
|
||
|
||
### Help | ||
|
||
```shell | ||
$ forge --help | ||
$ anvil --help | ||
$ cast --help | ||
``` | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[profile.default] | ||
src = "src" | ||
out = "out" | ||
libs = ["lib"] | ||
|
||
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.27; | ||
|
||
import {Script, console} from "forge-std/Script.sol"; | ||
import {Voting} from "../src/Voting.sol"; | ||
|
||
contract Deploy is Script { | ||
Voting public voting; | ||
|
||
function run() public returns(Voting) { | ||
// Function caller deploys Voting contract | ||
vm.startBroadcast(msg.sender); | ||
voting = new Voting(); | ||
|
||
voting.addCandidate(); | ||
voting.addCandidate(); | ||
voting.addCandidate(); | ||
voting.addCandidate(); | ||
|
||
vm.stopBroadcast(); | ||
console.log(voting.owner()); | ||
return (voting); | ||
} | ||
} | ||
|
||
|
||
// To deploy on anvil ( local chain ) with anvil's private key: | ||
// forge script script/Deploy.s.sol --fork-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.27; | ||
|
||
contract Voting { | ||
|
||
// owner of contract | ||
address public owner; | ||
|
||
// Users who have voted or not | ||
mapping(address => bool) public Voted; | ||
|
||
// Array to count number of votes for each candidate | ||
// Candidate Id = Array index | ||
uint256[] public candidates; | ||
|
||
// Constructor | ||
constructor() { | ||
owner = msg.sender; | ||
} | ||
|
||
// Errors | ||
error Voting__NotOwner(); | ||
error Voting__AlreadyVoted(); | ||
error Voting__IncorrectVoteIndex(); | ||
|
||
// Modifier to check if the caller is the owner | ||
modifier ownerOnly(){ | ||
require(msg.sender == owner, Voting__NotOwner()); | ||
_; | ||
} | ||
|
||
// Owner is able to add candidatest to the election | ||
function addCandidate() public ownerOnly { | ||
candidates.push(0); | ||
} | ||
|
||
// Any user can vote only once to a valid candidate | ||
function vote(uint _voteIndex) public { | ||
require(!Voted[msg.sender], Voting__AlreadyVoted()); | ||
require(_voteIndex<candidates.length, Voting__IncorrectVoteIndex()); | ||
Voted[msg.sender] = true; | ||
candidates[_voteIndex] += 1; | ||
} | ||
|
||
// Get candidates array which shows the votes gotten by each Candidate | ||
function getVotes() public view returns (uint256[] memory) { | ||
return candidates; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.27; | ||
|
||
import "forge-std/Test.sol"; | ||
import "../src/Voting.sol"; | ||
|
||
contract VotingTest is Test { | ||
Voting voting; | ||
address owner = makeAddr("Owner"); | ||
address voter1 = makeAddr("Voter1"); | ||
|
||
function setUp() public { | ||
vm.prank(owner); | ||
voting = new Voting(); | ||
} | ||
|
||
function testOwnerIsCorrect() public view{ | ||
assertEq(voting.owner(), owner); | ||
} | ||
|
||
function testAddCandidateAsOwner() public { | ||
vm.startPrank(owner); | ||
voting.addCandidate(); | ||
voting.addCandidate(); | ||
vm.stopPrank(); | ||
|
||
uint256[] memory candidates = voting.getVotes(); | ||
assertEq(candidates.length, 2); | ||
} | ||
|
||
function testAddCandidateNotOwner() public { | ||
vm.expectRevert(Voting.Voting__NotOwner.selector); | ||
voting.addCandidate(); | ||
} | ||
|
||
function testVote() public { | ||
vm.prank(owner); | ||
voting.addCandidate(); | ||
|
||
vm.prank(voter1); | ||
voting.vote(0); | ||
|
||
uint256[] memory candidates = voting.getVotes(); | ||
assertEq(candidates.length, 1); | ||
assertEq(candidates[0], 1); | ||
} | ||
|
||
function testVoteTwice() public { | ||
vm.prank(owner); | ||
voting.addCandidate(); | ||
|
||
vm.startPrank(voter1); | ||
voting.vote(0); | ||
vm.expectRevert(Voting.Voting__AlreadyVoted.selector); | ||
voting.vote(0); | ||
vm.stopPrank(); | ||
} | ||
|
||
function testVoteWithInvalidCandidate() public { | ||
vm.prank(voter1); | ||
vm.expectRevert(Voting.Voting__IncorrectVoteIndex.selector); | ||
voting.vote(100); | ||
} | ||
} |