Skip to content

mypttwo/gya

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple Voting App based on Ethereum

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 :

  1. 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.
  2. 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.

Getting Started

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.

Setting up the environment

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.

Running the app

You run the server like so
> npm start

API

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/

Quick API walkthrough

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/.

  1. 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.

  2. 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.

  3. 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 the token and the userId for further calls.

  4. Create a ballot using
    http://localhost:3000/api-docs/#/ballots/post_ballots.
    This is an authenticated call so you would need to add the token as a part of the x-access-tokenheader.
    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 ballot id for further calls.

  5. 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.

  6. 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.

  7. 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.

Acknowledgements