This is a sawtooth-based voting system. The use is accessible through a REST API (explained later). The design in mind is to make sure to preserve the following key-factors:
- Only eligible voters can vote
- Voter decision should be confidential
- A voter should have the ability to make sure his vote counted
- Vote process should be frauds-tolerable
To make sure all of this requirements are held properly, the system should be used in the following way:
- Prior to voting, a voter should identify hiself to a governmental represntative that verify his identity
- After verification, a voter can choose a secret scratch card that contains a private and a public key. The key would be used later to cast a vote.
The system is consist of the required TransactionProcessor implementation for 2 Transaction families, one for campaign-management related transactions for controlling the campaign and the other is for voter-verification related transactions to make sure a voter is eligible for voting.
The project contains both the Blockchain implementation and the Proxy(REST API SERVER) implementation. both needs to be up and running to use this system.
The Transaction Proccessors used are in the "blockchain" folder. the registration is made through the file index.js. please make sure to pass as an argument the address of the sawtooth Validator. (on local env, using the 1 node for testing (default address is: tcp://127.0.0.1:4004) Also, the validator makes use of the blockchain address passed in as a ENV_VAR, names BLOCKCHAIND_ADDR (default to: http://127.0.0.1:8008) and of course, the authorised secret scratch card list, is a JSON file in the listing folder, with the name "chisgads.json". After cloning the project, make sure to have the required files in place, and run:
$ npm install
$ export BLOCKCHAIN_ADDR={blockchaind_address}
$ node {path_to}/index.js {validator_address}
The code make use of 3 ENV_VARS: IP, PORT, BLOCKCHAIN_ADDR. To use, run the following commands:
$ npm install
$ export IP={ip_address} PORT={port_address} BLOCKCHAIN_ADD={blockchain_address}
$ node {path_to}/app.js
All the transactions-request API endpoints respond with a JSON that contains at least the following fields:
- link: contains the link to the batch_statuses href, so a user can track the state of his transaction request.
- res: SUCCESS or ERROR
- id: batch id, to make a use of saw_tooth api where needed
POST
/checkin?id={voter_id}&ballot={ballot_id}&scratchCard={scratch_card_id}
- voter_id - the voter id
- ballot_id - the ballot id
- scratch_card_id - in real life that would be the independant choose of a secret scratch card by the voter (here, it doesn't make a difference and will be randomized)
- privateKey: private key of the secret scratch card
- publicKey: public key of the secret scratch card
Some of these APIs make use of "admin_private_key", this can be set by the user in any way he likes, I gave as an example 3 keys in the admins.json file in the 'blockchain' folder
POST /admin/open_campaign?privkey={admin_private_key}
- admin_private_key - private key of system admin
POST
/admin/{action}?name={campaign_name}&party={party_name}&privkey={admin_private_key}
- action - can be either "add_party" or "remove_party"
- campaign_name - the campaign of which we want to modify the parties list
- party_name - the party name to add or remove
- admin_private_key - private key of system admin
POST
/state/{campaign_name}?new_state={new_state}&privkey={admin_private_key}
- campaign_name - the campaign of which we want to modify the parties list
- new_state - the desired state (SETUP,OPEN,SUSPEND,CLOSE*)
- admin_private_key - private key of system admin *Note that closed campaign can't be reopened
POST
/vote/{campaign_name}?party={party_name}&privkey={voter_private_key}
- campaign_name - the campaign of which we would like to vote
- party_name - the party the voter has chose to vote for
- voter_private_key - the private key a voter got when he checked-in (using the Voter-Verification API)
Getting the most up-to-date state of the existing campaigns.
GET
/state/{campaign_name}
- campaign_name (OPTIONAL) - if provided, get the specific campaign state. If not provided, it will respond with an array of all existed campaigns.
Getting secret keys of Sec256k1 for testing purposes.
GET
/signer/keys