This is the server implementation of an app that allows deployment of simple smart voting contracts and interaction with them without running a local geth node using web3 1.0.0 and nodejs.
You will find this interesting if
- you need a nodejs server
- with a simple user management module that includes authentication and authorization using jsonwebtokens
- that exposes a REST API which can be browsed via Swagger
- that uses mongo as the db
- you need a working example using web3 1.0.0.
- you do not want to run a local Ethereum node - either to connect to Ropsten/Rinkeby or even testrpc/ganache .
Disclaimers :
- While this allows deployment of smart contracts and interaction with them, this does not restrict anonymous users from directly interacting with the smart contracts on Ethereum. This can only serve as a model for future development.
- The simpler way to deploy the contract is to use truffle console of course. This only demonstrates a way it can be done via nodejs.
Apart from having nodejs installed and other usual stuff you will need to
- Signup on infura.io. This is the infrastructure that powers Metamask. You should have an API key at the end of the signup.
- Install Metamask if you have not done that as yet. This will give you a default account and a mnemonic to login.
- Get some ether to begin with. You would also like to work with a test network like Ropsten or Rinkeby. Look for faucets in the respective networks - like Ropsten faucet, Rinkeby faucet.
The code includes a .env file. You will need to set the appropriate variables to run the app.
- Specify the url for your mongodb instance. (Either you can download and run mongo locally or you can use a service (mlab, Atlas)
DB=mongodb://localhost:27017/gya
- Specify the port on which your server will run
PORT=3000
- Specify a secret which will be used for encryption of passwords and sensitive data
SECRET=<)GV-}Y+j{3WYGBa
- Specify the infura.io url with key which will allow you to interact with Ethereum blockchain
INFURA_URL_API_KEY=https://ropsten.infura.io/1t7lIne9gTwmPs9Twsd5
- Specify the mnemonic that allows you to access your Metamask wallet
MNEMONIC=one two three four five six seven eight nine ten eleven twelve
Needless to say the above file should never be checked in or even logged. If you do that in production you will be robbed.
You run the server like so
> npm start
The server API documentation can be accessed from the /api-docs endpoint.
For example if you are running the server off localhost and port 3000 you can access the API from the below endpoint
http://localhost:3000/api-docs/
If you would like to get a quick idea on the capabilities of the server follow the below steps.
For the purposes of this walkthrough we will assume that your server is running on
http://localhost:3000/.
-
You can at any time list all users this endpoint
http://localhost:3000/api-docs/#/users/get_users_.
Todo : This is an unauthenticated call. This can be put behind authentication and authorization. -
Register a user with appropriate credentials via this endpoint
http://localhost:3000/api-docs/#/users/post_register.
As a quick check you can now list users once again via
http://localhost:3000/api-docs/#/users/get_users_.
If all has gone well you would see the user created in the list. -
Login the user with appropriate credentials via
http://localhost:3000/api-docs/#/users/post_login.
If all has gone well again you should get a response as so{"auth": true, "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVhYTE5MGJmZWRmZGZkMmI4MzUyYjMyOCIsImlhdCI6MTUyMDUzNzg0MiwiZXhwIjoxNTIwNjI0MjQyfQ.mXiGsy2AfzgvCstr4w5dwXLWJAzBdjtQl6KBZaI4cyI", "userId": "5aa190bfedfdfd2b8352b328"}
You will need thetoken
and theuserId
for further calls. -
Create a ballot using
http://localhost:3000/api-docs/#/ballots/post_ballots.
This is an authenticated call so you would need to add thetoken
as a part of thex-access-token
header.
You will need to list the candidates with double quotes not single quotes. For instance["Pam", "Sam", "VanDam"]
will work;['Pam', 'Sam', 'VanDam']
will not.
You will need the ballotid
for further calls. -
Deploy the smart contract on Ethereum for a specific ballot via
http://localhost:3000/api-docs/#/ballots/post_ballots__id__deploy.
This may take a couple of minutes, so the call returns immediately. You will have to check back after a couple of minutes via
http://localhost:3000/api-docs/#/ballots/get_ballots_.
Todo : This call gets all the ballots created in the db. An endpoint can be supported to get the specific ballot.
Its also possible that an error may result even if all works well.
>Error: Transaction was not mined within 50 blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!
This means that you may have to try deploying the smart contract again after some time.
Todo : Some kind of a queueing mechanism needs to be put in place so that if the smart contract fails to deploy the server automatically re-queues the smart contract for deployment without user intervention. -
Vote for a candidate via
http://localhost:3000/api-docs/#/ballots/post_ballots__id__vote.
Todo : Currently no checks are maintained as to the number of times a user can vote.
Todo : Also there is no check as to whether the candidate exists. -
Finally get the tally of votes for all candidates via
http://localhost:3000/api-docs/#/ballots/get_ballots__id__tally
Todos have also been listed with some endpoints which can be taken up later.
Apart from the above, the API also contains endpoints that handle the usual data CRUD stuff.
- Excellent tutorials by Mahesh Murthy
- The code uses the Voting Contract by Mahesh Murthy.