Remove python code
This commit is contained in:
		
				
					committed by
					
						
						Jacob Evans
					
				
			
			
				
	
			
			
			
						parent
						
							b7fcc70cd9
						
					
				
				
					commit
					4f7d6132fc
				
			@@ -1,8 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
# Running Dev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start backend (see `backend/README.md`)
 | 
					 | 
				
			||||||
`npm install`
 | 
					 | 
				
			||||||
`npm run dev`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go to http://localhost:3000/vote.html
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								packages/v0x/backend/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								packages/v0x/backend/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
env
 | 
					 | 
				
			||||||
@@ -1,14 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
# Requirements
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 - python v3.6+
 | 
					 | 
				
			||||||
 - virtualenv
 | 
					 | 
				
			||||||
 - postgresql
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Starting
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Local dev
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`./run.sh`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On Linux you will have to create a `v0x` database under the current user manually, or modity the `DATABASE_URL` variable in the script.
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
aiohttp==3.5.4
 | 
					 | 
				
			||||||
asyncpg==0.18.3
 | 
					 | 
				
			||||||
coloredlogs==10.0
 | 
					 | 
				
			||||||
coloredlogs==10.0
 | 
					 | 
				
			||||||
eth-abi==1.3.0
 | 
					 | 
				
			||||||
ethereum==2.3.2
 | 
					 | 
				
			||||||
@@ -1,23 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
set -euo pipefail
 | 
					 | 
				
			||||||
IFS=$'\n\t'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export DATABASE_URL="postgresql:///v0x"
 | 
					 | 
				
			||||||
export DATABASE_SSL_ENABLED=0
 | 
					 | 
				
			||||||
export PORT=5000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! pg_isready -q; then
 | 
					 | 
				
			||||||
    echo "Postgresql isn't running! you need to start it..."
 | 
					 | 
				
			||||||
    exit 1
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ! psql $DATABASE_URL -c "SELECT 1" > /dev/null; then
 | 
					 | 
				
			||||||
    createdb v0x
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ ! -d env ]; then
 | 
					 | 
				
			||||||
    virtualenv -p python3.7 env
 | 
					 | 
				
			||||||
    env/bin/pip install -r requirements.txt
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
env/bin/python -m v0x
 | 
					 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
import coloredlogs
 | 
					 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
from aiohttp import web
 | 
					 | 
				
			||||||
from v0x.app import create_app
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if __name__ == '__main__':
 | 
					 | 
				
			||||||
    coloredlogs.install()
 | 
					 | 
				
			||||||
    logging.getLogger('aiohttp.access').setLevel(logging.DEBUG)
 | 
					 | 
				
			||||||
    logging.getLogger('aiohttp.server').setLevel(logging.DEBUG)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    app = create_app()
 | 
					 | 
				
			||||||
    web.run_app(app, port=os.environ.get('PORT', 5000))
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
from aiohttp import web
 | 
					 | 
				
			||||||
from v0x.database import init_database
 | 
					 | 
				
			||||||
from v0x.handlers import routes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def create_app():
 | 
					 | 
				
			||||||
    app = web.Application()
 | 
					 | 
				
			||||||
    app.add_routes(routes)
 | 
					 | 
				
			||||||
    app.on_startup.append(init_database)
 | 
					 | 
				
			||||||
    return app
 | 
					 | 
				
			||||||
@@ -1,45 +0,0 @@
 | 
				
			|||||||
import asyncpg
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import ssl
 | 
					 | 
				
			||||||
from aiohttp import web
 | 
					 | 
				
			||||||
from distutils.util import strtobool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SSL_CTX = ssl.create_default_context()
 | 
					 | 
				
			||||||
SSL_CTX.check_hostname = False
 | 
					 | 
				
			||||||
SSL_CTX.verify_mode = ssl.CERT_NONE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async def init_database(app: web.Application):
 | 
					 | 
				
			||||||
    pool = await asyncpg.create_pool(
 | 
					 | 
				
			||||||
        dsn=os.environ.get('DATABASE_URL'),
 | 
					 | 
				
			||||||
        ssl=SSL_CTX if strtobool(os.environ.get('DATABASE_SSL_ENABLED', '0')) else None)
 | 
					 | 
				
			||||||
    async with pool.acquire() as con:
 | 
					 | 
				
			||||||
        await con.execute(
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
            CREATE TABLE IF NOT EXISTS votes (
 | 
					 | 
				
			||||||
                campaign_id BIGINT,
 | 
					 | 
				
			||||||
                voter_address VARCHAR, -- hex
 | 
					 | 
				
			||||||
                preference VARCHAR,
 | 
					 | 
				
			||||||
                comment VARCHAR,
 | 
					 | 
				
			||||||
                zrx VARCHAR, -- hex
 | 
					 | 
				
			||||||
                timestamp TIMESTAMP WITHOUT TIME ZONE DEFAULT (NOW() AT TIME ZONE 'UTC'),
 | 
					 | 
				
			||||||
                signature VARCHAR, -- hex
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                PRIMARY KEY (campaign_id, voter_address)
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            CREATE TABLE IF NOT EXISTS campaigns (
 | 
					 | 
				
			||||||
                campaign_id BIGSERIAL PRIMARY KEY,
 | 
					 | 
				
			||||||
                open_date TIMESTAMP WITHOUT TIME ZONE,
 | 
					 | 
				
			||||||
                close_date TIMESTAMP WITHOUT TIME ZONE,
 | 
					 | 
				
			||||||
                open_block BIGINT
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            """)
 | 
					 | 
				
			||||||
        # TODO: make an admin way to add this
 | 
					 | 
				
			||||||
        from datetime import datetime
 | 
					 | 
				
			||||||
        await con.execute(
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
            INSERT INTO campaigns (campaign_id, open_date, close_date, open_block)
 | 
					 | 
				
			||||||
            VALUES ($1, $2, $3, $4) ON CONFLICT (campaign_id) DO NOTHING;
 | 
					 | 
				
			||||||
            """,
 | 
					 | 
				
			||||||
            1, datetime.utcnow(), datetime.utcnow(), 0x6be328)
 | 
					 | 
				
			||||||
    app['pool'] = pool
 | 
					 | 
				
			||||||
@@ -1,112 +0,0 @@
 | 
				
			|||||||
from aiohttp import web
 | 
					 | 
				
			||||||
from v0x.vote_utils import verify_signature
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
routes = web.RouteTableDef()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@routes.post('/api/vote')
 | 
					 | 
				
			||||||
async def vote(request: web.Request) -> web.Response:
 | 
					 | 
				
			||||||
    data = await request.json()
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        campaign_id = int(data['campaignId'])
 | 
					 | 
				
			||||||
        preference = data['preference']
 | 
					 | 
				
			||||||
        voter_address = data['voterAddress']
 | 
					 | 
				
			||||||
        signature = data['signature']
 | 
					 | 
				
			||||||
        comment = data.get('comment', '').strip()
 | 
					 | 
				
			||||||
    except KeyError as ke:
 | 
					 | 
				
			||||||
        return web.json_response({'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
                                  'missingKeys': list(ke.args)}, status=400)
 | 
					 | 
				
			||||||
    except AttributeError:
 | 
					 | 
				
			||||||
        # raised if comments is not a string
 | 
					 | 
				
			||||||
        return web.json_response({
 | 
					 | 
				
			||||||
            'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
            'invalidKeys': ['comment']
 | 
					 | 
				
			||||||
        }, status=400)
 | 
					 | 
				
			||||||
    except ValueError:
 | 
					 | 
				
			||||||
        # raised if campaignId is not convertable to an integer
 | 
					 | 
				
			||||||
        return web.json_response({
 | 
					 | 
				
			||||||
            'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
            'invalidKeys': ['campaignId']
 | 
					 | 
				
			||||||
        }, status=400)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # signature validation
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        signature_bytes = bytes.fromhex(signature[2:])
 | 
					 | 
				
			||||||
        if len(signature_bytes) != 65:
 | 
					 | 
				
			||||||
            return web.json_response({
 | 
					 | 
				
			||||||
                'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
                'invalidKeys': ['signature']
 | 
					 | 
				
			||||||
            }, status=400)
 | 
					 | 
				
			||||||
    except (ValueError, TypeError):
 | 
					 | 
				
			||||||
        return web.json_response({
 | 
					 | 
				
			||||||
            'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
            'invalidKeys': ['signature']
 | 
					 | 
				
			||||||
        }, status=400)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # address validation
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        if len(bytes.fromhex(voter_address[2:])) != 20:
 | 
					 | 
				
			||||||
            return web.json_response({
 | 
					 | 
				
			||||||
                'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
                'invalidKeys': ['voterAddress']
 | 
					 | 
				
			||||||
            }, status=400)
 | 
					 | 
				
			||||||
        voter_address = voter_address.lower()
 | 
					 | 
				
			||||||
    except (ValueError, TypeError):
 | 
					 | 
				
			||||||
        return web.json_response({
 | 
					 | 
				
			||||||
            'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
            'invalidKeys': ['voterAddress']
 | 
					 | 
				
			||||||
        }, status=400)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # validate preference
 | 
					 | 
				
			||||||
    if preference != 'Yes' and preference != 'No':
 | 
					 | 
				
			||||||
        return web.json_response({
 | 
					 | 
				
			||||||
            'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
            'invalidKeys': ['preference']
 | 
					 | 
				
			||||||
        }, status=400)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if not verify_signature(campaign_id, voter_address, preference, signature_bytes):
 | 
					 | 
				
			||||||
        return web.json_response({
 | 
					 | 
				
			||||||
            'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
            'message': 'signature does not match voterAddress'
 | 
					 | 
				
			||||||
        }, status=400)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # TODO: verify campaign can be voted on now
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async with request.app['pool'].acquire() as con:
 | 
					 | 
				
			||||||
        await con.execute("INSERT INTO votes "
 | 
					 | 
				
			||||||
                          "(campaign_id, voter_address, preference, comment, signature) "
 | 
					 | 
				
			||||||
                          "VALUES ($1, $2, $3, $4, $5) "
 | 
					 | 
				
			||||||
                          "ON CONFLICT (campaign_id, voter_address) "
 | 
					 | 
				
			||||||
                          "DO UPDATE SET "
 | 
					 | 
				
			||||||
                          "preference = EXCLUDED.preference, "
 | 
					 | 
				
			||||||
                          "comment = EXCLUDED.comment, "
 | 
					 | 
				
			||||||
                          "signature = EXCLUDED.signature",
 | 
					 | 
				
			||||||
                          campaign_id, voter_address, preference, comment, signature)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return web.json_response({'ok': True})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@routes.get('/api/votes/{campaign_id}')
 | 
					 | 
				
			||||||
async def list_votes(request: web.Request) -> web.Response:
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        campaign_id = int(request.match_info['campaign_id'])
 | 
					 | 
				
			||||||
    except ValueError:
 | 
					 | 
				
			||||||
        return web.json_response({
 | 
					 | 
				
			||||||
            'error': 'Bad Arguments',
 | 
					 | 
				
			||||||
            'message': 'Invalid campaign Id'
 | 
					 | 
				
			||||||
        }, status=400)
 | 
					 | 
				
			||||||
    async with request.app['pool'].acquire() as con:
 | 
					 | 
				
			||||||
        votes = await con.fetch("SELECT * FROM votes "
 | 
					 | 
				
			||||||
                                "WHERE campaign_id = $1 "
 | 
					 | 
				
			||||||
                                "ORDER BY timestamp DESC",
 | 
					 | 
				
			||||||
                                campaign_id)
 | 
					 | 
				
			||||||
    return web.json_response({'votes': [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            'voterAddress': v['voter_address'],
 | 
					 | 
				
			||||||
            'preference': v['preference'],
 | 
					 | 
				
			||||||
            'comment': v['comment'],
 | 
					 | 
				
			||||||
            'timestamp': v['timestamp'].isoformat() + "Z",
 | 
					 | 
				
			||||||
            'zrx': v['zrx']
 | 
					 | 
				
			||||||
        } for v in votes
 | 
					 | 
				
			||||||
    ]})
 | 
					 | 
				
			||||||
@@ -1,44 +0,0 @@
 | 
				
			|||||||
from eth_abi import encode_abi
 | 
					 | 
				
			||||||
from ethereum.utils import sha3 as keccak256, encode_hex, safe_ord, big_endian_to_int, ecrecover_to_pub
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
EIP191_HEADER = b"\x19\x01"
 | 
					 | 
				
			||||||
EIP712_DOMAIN_NAME = b"0x V0x"
 | 
					 | 
				
			||||||
EIP712_DOMAIN_VERSION = b"1"
 | 
					 | 
				
			||||||
EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(
 | 
					 | 
				
			||||||
    b"EIP712Domain(" +
 | 
					 | 
				
			||||||
    b"string name," +
 | 
					 | 
				
			||||||
    b"string version" +
 | 
					 | 
				
			||||||
    b")")
 | 
					 | 
				
			||||||
EIP712_DOMAIN_HASH = keccak256(encode_abi(
 | 
					 | 
				
			||||||
    ['bytes32', 'bytes32', 'bytes32'],
 | 
					 | 
				
			||||||
    [EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
 | 
					 | 
				
			||||||
     keccak256(EIP712_DOMAIN_NAME),
 | 
					 | 
				
			||||||
     keccak256(EIP712_DOMAIN_VERSION)]))
 | 
					 | 
				
			||||||
EIP712_VOTE_TYPE_HASH = keccak256(
 | 
					 | 
				
			||||||
    b"Vote(" +
 | 
					 | 
				
			||||||
    b"uint256 campaignId," +
 | 
					 | 
				
			||||||
    b"string preference" +
 | 
					 | 
				
			||||||
    b")")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def verify_signature(campaign_id, voter_address, preference, signature):
 | 
					 | 
				
			||||||
    # encode and hash vote
 | 
					 | 
				
			||||||
    encoded = encode_abi(
 | 
					 | 
				
			||||||
        ['bytes32', 'uint256', 'bytes32'],
 | 
					 | 
				
			||||||
        [EIP712_VOTE_TYPE_HASH, campaign_id,
 | 
					 | 
				
			||||||
         keccak256(preference.encode('utf-8'))])
 | 
					 | 
				
			||||||
    hash_struct = keccak256(encoded)
 | 
					 | 
				
			||||||
    hashed = keccak256(EIP191_HEADER +
 | 
					 | 
				
			||||||
                       EIP712_DOMAIN_HASH +
 | 
					 | 
				
			||||||
                       hash_struct)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # ecrecover
 | 
					 | 
				
			||||||
    v = safe_ord(signature[64])
 | 
					 | 
				
			||||||
    r = big_endian_to_int(signature[0:32])
 | 
					 | 
				
			||||||
    s = big_endian_to_int(signature[32:64])
 | 
					 | 
				
			||||||
    if v == 0 or v == 1:
 | 
					 | 
				
			||||||
        v += 27
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub = ecrecover_to_pub(hashed, v, r, s)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    recovered_address = '0x' + encode_hex(keccak256(pub)[-20:])
 | 
					 | 
				
			||||||
    return recovered_address == voter_address
 | 
					 | 
				
			||||||
							
								
								
									
										4756
									
								
								packages/v0x/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4756
									
								
								packages/v0x/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,17 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "name": "v0x",
 | 
					 | 
				
			||||||
  "version": "1.0.0",
 | 
					 | 
				
			||||||
  "description": "",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					 | 
				
			||||||
    "dev": "webpack-dev-server --mode=development",
 | 
					 | 
				
			||||||
    "test": "echo \"Error: no test specified\" && exit 1"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "author": "",
 | 
					 | 
				
			||||||
  "license": "ISC",
 | 
					 | 
				
			||||||
  "dependencies": {},
 | 
					 | 
				
			||||||
  "devDependencies": {
 | 
					 | 
				
			||||||
    "webpack": "^4.26.0",
 | 
					 | 
				
			||||||
    "webpack-cli": "^3.1.2",
 | 
					 | 
				
			||||||
    "webpack-dev-server": "^3.1.10"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
<html>
 | 
					 | 
				
			||||||
  <body>
 | 
					 | 
				
			||||||
    Vote:
 | 
					 | 
				
			||||||
    <button onClick="vote('Yes')">Yes</button>
 | 
					 | 
				
			||||||
    <button onClick="vote('No')">No</button>
 | 
					 | 
				
			||||||
    Comment: <textarea id="comment"></textarea>
 | 
					 | 
				
			||||||
    <br/>
 | 
					 | 
				
			||||||
    <pre id="comments"></pre>
 | 
					 | 
				
			||||||
    <script type="text/javascript" src="vote.js"></script>
 | 
					 | 
				
			||||||
  </body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
@@ -1,74 +0,0 @@
 | 
				
			|||||||
// https://gist.github.com/bitpshr/076b164843f0414077164fe7fe3278d9
 | 
					 | 
				
			||||||
// use the whole thing here preferably
 | 
					 | 
				
			||||||
window.addEventListener('load', function() {
 | 
					 | 
				
			||||||
  console.log('...');
 | 
					 | 
				
			||||||
  if (window.ethereum) {
 | 
					 | 
				
			||||||
    window.web3 = new Web3(ethereum);
 | 
					 | 
				
			||||||
    ethereum.enable();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  var xhr = new XMLHttpRequest();
 | 
					 | 
				
			||||||
  xhr.open('GET', '/api/votes/1', true);
 | 
					 | 
				
			||||||
  xhr.addEventListener("load", function() {
 | 
					 | 
				
			||||||
    document.getElementById("comments").innerHTML = xhr.responseText;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  xhr.send();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function signVote(preference) {
 | 
					 | 
				
			||||||
  let domainType = [
 | 
					 | 
				
			||||||
    { name: "name", type: "string" },
 | 
					 | 
				
			||||||
    { name: "version", type: "string" },
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
  let voteType = [
 | 
					 | 
				
			||||||
    { name: "campaignId", type: "uint256" },
 | 
					 | 
				
			||||||
    { name: "preference", type: "string" },
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let domainData = {
 | 
					 | 
				
			||||||
    name: "0x V0x",
 | 
					 | 
				
			||||||
    version: "1"
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  var voteData = {
 | 
					 | 
				
			||||||
    campaignId: "1",
 | 
					 | 
				
			||||||
    preference: preference,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  let zdata = JSON.stringify({
 | 
					 | 
				
			||||||
    types: {
 | 
					 | 
				
			||||||
      EIP712Domain: domainType,
 | 
					 | 
				
			||||||
      Vote: voteType,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    domain: domainData,
 | 
					 | 
				
			||||||
    primaryType: "Vote",
 | 
					 | 
				
			||||||
    message: voteData
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  signer = web3.eth.coinbase
 | 
					 | 
				
			||||||
  console.log(zdata, signer, preference);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return new Promise(function(resolve, reject) {
 | 
					 | 
				
			||||||
    function done(error, result) {
 | 
					 | 
				
			||||||
      if (error) { console.error(error); reject(error); }
 | 
					 | 
				
			||||||
      else { console.log(result); resolve(result.result); }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    web3.currentProvider.sendAsync({
 | 
					 | 
				
			||||||
      method: "eth_signTypedData_v3",
 | 
					 | 
				
			||||||
      params: [signer, zdata],
 | 
					 | 
				
			||||||
      from: signer
 | 
					 | 
				
			||||||
    }, done)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function vote(preference) {
 | 
					 | 
				
			||||||
  signVote(preference).then(function(sig) {
 | 
					 | 
				
			||||||
    var xhr = new XMLHttpRequest();
 | 
					 | 
				
			||||||
    xhr.open('POST', '/api/vote', true);
 | 
					 | 
				
			||||||
    xhr.setRequestHeader("Content-Type", "application/json");
 | 
					 | 
				
			||||||
    xhr.send(JSON.stringify({
 | 
					 | 
				
			||||||
      preference: preference,
 | 
					 | 
				
			||||||
      voterAddress: web3.eth.coinbase,
 | 
					 | 
				
			||||||
      signature: sig,
 | 
					 | 
				
			||||||
      comment: document.getElementById("comment").value,
 | 
					 | 
				
			||||||
      campaignId: 1}));
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
var path = require('path');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = {
 | 
					 | 
				
			||||||
  devServer: {
 | 
					 | 
				
			||||||
    contentBase: path.join(__dirname, '/src'),
 | 
					 | 
				
			||||||
    compress: true,
 | 
					 | 
				
			||||||
    host: '0.0.0.0',
 | 
					 | 
				
			||||||
    port: 3000,
 | 
					 | 
				
			||||||
    proxy: {
 | 
					 | 
				
			||||||
      '/api/': {
 | 
					 | 
				
			||||||
        target: 'http://localhost:5000/',
 | 
					 | 
				
			||||||
        secure: false,
 | 
					 | 
				
			||||||
        logLevel: 'debug',
 | 
					 | 
				
			||||||
        changeOrigin: true,
 | 
					 | 
				
			||||||
        xfwd: true
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user