Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ag 39 encrypt dec data #20

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: 20.x

- name: Set up Git
run: |
git config --global user.email "nova.web3.collective@gmail.com"
git config --global user.name "nova collective"
- name: Install dependencies
run: node ci --function installDeps
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ For the local network the parameter to pass is `localhost`, there is no need to
* 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;
* edit the data of the Voter 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:
Expand All @@ -104,7 +105,10 @@ Execute the `create-voter` scripts and take note of the resulting `address` and
`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]
in the `election-scripts/create-dec.ts` file, insert the Voter's private key and save the file.
Then, deploy the contract encrypting the Voter's data with the command:

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

### 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.
Expand Down
39 changes: 23 additions & 16 deletions contracts/DEC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ pragma solidity ^0.8.24;
/// @custom:experimental This is an experimental contract.
contract DEC {
address public owner;
bytes taxCode;
bytes municipality;
bytes region;
bytes country;
Encrypted taxCode;
Encrypted municipality;
Encrypted region;
Encrypted country;

struct Encrypted {
string iv;
string ephemPublicKey;
string ciphertext;
string mac;
}

constructor(
bytes memory _taxCode,
bytes memory _municipality,
bytes memory _region,
bytes memory _country
Encrypted memory _taxCode,
Encrypted memory _municipality,
Encrypted memory _region,
Encrypted memory _country
) {
/// @dev only the owner of the contract has write permissions
owner = msg.sender;
Expand All @@ -30,35 +37,35 @@ contract DEC {
_;
}

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

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

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

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

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

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

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

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

Expand Down
Binary file modified docs/assets/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
177 changes: 100 additions & 77 deletions docs/diagrams/Agora-high-level.drawio

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions election-scripts/__mocks__.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { Party } from "./types";

export const DECMock = {
taxCode: "RSSMRA85C27H501W",
municipality: "Ardea",
region: "Lazio",
country: "Italy",
};

export const PRIVATE_KEY =
"0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e";

export const MUNICIPALITY_ELECTION_DATA = {
name: "Election of major of Braccagni city",
municipality: "Braccagni",
Expand Down
16 changes: 16 additions & 0 deletions election-scripts/create-dec.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { assert } from "chai";
import { main } from "./create-dec";
import { Response, result } from "../election-scripts/types";
import { DECMock, PRIVATE_KEY } from "./__mocks__";

describe("Create DEC Script", () => {
it("Should run without errors", async () => {
const response: Response<string> = await main(DECMock, PRIVATE_KEY);
assert.equal(response.result, result.OK);
});

it("Should encrypt and deploy DEC correctly", async () => {
const response: Response<string> = await main(DECMock, PRIVATE_KEY);
assert.equal(response.result, result.OK);
});
});
60 changes: 60 additions & 0 deletions election-scripts/create-dec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* In order to run this script in hardhat, run the command: npx hardhat run election-scripts/create-dec.ts
* to run the script over a network configured in the hardhat.config.ts run:
* npx hardhat run election-scripts/create-dec.ts --network <network-configured>, example:
* npx hardhat run election-scripts/create-dec.ts --network sepolia
*
* This is the second step of the voting process: a public authority creates an EOA for the Voter.
* The EOA has a public address and a private key.
* This script deploys the DEC for the Voter by encrypting the data using the Voter's EOA private key.
*/

import { ethers } from "hardhat";
import { DEC, Response, result } from "./types";
import { DECMock, PRIVATE_KEY } from "./__mocks__";
import { encryptString } from "../lib";
import { Encrypted } from "eth-crypto";

/**
* This function encrypt the Voter's DECs data and deploys the smart contract instance.
*
* @param {DEC} decsData - the list of DECs to deploy
* @returns - the api response containing the outcome of the operation
*/
export async function main(
decsData?: DEC,
privateKey?: string,
): Promise<Response<string>> {
const response: Response<string> = {
result: result.OK,
};

try {
const ContractFactory = await ethers.getContractFactory("DEC");

const dec = decsData || DECMock;
const key = privateKey || PRIVATE_KEY;

const eTaxCode: Encrypted = await encryptString(dec.taxCode, key);
const eMunicipality: Encrypted = await encryptString(dec.municipality, key);
const eRegion: Encrypted = await encryptString(dec.region, key);
const eCountry: Encrypted = await encryptString(dec.country, key);

await ContractFactory.deploy(eTaxCode, eMunicipality, eRegion, eCountry);

return response;
} catch (e: any) {
response.result = result.ERROR;
response.errorMessage = e.message || "unknown error";
return response;
}
}

main()
.then((response) => {
console.log(JSON.stringify(response));
return response;
})
.catch((error) => {
console.error(error);
});
Loading
Loading