Skip to content

Commit

Permalink
Ag 26 register election script (#14)
Browse files Browse the repository at this point in the history
* docs(@docs): modified main flow diagram

modified the representation of the entire process in the functional analysis

* docs(@docs): AG-26 typo fix

typo fix in the README file

* feat(@scripts): AG-26 implemented the deploy for the Election smart contract

implemented the ignition module for the deploy of the Election smart contract

* feat(@script): AG-26 municipality election deploy

created the ignition module for the deploy of a municipality election

* feat(@contracts): AG-26 defined methods for municipality election contract

defined properties and methods for the municipality election smart contract

* feat(@contracts): AG-26 election contract modifier implementation

implemented a modifier in the municipality election smart contract

* feat(@contracts): AG-26 municipality election method implementation

implemented the registerParty method in the municipality election smart contract

* refactor(@contracts): AG_26 modified contracts methods

modified the sign of the methods of all the smart contracts

* feat(@contracts): AG-26 municipality election smart contract

implemented the municipality election smart contract

* refactor(@contracts): AG-26 refactored municipality election contract

refactored municipality election smart contract to make it more gas efficient

* feat(@contracts): AG-26 added getter to municipality election contract

added a getter function to the municipality election getter contract

* refactor(@contracts): AG-26 formatted smart contract

formatted smart contract file

* feat(@contracts): AG-26 get coalition in municipality election

implemented a get coalition in the municipality election contract

* refactor(@contracts): AG-26 refactored municipality election contract

refactored municipality election contract

* refactor(@contracts): AG-26 Municipality contract unit test

unit tests implementation for municipality election smart contract

* feat(contracts): AG-26 refactored Municipality Election

modified Municipality Election smart contract deploy

* feat(@contracts): AG-26 Ignition module implementation

ignition module implementation

* style(@contracts): AG-26 contract refactor

refactored formatting of a smart contract

* feat(@contracts): AG-26 MunicipalityElection smart contract deploy script

implementation of the ignition module for the deploy of the MunicipalityElection smart dd contract

* feat(@contracts): AG-26 Create election script definition

defined create-election script that register the data into a given election contract

* feat(@scripts): AG-26 create election script partial implementation

partially implemented the script for the MunicipalityElection smart contract

* feat(@scripts): AG-26 Implemented the create-election script

implemented the create election script

* feat(@script): AG-26 unit test implementation

implemented unit test for create election script

* refactor(@script): improved script

improved script
  • Loading branch information
g3k0 authored Apr 7, 2024
1 parent ed96d8d commit 202b9fa
Show file tree
Hide file tree
Showing 23 changed files with 817 additions and 54 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ To setup the application follow these steps:
3. run `npm run prepare`
4. Write a `.env` file in the root of the project and configure:
* `SEPOLIA_URL` You can find the data in your Alchemy account, after you create an app there;
* `ALCHEMY_API_KEY` You can find the data in your Alchemy account;
* `ALCHEMY_PRIVATE_KEY` You can find the data in your Alchemy account;
* `REPORT_GAS` enable or disable the gas report on smart contracts unit tests executions;
* `NODE_ENV` set `development` for your local machine;

Expand Down Expand Up @@ -77,8 +77,39 @@ To deploy to a specific network (e.g. mainnet, sepora), the network must be conf

For the local network the parameter to pass is `localhost`, there is no need to configure the local network.

## Emulate the whole process using the scrips

# Donations
### Prerequisites

* edit the scripts mocks file: `election-scripts/__mocks__.ts`;
* edit the municipality election contract data, in particular registrationStart and registrationEnd are timestamps in seconds;
* edit the data of the parties and candidates as you prefer;

### 1. The Public Authority / Admin creates the DECs Registry
For the creation of the registry we deploy the DECs Registry smart contract using ignition:

`npm run deploy-contract Registry localhost`;

### 2. The Public Authority / Admin creates the EOA for the Voter
Execute the `create-voter` scripts and take note of the resulting `address` and `privateKey`:

`npx hardhat run election-scripts/create-voter-eoa.ts`

### 3. The Public Authority / Admin creates the DEC for the Voter and register the DEC into the DECs Registry
[TO DO]

### 4. The Public Authority / Admin creates a Municipality Election
At this point we have the EOA credentials and the DEC for our voters, and the DECs are registered on the DECs Registry. It's time to create an election: as an example we implemented a smart contract for a municipality election, that elects the major and the council.

Now it's time to deploy the smart contract election and register parties, councilor and major candidates, parties coalitions in the municipality election contract, run the command:

`npx hardhat run election-scripts/create-election.ts`

Please note that to make the registration of parties and coalition working, the functions must be called in the registration period set before.



## Donations
Support this project and offer me a crypto-coffee!!

![wallet](docs/assets/wallet_address.png)
Expand Down
7 changes: 6 additions & 1 deletion contracts/CountryElection.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import "./Election.sol";
/// @custom:experimental This is an experimental contract.
contract CountryElection is Election {

constructor(uint256 _electionStart, uint256 _electionEnd) Election(_electionStart, _electionEnd) {
constructor(
string memory _name,
uint256 _registrationStart,
uint256 _registrationEnd,
uint8 _votingPoints
) Election(_name, _registrationStart, _registrationEnd, _votingPoints) {

}

Expand Down
16 changes: 8 additions & 8 deletions contracts/DEC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,35 @@ contract DEC {
_;
}

function setTaxCode(bytes memory _taxCode) public onlyOwner {
function setTaxCode(bytes memory _taxCode) external onlyOwner {
taxCode = _taxCode;
}

function getTaxCode() public view returns (bytes memory) {
function getTaxCode() external view returns (bytes memory) {
return taxCode;
}

function setMunicipality(bytes memory _municipality) public onlyOwner {
function setMunicipality(bytes memory _municipality) external onlyOwner {
municipality = _municipality;
}

function getMunicipality() public view returns (bytes memory) {
function getMunicipality() external view returns (bytes memory) {
return municipality;
}

function setRegion(bytes memory _region) public onlyOwner {
function setRegion(bytes memory _region) external onlyOwner {
region = _region;
}

function getRegion() public view returns (bytes memory) {
function getRegion() external view returns (bytes memory) {
return region;
}

function setCountry(bytes memory _country) public onlyOwner {
function setCountry(bytes memory _country) external onlyOwner {
country = _country;
}

function getCountry() public view returns (bytes memory) {
function getCountry() external view returns (bytes memory) {
return country;
}

Expand Down
12 changes: 6 additions & 6 deletions contracts/DECsRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ contract DECsRegistry {
}

/// @notice DECs REgistry name setter function
function setName(string memory _name) public onlyOwner {
function setName(string memory _name) external onlyOwner {
name = _name;
}

/// @notice DECs REgistry name getter function
function getName() public view returns (string memory) {
function getName() external view returns (string memory) {
return name;
}

/// @notice this function is used by the third party authority to register a Voter's DEC in the registry
function registerDEC(address dec, address voter) public onlyOwner {
function registerDEC(address dec, address voter) external onlyOwner {
require(
registry[voter] == address(0),
"The Voter's DEC has been already registered"
Expand All @@ -54,7 +54,7 @@ contract DECsRegistry {
}

/// @notice this function returns an encrypted DEC in order to check if a Voter has the voting rights
function getDEC(address voter) public view returns (address) {
function getDEC(address voter) external view returns (address) {
require(
registry[voter] != address(0),
"The Voter don't have a registered DEC"
Expand All @@ -66,7 +66,7 @@ contract DECsRegistry {
function hasVoterAlreadyVoted(
address voter,
address election
) public view returns (bool) {
) external view returns (bool) {
for (uint i = 0; i < electoralStamps[voter].length; i++) {
if (electoralStamps[voter][i] == election) {
return true;
Expand All @@ -76,7 +76,7 @@ contract DECsRegistry {
}

/// @notice this function put the election stamp on the Voter's stamps list after the vote
function stamps(address election, address voter) public onlyOwner {
function stamps(address election, address voter) external onlyOwner {
electoralStamps[voter].push(election);
emit DECStamped(election, voter);
return;
Expand Down
66 changes: 55 additions & 11 deletions contracts/Election.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,29 @@ pragma solidity ^0.8.24;
/// @custom:experimental This is an experimental contract.
contract Election {
address public owner;
uint256 private electionStart;
uint256 private electionEnd;
string public name;
uint256 public electionStart;
uint256 public electionEnd;
uint256 public registrationStart;
uint256 public registrationEnd;
uint8 private votingPoints;
mapping (uint256 => string) private ballotBox; // change the data types later
mapping (uint256 => string) results; // change the data types later

constructor(uint256 _electionStart, uint256 _electionEnd) {
constructor(
string memory _name,
uint256 _registrationStart,
uint256 _registrationEnd,
uint8 _votingPoints
) {
require(_registrationStart < _registrationEnd, "The registration start date can't be equal or after the registration end date");
require(_votingPoints > 19, "It is not possible to assing less that 20 voting points for the election");

owner = msg.sender;
electionStart = _electionStart;
electionEnd = _electionEnd;
name = _name;
registrationStart = _registrationStart;
registrationEnd = _registrationEnd;
votingPoints = _votingPoints;
}

modifier onlyOwner() {
Expand All @@ -28,18 +42,29 @@ contract Election {
return (block.timestamp >= electionStart && block.timestamp <= electionEnd);
}

/// @notice this function checks if the transaction occours when the registration are open
function isIvokedInRegistrationPeriod() private view returns (bool) {
return (block.timestamp >= registrationStart && block.timestamp <= registrationEnd);
}

/// @notice this function checks if the transaction occours after the election is closed
function isElectionClosed() private view returns (bool) {
return block.timestamp > electionEnd;
}

function setElectionStart(uint256 _electionStart) public onlyOwner {
/// @notice this function checks if the transaction occours after the registration is closed
function isRegistrationClosed() private view returns (bool) {
return block.timestamp > registrationEnd;
}

function setElectionStart(uint256 _electionStart) external onlyOwner {
require(block.timestamp > registrationEnd, "Elections can't start before the end of the registration process");
require(!isIvokedInElectionPeriod(), "Elections have already started, it's too late for changing the start of the elections");
require(!isElectionClosed(), "Elections are closed, it's not possible to change the start of the elections");
electionStart = _electionStart;
}

function getElectionStart() public view returns (uint256) {
function getElectionStart() external view returns (uint256) {
return electionStart;
}

Expand All @@ -49,19 +74,38 @@ contract Election {
electionEnd = _electionEnd;
}

function getElectionEnd() public view returns (uint256) {
function getElectionEnd() external view returns (uint256) {
return electionEnd;
}

function setRegistrationStart(uint256 _registrationStart) external onlyOwner {
require(!isIvokedInRegistrationPeriod(), "Registrations have already started, it's too late for changing the start of the registration");
require(!isRegistrationClosed(), "Registration are closed, it's not possible to change the start of the registration");
registrationStart = _registrationStart;
}

function getRegistrationStart() external view returns (uint256) {
return registrationStart;
}

function setRegistrationEnd(uint256 _registrationEnd) public onlyOwner {
require(!isIvokedInRegistrationPeriod(), "Registrations have already started, it's too late for changing the end of the registration");
require(!isRegistrationClosed(), "Registrations are closed, it's not possible to change the end of the registration");
registrationEnd = _registrationEnd;
}

function getRegistrationEnd() external view returns (uint256) {
return registrationEnd;
}

/// @notice this function collects the ballots
function vote() public view {
function vote() external view {
require(isIvokedInElectionPeriod(), "Elections are not open");
require(!isElectionClosed(), "Elections are closed");
}

/// @notice this function calculates the elections results
function scrutiny() public view onlyOwner {
require(!isIvokedInElectionPeriod(), "Elections are in progress, it's not possible to calculate the results");
function scrutiny() external view onlyOwner {
require(isElectionClosed(), "Scrutiny is possible only after the elections end");
}
}
Loading

0 comments on commit 202b9fa

Please sign in to comment.