Contract Build Improvements (#215)

This commit is contained in:
Daniel Ternyak 2018-11-21 17:24:33 -06:00 committed by GitHub
parent 0496b58130
commit f8910b1e09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 107 additions and 30543 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
.idea
contract/build

View File

@ -2,7 +2,7 @@ matrix:
include:
# Frontend
- language: node_js
node_js: 8.11.4
node_js: 8.13.0
before_install:
- cd frontend/
install: yarn
@ -15,17 +15,23 @@ matrix:
before_install:
- cd backend/
- cp .env.example .env
env:
- FLASK_APP=app.py FLASK_DEBUG=1 CROWD_FUND_URL=https://eip-712.herokuapp.com/contract/crowd-fund
CROWD_FUND_FACTORY_URL=https://eip-712.herokuapp.com/contract/factory
install: pip install -r requirements/dev.txt
script:
- flask test
# Contracts
- language: node_js
node_js: 8.11.4
node_js: 8.13.0
before_install:
- cd contract/
install: yarn && yarn add global truffle ganache-cli
install: yarn && yarn add global truffle ganache-cli@6.1.8
before_script:
- ganache-cli > /dev/null &
- sleep 10
script:
- yarn run test
env:
- CROWD_FUND_URL=https://eip-712.herokuapp.com/contract/crowd-fund
CROWD_FUND_FACTORY_URL=https://eip-712.herokuapp.com/contract/factory

View File

@ -9,5 +9,8 @@ SENDGRID_API_KEY="optional, but emails won't send without it"
# for ropsten use the following
# ETHEREUM_ENDPOINT_URI = "https://ropsten.infura.io/API_KEY"
ETHEREUM_ENDPOINT_URI = "http://localhost:8545"
CROWD_FUND_URL = "https://eip-712.herokuapp.com/contract/crowd-fund"
CROWD_FUND_FACTORY_URL = "https://eip-712.herokuapp.com/contract/factory"
UPLOAD_DIRECTORY = "/tmp"
UPLOAD_URL = "http://localhost:5000" # for constructing download url
UPLOAD_URL = "http://localhost:5000" # for constructing download url

View File

@ -1,20 +0,0 @@
# Config file for automatic testing at travis-ci.org
sudo: false # http://docs.travis-ci.com/user/migrating-from-legacy/
language: python
env:
- FLASK_APP=app.py FLASK_DEBUG=1
python:
- 2.7
- 3.4
- 3.5
- 3.6
install:
- pip install -r requirements/dev.txt
- nvm install 6.10
- nvm use 6.10
- npm install
before_script:
- npm run lint
- npm run build
- flask lint
script: flask test

View File

@ -15,6 +15,8 @@ ENV = env.str("FLASK_ENV", default="production")
DEBUG = ENV == "development"
SITE_URL = env.str('SITE_URL', default='https://grant.io')
AUTH_URL = env.str('AUTH_URL', default='https://eip-712.herokuapp.com')
CROWD_FUND_FACTORY_URL = env.str('CROWD_FUND_FACTORY_URL', default=None)
CROWD_FUND_URL = env.str('CROWD_FUND_URL', default=None)
SQLALCHEMY_DATABASE_URI = env.str("DATABASE_URL")
QUEUES = ["default"]
SECRET_KEY = env.str("SECRET_KEY")

View File

@ -2,6 +2,8 @@ import json
import time
from flask_web3 import current_web3
from .util import batch_call, call_array, RpcError
import requests
from grant.settings import CROWD_FUND_URL
crowd_fund_abi = None
@ -11,11 +13,18 @@ def get_crowd_fund_abi():
global crowd_fund_abi
if crowd_fund_abi:
return crowd_fund_abi
if CROWD_FUND_URL:
crowd_fund_json = requests.get(CROWD_FUND_URL).json()
crowd_fund_abi = crowd_fund_json['abi']
return crowd_fund_abi
with open("../contract/build/contracts/CrowdFund.json", "r") as read_file:
crowd_fund_abi = json.load(read_file)['abi']
return crowd_fund_abi
def read_proposal(address):
current_web3.eth.defaultAccount = current_web3.eth.accounts[0]
crowd_fund_abi = get_crowd_fund_abi()

View File

@ -1,13 +1,14 @@
import copy
import json
import time
from grant.extensions import web3
from ..config import BaseTestConfig
from grant.web3.proposal import read_proposal
from flask_web3 import current_web3
import eth_tester.backends.pyevm.main as py_evm_main
from flask_web3 import current_web3
from grant.extensions import web3
from grant.settings import CROWD_FUND_URL, CROWD_FUND_FACTORY_URL
from grant.web3.proposal import read_proposal
from ..config import BaseTestConfig
import requests
# increase gas limit on eth-tester
# https://github.com/ethereum/web3.py/issues/1013
# https://gitter.im/ethereum/py-evm?at=5b7eb68c4be56c5918854337
@ -23,10 +24,17 @@ class TestWeb3ProposalRead(BaseTestConfig):
BaseTestConfig.setUp(self)
# the following will properly configure web3 with test config
web3.init_app(self.real_app)
with open("../contract/build/contracts/CrowdFundFactory.json", "r") as read_file:
crowd_fund_factory_json = json.load(read_file)
with open("../contract/build/contracts/CrowdFund.json", "r") as read_file:
self.crowd_fund_json = json.load(read_file)
if CROWD_FUND_FACTORY_URL:
crowd_fund_factory_json = requests.get(CROWD_FUND_FACTORY_URL).json()
else:
with open("../frontend/client/lib/contracts/CrowdFundFactory.json", "r") as read_file:
crowd_fund_factory_json = json.load(read_file)
if CROWD_FUND_URL:
self.crowd_fund_json = requests.get(CROWD_FUND_URL).json()
else:
with open("../frontend/client/lib/contracts/CrowdFund.json", "r") as read_file:
self.crowd_fund_json = json.load(read_file)
current_web3.eth.defaultAccount = current_web3.eth.accounts[0]
CrowdFundFactory = current_web3.eth.contract(
abi=crowd_fund_factory_json['abi'], bytecode=crowd_fund_factory_json['bytecode'])
@ -78,13 +86,13 @@ class TestWeb3ProposalRead(BaseTestConfig):
def create_crowd_fund(self):
tx_hash = self.crowd_fund_factory.functions.createCrowdFund(
5000000000000000000, # ethAmount
current_web3.eth.accounts[0], # payout
5000000000000000000, # ethAmount
current_web3.eth.accounts[0], # payout
[current_web3.eth.accounts[0]], # trustees
[5000000000000000000], # milestone amounts
60, # duration (minutes)
60, # voting period (minutes)
True # immediate first milestone payout
[5000000000000000000], # milestone amounts
60, # duration (minutes)
60, # voting period (minutes)
True # immediate first milestone payout
).transact()
tx_receipt = current_web3.eth.waitForTransactionReceipt(tx_hash)
tx_events = self.crowd_fund_factory.events.ContractCreated().processReceipt(tx_receipt)

3
contract/.gitignore vendored
View File

@ -2,5 +2,4 @@ node_modules
.idea/
yarn-error.log
.env
build/abi
build/typedefs
build

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,4 +5,7 @@ FUND_ETH_ADDRESSES=0x4bbeEB066eD09B7AEd07bF39EEe0460DFa261520,0xDECAF9CD2367cdbb
NO_DEV_TS_CHECK=true
# Set the public host url (no trailing slash)
PUBLIC_HOST_URL=https://demo.grant.io
PUBLIC_HOST_URL=https://demo.grant.io
CROWD_FUND_URL = "https://eip-712.herokuapp.com/contract/crowd-fund"
CROWD_FUND_FACTORY_URL = "https://eip-712.herokuapp.com/contract/factory"

View File

@ -1 +1 @@
8.11.4
8.13.0

1
frontend/Procfile Normal file
View File

@ -0,0 +1 @@
web: yarn start

View File

@ -1,9 +1,9 @@
import axios from './axios';
import { Proposal, TeamMember, Update } from 'types';
import {
formatProposalFromGet,
formatTeamMemberForPost,
formatTeamMemberFromGet,
formatProposalFromGet,
} from 'utils/api';
import { PROPOSAL_CATEGORY } from './constants';
@ -91,6 +91,16 @@ export function verifyEmail(code: string): Promise<any> {
return axios.post(`/api/v1/email/${code}/verify`);
}
export async function fetchCrowdFundFactoryJSON(): Promise<any> {
const res = await axios.get(process.env.CROWD_FUND_FACTORY_URL as string);
return res.data;
}
export async function fetchCrowdFundJSON(): Promise<any> {
const res = await axios.get(process.env.CROWD_FUND_URL as string);
return res.data;
}
export function postProposalUpdate(
proposalId: number,
title: string,

View File

@ -1,6 +1,6 @@
import Web3 from 'web3';
import getContractInstance from './getContract';
import CrowdFund from 'lib/contracts/CrowdFund.json';
import { fetchCrowdFundJSON } from 'api/api';
const contractCache = {} as { [key: string]: any };
@ -9,6 +9,12 @@ export async function getCrowdFundContract(web3: Web3 | null, deployedAddress: s
throw new Error('getCrowdFundAddress: web3 was null but is required!');
}
if (!contractCache[deployedAddress]) {
let CrowdFund;
if (process.env.CROWD_FUND_FACTORY_URL) {
CrowdFund = await fetchCrowdFundJSON();
} else {
CrowdFund = await import('./contracts/CrowdFund.json');
}
try {
contractCache[deployedAddress] = await getContractInstance(
web3,

View File

@ -1,18 +1,22 @@
import { SagaIterator } from 'redux-saga';
import { put, all, fork, take, takeLatest, select, call } from 'redux-saga/effects';
import { setWeb3, setAccounts, setContract } from './actions';
import { all, call, fork, put, select, take, takeLatest } from 'redux-saga/effects';
import { setAccounts, setContract, setWeb3 } from './actions';
import { selectWeb3 } from './selectors';
import { safeEnable } from 'utils/web3';
import types from './types';
import { fetchCrowdFundFactoryJSON } from 'api/api';
/* tslint:disable no-var-requires --- TODO: find a better way to import contract */
const CrowdFundFactory = require('lib/contracts/CrowdFundFactory.json');
let CrowdFundFactory = require('lib/contracts/CrowdFundFactory.json');
export function* bootstrapWeb3(): SagaIterator {
// Don't attempt to bootstrap web3 on SSR
if (process.env.SERVER_SIDE_RENDER) {
return;
}
if (process.env.CROWD_FUND_FACTORY_URL) {
CrowdFundFactory = yield call(fetchCrowdFundFactoryJSON);
}
yield put<any>(setWeb3());
yield take(types.WEB3_FULFILLED);

View File

@ -26,14 +26,29 @@ dotenvFiles.forEach(dotenvFile => {
}
});
if (!process.env.PUBLIC_HOST_URL) {
if (process.env.NODE_ENV === 'production') {
throw new Error(
'The process.env.PUBLIC_HOST_URL environment variable is required but was not specified.',
);
const envProductionRequiredHandler = (envVariable, fallbackValue) => {
if (!process.env[envVariable]) {
if (process.env.NODE_ENV === 'production') {
throw new Error(
`The process.env.${envVariable} environment variable is required but was not specified.`,
);
}
process.env[envVariable] = fallbackValue;
}
process.env.PUBLIC_HOST_URL = 'http://localhost:' + (process.env.PORT || 3000);
}
};
envProductionRequiredHandler(
'PUBLIC_HOST_URL',
'http://localhost:' + (process.env.PORT || 3000),
);
envProductionRequiredHandler(
'CROWD_FUND_URL',
'https://eip-712.herokuapp.com/contract/crowd-fund',
);
envProductionRequiredHandler(
'CROWD_FUND_FACTORY_URL',
'https://eip-712.herokuapp.com/contract/factory',
);
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')

View File

@ -1,6 +1,6 @@
{
"name": "grant",
"version": "1.0.1",
"version": "1.0.2",
"main": "index.js",
"license": "MIT",
"scripts": {
@ -10,12 +10,16 @@
"lint": "tslint --project ./tsconfig.json --config ./tslint.json -e \"**/build/**\"",
"start": "NODE_ENV=production node ./build/server/server.js",
"now": "npm run build && now -e BACKEND_URL=https://grant-stage.herokuapp.com",
"heroku-postbuild": "yarn build",
"tsc": "tsc",
"link-contracts": "cd client/lib && ln -s ../../build/contracts contracts",
"ganache": "ganache-cli -b 5",
"truffle": "truffle exec ./bin/init-truffle.js && cd client/lib/contracts && truffle console",
"storybook": "start-storybook -p 9001 -c .storybook"
},
"engines": {
"node": "8.13.0"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",