Skip to content

Commit

Permalink
Develop (#15)
Browse files Browse the repository at this point in the history
* Ag 17 commitlint fix (#1)

* fix(@script): AG-17 changed script logic

changed script login the commit script

* fix(@script): AG-17 changed script

modified some logic in the script folder

* docs(@agora): modified readme

modified readme

* feat(@agora): AG-35 basic workflow (#3)

* feat(@agora): AG-35 basic workflow

basic GitHub Actions workflow implementation

* feat(@agora): AG-35 duplicated code

inserted duplicated code check in ci-cd

* docs(@agora): AG-35 updloaded image (#5)

uploaded image for functional analysis

* Ag 18 eoa implementation (#7)

* feat(@script): AG-18 EOA script implementation

implemented script in order to generate an EOA over different ethereum networks configured

* test(@script): AG-18 unit test configuration

unit test configuration for scripts using jest

* test(@agora): AG-18 configured test step in workflow

configured workflow to run script unit test

* test(@script): AG-18 configured commit script

configured pre-commit hook script to run unit test

* test(@script): AG-18 unit test implementation

implemented unit test for eoa script

* test(@script): AG-18 code coverage

unit test code coverage report implementation

* refactor(@script): AG-18 precommit hook

added check in pre-commit hook

* fix(@script): AG-18 fixed unit test threshold

fixed unit test code coverage threshold

* fix(@agora): AG-18 fixed package.json

fixed package json property not used

* fix(@agora): AG-18 fixed unit test

n

* fix(@agora): AG-18 fixed workflow

fixed workflow

* refactor(@script): AG-18 test code coverage threshold

test code coverage threshold

* docs(@agora): AG-18 updated readme

updated readme file

* Ag 19 DECsRegistry smart contract (#8)

* fix(@script): AG-19 removed comments

removed code comments

* docs(@docs): AG-19 updated sequence diagrams

updated the sequence diagrams images for the functional analysis

* docs(@docs): AG-19 updated smart contract classes

updated docs about the smart contracts classes

* feat(@contracts): AG-19 DEC contract implementation

implemented a first version of the DEC contract

* feat(@contracts): AG-19 added events to DEC sc

emitted event in the DEC smart contract implementation

* feat(@contracts): AG-19 implemented DEC contract

implemented DEC contract and related unit tests

* fix(@contracts): AG-19 removed event

removed event not used in DEC contract

* feat(@contracts): AG-19 DECs registry implementation

implemented the register of the DECs with the required methods

* test(@contracts): AG-19 defined test for DECsRegistry contract

defined test structure for the DECsRegistry smart contract

* test(@contracts): AG-19 implemented unit test

implemented unit tests for DECsRegistry smart contract

* feat(@contracts): AG-19 added events to smart contract

added events to the DECsRegistry smart contract

* Ag 20 election smart contract (#9)

* refactor(@agora): AG-20 switched test network

switched from legacy goerli test network to sepolia

* docs(@docs): AG-20 updated analysis diagrams

updated diagrams in the functional analysis

* feat(@contracts): AG-20 Election smart contract

implemented Election smart contract with unit tests

* feat(@contracts): AG-20 Elections smart contracts

implemeneted different smart contracts for different kind of elections

* docs(@docs): AG-20 addded diagrams files to docs

added diagrams file to the docs folder

* docs(@docs): AG-20 updated class diagrams

updated the smart contracts class diagrams

* Ag 20 election smart contract (#10)

* refactor(@agora): AG-20 switched test network

switched from legacy goerli test network to sepolia

* docs(@docs): AG-20 updated analysis diagrams

updated diagrams in the functional analysis

* feat(@contracts): AG-20 Election smart contract

implemented Election smart contract with unit tests

* feat(@contracts): AG-20 Elections smart contracts

implemeneted different smart contracts for different kind of elections

* docs(@docs): AG-20 addded diagrams files to docs

added diagrams file to the docs folder

* docs(@docs): AG-20 updated class diagrams

updated the smart contracts class diagrams

* fix(@agora): AG-20 updated version number

updated version number in package json

* Ag 25 deploy contracts (#13)

* feat(@agora): AG-25 configured evm compiler

configured the evm compiler in the hardhat configuration file

* refactor(@contracts): AG-25 refactored DECs Registry contract

refactored DECs registry contract

* refactor(@contracts): AG-25 refactored DEC contract

refactored DEC smart contract

* feat(@contracts): AG-25 added name property to DECs Registry

added name property to DECs Registry smart contract

* feat(@contracts): ignition modules implementation

implemented the ignition modules for contracts deploy

* fix(@contracts): AG-25 added folder to gitignore

added foldet to gitignore

* fix(@contracts): AG-25 ignored files

added files to gitignore

* Ag 26 register election script (#14)

* 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 f34a355 commit dadbfb4
Show file tree
Hide file tree
Showing 30 changed files with 1,137 additions and 135 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ node_modules
/coverage.json

# reports folder
report
report

#ignition files
/ignition/deployments
62 changes: 60 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ 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;

## How to commit

Expand All @@ -51,7 +52,64 @@ Smart contracts code coverage documentation [here](https://www.npmjs.com/package

CI/CD workflow fails if the unit test code coverage threshold (**80% of lines of code**) for scripts is not met.

# Donations
## Run the localhost development network

Hardhat framework provides a local blockchain network that lives in memory, that is useful to test local developments.
To start the network run the command:

`npm run node:start`

## Compile the smart contracts

Run the command: `npm run compile`

## Deploy the smart contract

The smart contracts deploy process is managed, under the hood, by [Ignition](https://hardhat.org/ignition/docs/getting-started#overview).

To deploy smart contract instances run the command:

`npm run deploy-contract <ignition-module-path> <network>`

Ignition will deploy the instances of the smart contract following the logic specified in the ignition module.

To deploy to a specific network (e.g. mainnet, sepora), the network must be configured in the `hardhat.config.ts` file.

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

### 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
76 changes: 38 additions & 38 deletions contracts/DEC.sol
Original file line number Diff line number Diff line change
@@ -1,66 +1,66 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

/// @title The Voter's Digital Electoral Cards
/// @title The Voter's Digital Electoral Card
/// @author Christian Palazzo <palazzochristian@yahoo.it>
/// @custom:experimental This is an experimental contract.
contract DEC {
address public owner;
bytes taxCode;
bytes municipality;
bytes region;
bytes country;

constructor() {
constructor(
bytes memory _taxCode,
bytes memory _municipality,
bytes memory _region,
bytes memory _country
) {
/// @dev only the owner of the contract has write permissions
owner = msg.sender;
taxCode = _taxCode;
municipality = _municipality;
region = _region;
country = _country;
}

modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}

/// @notice This is the Digital Electoral Card, emitted by a public third-party authority and owned by the Voter
/// @dev This data is encrypted with the Voter's public address and only the Voter can decrypt it using the private key
struct decData {
string taxCode;
string municipality;
string province;
string region;
string country;
function setTaxCode(bytes memory _taxCode) external onlyOwner {
taxCode = _taxCode;
}

event DECEncrypted(address indexed owner, bytes encryptedData);
function getTaxCode() external view returns (bytes memory) {
return taxCode;
}

/// @notice This function is used to encrypt ad digitally sign a DEC
function encryptDEC(
decData memory dec
) public onlyOwner returns (bytes memory) {
bytes memory encodedData = abi.encodePacked(
dec.taxCode,
dec.municipality,
dec.province,
dec.region,
dec.country
);
bytes32 hashedData = keccak256(encodedData);
bytes memory signature = signData(hashedData);
function setMunicipality(bytes memory _municipality) external onlyOwner {
municipality = _municipality;
}

emit DECEncrypted(msg.sender, abi.encodePacked(hashedData, signature));
function getMunicipality() external view returns (bytes memory) {
return municipality;
}

return abi.encodePacked(hashedData, signature);
function setRegion(bytes memory _region) external onlyOwner {
region = _region;
}

/// @notice This function is used to digitally sign the data
function signData(bytes32 data) private pure returns (bytes memory) {
bytes32 hash = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", data)
);
bytes1 v = bytes1(0);
bytes32 r = bytes32(0);
bytes32 s = uintToBytes32(1);
return abi.encodePacked(ecrecover(hash, uint8(v), r, s), r, s);
function getRegion() external view returns (bytes memory) {
return region;
}

/// @notice this function is used in signData function
function uintToBytes32(uint256 x) private pure returns (bytes32) {
return bytes32(x);
function setCountry(bytes memory _country) external onlyOwner {
country = _country;
}

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


}
52 changes: 36 additions & 16 deletions contracts/DECsRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,57 @@ import "./DEC.sol";
/// @title The Registry of the Digital Electoral Cards
/// @author Christian Palazzo <palazzochristian@yahoo.it>
/// @custom:experimental This is an experimental contract.
contract DECsRegistry is DEC {
constructor() DEC() {}
contract DECsRegistry {
address public owner;
string public name;

/// @notice this is the list of stamps of elections in which the voter participated
/// @dev the first address is related to the Voter's EOA, the second array is the Voter's stamps list
/// @dev the first address is related to the Voter's DEC, the second array is the Voter's stamps list
mapping(address => address[]) electoralStamps;

/// @notice this function contains the list of DECs
/// @dev the address is related to the Voter's EOA
mapping(address => bytes) registry;
/// @dev the first address is related to the Voter's EOA, the second address is related to the DEC
mapping(address => address) registry;

event DECRegistered(address indexed voter, bytes dec);
event DECRegistered(address indexed voter, address dec);
event DECStamped(address indexed election, address indexed voter);

constructor(string memory _name) {
/// @dev only the owner of the contract has write permissions
owner = msg.sender;
name = _name;
}

modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}

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

/// @notice DECs REgistry name getter function
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
/// @dev the DEC contains sensitive data that must be encrypted
function registerDEC(decData memory dec, address voter) public onlyOwner {
function registerDEC(address dec, address voter) external onlyOwner {
require(
registry[voter].length == 0,
registry[voter] == address(0),
"The Voter's DEC has been already registered"
);
registry[voter] = encryptDEC(dec);
registry[voter] = dec;
emit DECRegistered(voter, registry[voter]);
return;
}

/// @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 (bytes memory) {
function getDEC(address voter) external view returns (address) {
require(
registry[voter].length != 0,
registry[voter] != address(0),
"The Voter don't have a registered DEC"
);
return registry[voter];
Expand All @@ -45,7 +66,7 @@ contract DECsRegistry is DEC {
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 @@ -54,9 +75,8 @@ contract DECsRegistry is DEC {
return false;
}

/// @notice this function put the election stamp on the Voter's DEC after the vote
/// @dev the owner of the DECs registry is the same of the election smart contract (third party authority)
function stampsTheDEC(address election, address voter) public onlyOwner {
/// @notice this function put the election stamp on the Voter's stamps list after the vote
function stamps(address election, address voter) external onlyOwner {
electoralStamps[voter].push(election);
emit DECStamped(election, voter);
return;
Expand Down
Loading

0 comments on commit dadbfb4

Please sign in to comment.