Skip to content

Commit

Permalink
Merge pull request #21 from ShivRaiGithub/login_voting_result_db
Browse files Browse the repository at this point in the history
Created Blockchain Smart Contracts
  • Loading branch information
vigneshs-dev authored Oct 9, 2024
2 parents 2f9a0c7 + 7740d22 commit 08fdda5
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
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
45 changes: 45 additions & 0 deletions Foundry_contracts/.github/workflows/test.yml
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
14 changes: 14 additions & 0 deletions Foundry_contracts/.gitignore
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
80 changes: 80 additions & 0 deletions Foundry_contracts/README.md
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
```


6 changes: 6 additions & 0 deletions Foundry_contracts/foundry.toml
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
1 change: 1 addition & 0 deletions Foundry_contracts/lib/forge-std
Submodule forge-std added at 8f24d6
29 changes: 29 additions & 0 deletions Foundry_contracts/script/Deploy.s.sol
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

50 changes: 50 additions & 0 deletions Foundry_contracts/src/Voting.sol
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;
}

}
64 changes: 64 additions & 0 deletions Foundry_contracts/test/VotingTest.sol
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);
}
}

0 comments on commit 08fdda5

Please sign in to comment.