This is a POC for anonymous-voting system inspired by the paper An efficient and effective Decentralized Anonymous Voting System. The contract is built on Near protocol. The generated ballot is signed by a ring signature to ensure anonimity and the ballot itself is ecrypted by applying unlinkable payments scheme proposed by Nicolas van Saberhagen.
Note : This is not a scalable system and the amount of gas required to decrypt a ballot is quite high.
- rustc
1.62.1
and rustup1.25.1
for smart contract - nodejs ^18.0.0
- wasm-pack 0.10.3
- Install docker and docker compose
- Run
docker-compose up
in the project directory.
- Install dependencies
npm run deps-install
- Deploy smart contract
npm run deploy
- Copy the contract name from contract/neardev/dev-account.env to frontend/.env as VITE_CONTRACT_NAME=${contractname}
- Run
npm start
to start the frontend dev server.
- The smart-contract code lives in the
/contract
folder. In blockchain apps the smart contract is the "backend" of your app. - The frontend code lives in the
/frontend
folder./frontend/index.html
is a great place to start exploring. Note that it loads in/frontend/index.tsx
, this is your entrypoint to learn how the frontend connects to the NEAR blockchain. - Ring signature and code for generating keys are in
/frontend/ring-sig/
. - Run tests on contract:
npm test:unit
, this will run the unit tests.
Every smart contract in NEAR has its [own associated account][NEAR accounts].
When you run npm run deploy
, your smart contract gets deployed to the live NEAR TestNet with a temporary dev account.
When you're ready to make it permanent, here's how:
near-cli is a command line interface (CLI) for interacting with the NEAR blockchain. It was installed to the local node_modules
folder when you ran npm install
, but for best ergonomics you may want to install it globally:
npm install --global near-cli
Or, if you'd rather use the locally-installed version, you can prefix all near
commands with npx
Ensure that it's installed with near --version
(or npx near --version
)
Each account on NEAR can have at most one contract deployed to it. If you've already created an account such as your-name.testnet
, you can deploy your contract to near-blank-project.your-name.testnet
. Assuming you've already created an account on [NEAR Wallet], here's how to create near-blank-project.your-name.testnet
:
-
Authorize NEAR CLI, following the commands it gives you:
near login
-
Create a subaccount (replace
YOUR-NAME
below with your actual account name):near create-account near-blank-project.YOUR-NAME.testnet --masterAccount YOUR-NAME.testnet
Use the CLI to deploy the contract to TestNet with your account ID.
Replace PATH_TO_WASM_FILE
with the wasm
that was generated in contract
build directory.
near deploy --accountId near-blank-project.YOUR-NAME.testnet --wasmFile PATH_TO_WASM_FILE
Modify the line in src/config.js
that sets the account name of the contract. Set it to the account id you used above.
const CONTRACT_NAME = process.env.CONTRACT_NAME || 'near-blank-project.YOUR-NAME.testnet'
- Move the poll data to a decentralised database or ipfs rather than storing it in smart contract.
- We can use Diffie-Hellman key exchange to create the shared public-private key pair instead of storing them in smart contract.
- Decrypting a ballot right now takes up high amount of gas and thus large number of ballots cannot be decrypted in a single transaction. A better solution is to have a serverless function or a centralised backend that calls the smart contract in a loop to decrypt ballots rather than computing the voting result in a single smart contract call.