This repository contains three key items:
- The solidity contract for the ballot itself
- The web UI for voters
- The auditing software (for voters, or anyone, really)
Ballots are stored on the Ethereum chain. Currently the only integrity check is the name of the ballot options.
To run a ballot, you should do these things in roughly this order:
- Set some environment variables in your build host or
.env
file. Particularly you'll needMAIN_TITLE
for the title of the website. See #web-ui for more. - Deploy a copy of this repository with
yarn build-web
(builds to_dist
) - Run
yarn sol-compile
to generate copies of the smart contract binaries. - Generate admin tools locally:
yarn admin-prod
(builds into_pureDist
)
- Generate an encryption keypair with
node _pureDist/admin.js --genBallotKey
. Save theSECRET KEY
privately somewhere, and copy thePUBLIC KEY
for use in a moment. - Run
yarn sol-deploy
to prepare a copy of the ballot smart contract for deployment, being sure to set correct start and end times, and use thePUBLIC KEY
you generated before. You'll need to release theSECRET KEY
at the end of the ballot.
Example yarn sol-deploy
:
yarn sol-deploy --startTime 1518420000 --endTime 1518421966 \
--ballotEncPubkey 0x3ae1a05881fe3bc1abcebde6898ed30716111c52fef9a7895dd82a2b8a595163 \
--optionNamesJson '["Option 1", "Option 2", "Option 3 with some caveat and a long title", "the last option", "not really"]'
Note: --optionNamesJson
needs to be formatted well. You should confirm the options before generating the final code.
- Copy the contract code generated and deploy it to your chosen Ethereum network in the usual way.
- Note down the address of the deployed contract.
- Edit
./web/src/SecureVote/SPAs/SwarmMVP/Ballot.elm
using the example as a template and fill in all relevant details, including the ERC20 address you'd like the ballot to be paired with. Be sure to add your new variable name to the list ofallBallots
. This is required for it to show up in the UI. - Deploy a new version of the UI (after testing) with the details of the new ballot.
- Tell your token holders and wait for the ballot to complete.
- After the ballot is complete use the
revealSecKey
method of the ballot contract and publish theSECRET KEY
you generated earlier. - After the
SECRET KEY
has been published (and confirmed), go to the ballot page in the UI and the audit suite will kick in, download the ballots, and show you the results.
- Install Elm-Package: https://guide.elm-lang.org/install.html
yarn install
to install all JS dependencies.elm-package install
to install Elm packages- Install
solc
npm install -g purescript pulp bower
andbower install
to install purescript dependencies
yarn build-web
outputs to_dist
yarn sol-compile
outputs to_solDist
yarn admin-prod
andyarn audit-prod
output to_pureDist
yarn sol-compile
(./bin/solidity/compile.sh
) for compilingSwarmVotingMVP.sol
; use-c <Contract.sol>
to compile another contract.yarn sol-deploy
(node ./bin/solidity/deploy.js
) for deployingSwarmVotingMVP.sol
; use--deployOther <Contract>
(with dummy endTime, startTime, ballotEncPubkey arguments) - omit the.sol
Web code lives in ./web
You'll need to set these environment variables:
MAIN_TITLE
: A string corresponding to the main title of the first page, e.g. "SWM Governance".DEV
: a boolean to indicate if it's a dev environment or not.DEMOC_HASH
: the Eth encoded hash of the relevant democracy (note: in future this might be handled in-app)
If you're building locally you can put these in a .env
file in the root of the repo.
The frontend is built in Elm using Material Design (elm-mdl
).
Elm is a strongly typed purely functional language based on Haskell, and built with frontend in mind (and no other use cases currently).
It compiles to JS.
Elm uses The Elm Architecture (TEA) which is a Model, View, Update style framework.
It works similarly to React + Redux, though handles side effects very elegantly.
We're using it because it guarantees no runtime errors and its strictness helps write code that runs correctly the first time.
yarn web
to run Elm live-reloading devyarn build-web
to build SPA in_dist
elm-format
is a program that automatically formats elm files according to a standard set of rules.
You should set it up for your editor and Elm code should be formatted with this tool before committing.
Docs: https://github.com/avh4/elm-format - instructions are listed here for most popular editors.
npm install -g elm-format@exp
- currently using elm-format-0.18 0.7.0-exp
We use elm-mdl
(material design light) for UI components.
- Docs: http://package.elm-lang.org/packages/debois/elm-mdl/8.1.0/Material
- Live example site + docs: http://debois.github.io/elm-mdl/
The Audit suite is built in Purescript.
To compile / develop it:
npm install -g purescript pulp bower
yarn audit-prod
oryarn admin-prod
(depending on which target you want to generate)
To run the audit script:
node ./_pureDist/audit.js -e http://localhost:8545 --swmBallotAddr <address here> --erc20Addr <address>
To run the admin script (key generation)
node ./_pureDist/admin.js --genBallotKey
The contract lives in ./contract
and uses truffle for development, though not for deployment.
yarn sol-compile
to compile contract to_solDist
yarn sol-deploy <args>
to deploy (after compiling) to the blockchain
To play with a Web3-esq CLI run yarn sol-compile && yarn sol-cli
Example deployment:
(see yarn sol-deploy --help
for all arguments)
yarn sol-deploy --startTime 1508824035 --endTime 1509667200 \
--ballotEncPubkey 0xf13a7020b9d69380e8b91fc51acae296cf3368174edd6bfbd4edeac70bbca80f
Currently purescript-decimals
is causing a problem with imports and webpack (only for frontend).
This means decimal.js
needs to be manually included with a <script>
tag.
yarn 1.3.2 was giving us problems on netlify (though not on dev machines). If you have trouble try yarn 0.18.1.
additionally, if you run INSTALL_WEBPACK=true yarn build-web
it run npm install -g webpack
first.
in addition to the yarn issue we also had issues with node v8.9.4. If you have trouble try v6.9.1.
Some troubles exist with webpack 4 and the loaders used by elm and purescript.
elm-webpack-loader is pinned to a commit for the mean time to get around this. It should be removed once the loader itself is fixed.