README
votepeerjs - VotePeer Javascript Library
Notable features
Transparent Voting
A Bitcoin Cash smart contract and protocol for transparent on-chain voting.
"Two option vote" is a minimalistic and transparent voting protocol on top of Bitcoin Cash and similar blockchains. Participating, verifying and tallying does not require a full node, but is fully SPV client compatible. Votes are non-transferable.
This repository hosts the protocol/smart contract specification and a reference implementation in javascript.
Example
import {
TwoOptionVote, TwoOptionVoteContract, tallyVotes, Blockchain,
DEFAULT_CAST_TX_FEE, createSalt, derivePublicKey, getPublicKeyHash,
generatePrivateKey, DEFAULT_DUST_THRESHOLD
} from 'two-option-vote';
const sleep = require('sleep');
// Initialize participants.
const alice = generatePrivateKey();
const bob = generatePrivateKey();
// Initialize an election
const votersPKH = [
await getPublicKeyHash(await derivePublicKey(alice)),
await getPublicKeyHash(await derivePublicKey(bob)),
];
const election: TwoOptionVote = {
network: 'mainnet',
salt: createSalt(),
description: 'Pizza for lunch?',
optionA: 'Yes',
optionB: 'No',
endHeight: 1_000_000,
votersPKH,
};
// Setup contracts
const aliceContract = await TwoOptionVoteContract.make(election, alice);
const bobContract = await TwoOptionVoteContract.make(election, bob);
for (const contract of [aliceContract, bobContract]) {
await contract.waitForBalance(DEFAULT_CAST_TX_FEE + DEFAULT_DUST_THRESHOLD, () => {
console.log(`Too low balance in contract ${contract.getContractAddress()}`);
});
}
const electrum = new Blockchain();
await electrum.connect();
// Alice casts vote for option A ("Yes") and bob for B ("No")
const aliceTxID = await aliceContract.castVote(await aliceContract.optionAHash());
const bobTxID = await bobContract.castVote(await bobContract.optionBHash());
console.log(`Alice voted in tx ${aliceTxID}`);
console.log(`Bob voted in tx ${bobTxID}`);
// Tally votes on election
sleep.sleep(5); // Wait for transactions to propagate before tallying.
const includeUnconfirmed = true;
const tally = await tallyVotes(electrum, election, includeUnconfirmed);
console.log(`Results: ${JSON.stringify(tally, null, 4)}`);
See this and more examples in the examples directory.
Developers
Tests vectors
See files with *.test.ts
suffix.
Build project
npm run build
npm run test
Run the above example: node build/examples/readme-example.js
Building Fujisaki Ring signature dependency
For building the fujisaki ring signature dependency, you'll need to install wasm-pack and Rust.
When these dependencies are installed, run:
npm run build-ringsig
To use your new build, rm -rf node_modules/fujisaki-ringsig-wasm && npm install
.