Deploy contract

This commit is contained in:
Anthony Laibe 2018-08-16 16:18:07 +01:00 committed by Pascal Precht
parent 870efbcf20
commit 6038da4339
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
9 changed files with 110 additions and 5 deletions

View File

@ -118,6 +118,13 @@ export const contractFunction = {
failure: (error) => action(CONTRACT_FUNCTION[FAILURE], {error})
};
export const CONTRACT_DEPLOY = createRequestTypes('CONTRACT_DEPLOY');
export const contractDeploy = {
post: (contractName, method, inputs) => action(CONTRACT_DEPLOY[REQUEST], {contractName, method, inputs}),
success: (result, payload) => action(CONTRACT_DEPLOY[SUCCESS], {contractDeploys: [{...result, ...payload}]}),
failure: (error) => action(CONTRACT_DEPLOY[FAILURE], {error})
};
export const VERSIONS = createRequestTypes('VERSIONS');
export const versions = {
request: () => action(VERSIONS[REQUEST]),

View File

@ -72,6 +72,10 @@ export function postContractFunction(payload) {
return post(`/contract/${payload.contractName}/function`, payload);
}
export function postContractDeploy(payload) {
return post(`/contract/${payload.contractName}/deploy`, payload);
}
export function fetchVersions() {
return get('/versions');
}

View File

@ -10,6 +10,7 @@ import {
import ContractContainer from '../containers/ContractContainer';
import ContractLoggerContainer from '../containers/ContractLoggerContainer';
import ContractFunctionsContainer from '../containers/ContractFunctionsContainer';
import ContractDeploymentContainer from '../containers/ContractDeploymentContainer';
import ContractProfileContainer from '../containers/ContractProfileContainer';
import ContractSourceContainer from '../containers/ContractSourceContainer';
@ -73,6 +74,7 @@ const ContractLayout = ({match}) => (
<Grid.Col md={9}>
<Switch>
<Route exact path="/embark/contracts/:contractName/overview" component={ContractContainer} />
<Route exact path="/embark/contracts/:contractName/deployment" component={ContractDeploymentContainer} />
<Route exact path="/embark/contracts/:contractName/functions" component={ContractFunctionsContainer} />
<Route exact path="/embark/contracts/:contractName/source" component={ContractSourceContainer} />
<Route exact path="/embark/contracts/:contractName/profiler" component={ContractProfileContainer} />

View File

@ -0,0 +1,54 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {withRouter} from 'react-router-dom';
import {contractProfile as contractProfileAction, contractDeploy as contractDeployAction} from '../actions';
import ContractFunctions from '../components/ContractFunctions';
import DataWrapper from "../components/DataWrapper";
import {getContractProfile, getContractDeploys} from "../reducers/selectors";
class ContractDeploymentContainer extends Component {
componentDidMount() {
this.props.fetchContractProfile(this.props.match.params.contractName);
}
render() {
return (
<DataWrapper shouldRender={this.props.contractProfile !== undefined }
{...this.props}
render={({contractProfile, contractDeploys, postContractDeploy}) => (
<ContractFunctions contractProfile={contractProfile}
contractFunctions={contractDeploys}
onlyConstructor
postContractFunction={postContractDeploy}/>
)} />
);
}
}
function mapStateToProps(state, props) {
return {
contractProfile: getContractProfile(state, props.match.params.contractName),
contractDeploys: getContractDeploys(state, props.match.params.contractName),
error: state.errorMessage,
loading: state.loading
};
}
ContractDeploymentContainer.propTypes = {
match: PropTypes.object,
contractProfile: PropTypes.object,
contractFunctions: PropTypes.arrayOf(PropTypes.object),
postContractDeploy: PropTypes.func,
fetchContractProfile: PropTypes.func,
error: PropTypes.string
};
export default withRouter(connect(
mapStateToProps,
{
fetchContractProfile: contractProfileAction.request,
postContractDeploy: contractDeployAction.post
}
)(ContractDeploymentContainer));

View File

@ -20,7 +20,6 @@ class ContractFunctionsContainer extends Component {
render={({contractProfile, contractFunctions, postContractFunction}) => (
<ContractFunctions contractProfile={contractProfile}
contractFunctions={contractFunctions}
constructor={true}
postContractFunction={postContractFunction}/>
)} />
);

View File

@ -14,6 +14,7 @@ const entitiesDefaultState = {
contractProfiles: [],
contractFiles: [],
contractFunctions: [],
contractDeploys: [],
contractLogs: [],
commands: [],
messages: [],

View File

@ -70,6 +70,10 @@ export function getContractFunctions(state, contractName) {
return state.entities.contractFunctions.filter((contractFunction => contractFunction.contractName === contractName));
}
export function getContractDeploys(state, contractName) {
return state.entities.contractDeploys.filter((contractDeploy => contractDeploy.contractName === contractName));
}
export function getVersions(state) {
return state.entities.versions;
}

View File

@ -5,7 +5,7 @@ import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects';
const {account, accounts, block, blocks, transaction, transactions, processes, commands, processLogs,
contracts, contract, contractProfile, messageSend, versions, plugins, messageListen, fiddle,
ensRecord, ensRecords, contractLogs, contractFile, contractFunction} = actions;
ensRecord, ensRecords, contractLogs, contractFile, contractFunction, contractDeploy} = actions;
function *doRequest(entity, apiFn, payload) {
const {response, error} = yield call(apiFn, payload);
@ -33,6 +33,7 @@ export const fetchContract = doRequest.bind(null, contract, api.fetchContract);
export const fetchContractProfile = doRequest.bind(null, contractProfile, api.fetchContractProfile);
export const fetchContractFile = doRequest.bind(null, contractFile, api.fetchContractFile);
export const postContractFunction = doRequest.bind(null, contractFunction, api.postContractFunction);
export const postContractDeploy = doRequest.bind(null, contractDeploy, api.postContractDeploy);
export const fetchFiddle = doRequest.bind(null, fiddle, api.fetchFiddle);
export const sendMessage = doRequest.bind(null, messageSend, api.sendMessage);
export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord);
@ -98,6 +99,10 @@ export function *watchPostContractFunction() {
yield takeEvery(actions.CONTRACT_FUNCTION[actions.REQUEST], postContractFunction);
}
export function *watchPostContractDeploy() {
yield takeEvery(actions.CONTRACT_DEPLOY[actions.REQUEST], postContractDeploy);
}
export function *watchFetchVersions() {
yield takeEvery(actions.VERSIONS[actions.REQUEST], fetchVersions);
}
@ -206,6 +211,7 @@ export default function *root() {
fork(watchFetchContractProfile),
fork(watchFetchContractFile),
fork(watchPostContractFunction),
fork(watchPostContractDeploy),
fork(watchListenToMessages),
fork(watchSendMessage),
fork(watchFetchContract),

View File

@ -103,7 +103,7 @@ class ContractsManager {
account: (callback) => {
self.events.request("blockchain:defaultAccount:get", (account) => callback(null, account));
}
}, function (error, result) {
}, (error, result) => {
if (error) {
return res.send({error: error.message});
}
@ -117,10 +117,38 @@ class ContractsManager {
return res.send({result: error.message});
}
return res.send({result});
res.send({result});
});
} catch (e) {
return res.send({result: e.message});
res.send({result: e.message});
}
});
}
);
plugin.registerAPICall(
'post',
'/embark-api/contract/:contractName/deploy',
(req, res) => {
async.parallel({
contract: (callback) => {
self.events.request('contracts:contract', req.body.contractName, (contract) => callback(null, contract));
},
account: (callback) => {
self.events.request("blockchain:defaultAccount:get", (account) => callback(null, account));
}
}, async (error, result) => {
if (error) {
return res.send({error: error.message});
}
const {account, contract} = result;
const contractObj = new web3.eth.Contract(contract.abiDefinition);
try {
let gas = await contractObj.deploy({data: `0x${contract.code}`, arguments: req.body.inputs}).estimateGas();
let newContract = await contractObj.deploy({data: `0x${contract.code}`, arguments: req.body.inputs}).send({from: account, gas});
res.send({result: newContract._address});
} catch (e) {
res.send({result: e.message});
}
});
}