Deploy contract
This commit is contained in:
parent
870efbcf20
commit
6038da4339
|
@ -118,6 +118,13 @@ export const contractFunction = {
|
||||||
failure: (error) => action(CONTRACT_FUNCTION[FAILURE], {error})
|
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 = createRequestTypes('VERSIONS');
|
||||||
export const versions = {
|
export const versions = {
|
||||||
request: () => action(VERSIONS[REQUEST]),
|
request: () => action(VERSIONS[REQUEST]),
|
||||||
|
|
|
@ -72,6 +72,10 @@ export function postContractFunction(payload) {
|
||||||
return post(`/contract/${payload.contractName}/function`, payload);
|
return post(`/contract/${payload.contractName}/function`, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function postContractDeploy(payload) {
|
||||||
|
return post(`/contract/${payload.contractName}/deploy`, payload);
|
||||||
|
}
|
||||||
|
|
||||||
export function fetchVersions() {
|
export function fetchVersions() {
|
||||||
return get('/versions');
|
return get('/versions');
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
import ContractContainer from '../containers/ContractContainer';
|
import ContractContainer from '../containers/ContractContainer';
|
||||||
import ContractLoggerContainer from '../containers/ContractLoggerContainer';
|
import ContractLoggerContainer from '../containers/ContractLoggerContainer';
|
||||||
import ContractFunctionsContainer from '../containers/ContractFunctionsContainer';
|
import ContractFunctionsContainer from '../containers/ContractFunctionsContainer';
|
||||||
|
import ContractDeploymentContainer from '../containers/ContractDeploymentContainer';
|
||||||
import ContractProfileContainer from '../containers/ContractProfileContainer';
|
import ContractProfileContainer from '../containers/ContractProfileContainer';
|
||||||
import ContractSourceContainer from '../containers/ContractSourceContainer';
|
import ContractSourceContainer from '../containers/ContractSourceContainer';
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ const ContractLayout = ({match}) => (
|
||||||
<Grid.Col md={9}>
|
<Grid.Col md={9}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/embark/contracts/:contractName/overview" component={ContractContainer} />
|
<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/functions" component={ContractFunctionsContainer} />
|
||||||
<Route exact path="/embark/contracts/:contractName/source" component={ContractSourceContainer} />
|
<Route exact path="/embark/contracts/:contractName/source" component={ContractSourceContainer} />
|
||||||
<Route exact path="/embark/contracts/:contractName/profiler" component={ContractProfileContainer} />
|
<Route exact path="/embark/contracts/:contractName/profiler" component={ContractProfileContainer} />
|
||||||
|
|
|
@ -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));
|
|
@ -20,7 +20,6 @@ class ContractFunctionsContainer extends Component {
|
||||||
render={({contractProfile, contractFunctions, postContractFunction}) => (
|
render={({contractProfile, contractFunctions, postContractFunction}) => (
|
||||||
<ContractFunctions contractProfile={contractProfile}
|
<ContractFunctions contractProfile={contractProfile}
|
||||||
contractFunctions={contractFunctions}
|
contractFunctions={contractFunctions}
|
||||||
constructor={true}
|
|
||||||
postContractFunction={postContractFunction}/>
|
postContractFunction={postContractFunction}/>
|
||||||
)} />
|
)} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,6 +14,7 @@ const entitiesDefaultState = {
|
||||||
contractProfiles: [],
|
contractProfiles: [],
|
||||||
contractFiles: [],
|
contractFiles: [],
|
||||||
contractFunctions: [],
|
contractFunctions: [],
|
||||||
|
contractDeploys: [],
|
||||||
contractLogs: [],
|
contractLogs: [],
|
||||||
commands: [],
|
commands: [],
|
||||||
messages: [],
|
messages: [],
|
||||||
|
|
|
@ -70,6 +70,10 @@ export function getContractFunctions(state, contractName) {
|
||||||
return state.entities.contractFunctions.filter((contractFunction => contractFunction.contractName === 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) {
|
export function getVersions(state) {
|
||||||
return state.entities.versions;
|
return state.entities.versions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
const {account, accounts, block, blocks, transaction, transactions, processes, commands, processLogs,
|
||||||
contracts, contract, contractProfile, messageSend, versions, plugins, messageListen, fiddle,
|
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) {
|
function *doRequest(entity, apiFn, payload) {
|
||||||
const {response, error} = yield call(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 fetchContractProfile = doRequest.bind(null, contractProfile, api.fetchContractProfile);
|
||||||
export const fetchContractFile = doRequest.bind(null, contractFile, api.fetchContractFile);
|
export const fetchContractFile = doRequest.bind(null, contractFile, api.fetchContractFile);
|
||||||
export const postContractFunction = doRequest.bind(null, contractFunction, api.postContractFunction);
|
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 fetchFiddle = doRequest.bind(null, fiddle, api.fetchFiddle);
|
||||||
export const sendMessage = doRequest.bind(null, messageSend, api.sendMessage);
|
export const sendMessage = doRequest.bind(null, messageSend, api.sendMessage);
|
||||||
export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord);
|
export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord);
|
||||||
|
@ -98,6 +99,10 @@ export function *watchPostContractFunction() {
|
||||||
yield takeEvery(actions.CONTRACT_FUNCTION[actions.REQUEST], postContractFunction);
|
yield takeEvery(actions.CONTRACT_FUNCTION[actions.REQUEST], postContractFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function *watchPostContractDeploy() {
|
||||||
|
yield takeEvery(actions.CONTRACT_DEPLOY[actions.REQUEST], postContractDeploy);
|
||||||
|
}
|
||||||
|
|
||||||
export function *watchFetchVersions() {
|
export function *watchFetchVersions() {
|
||||||
yield takeEvery(actions.VERSIONS[actions.REQUEST], fetchVersions);
|
yield takeEvery(actions.VERSIONS[actions.REQUEST], fetchVersions);
|
||||||
}
|
}
|
||||||
|
@ -206,6 +211,7 @@ export default function *root() {
|
||||||
fork(watchFetchContractProfile),
|
fork(watchFetchContractProfile),
|
||||||
fork(watchFetchContractFile),
|
fork(watchFetchContractFile),
|
||||||
fork(watchPostContractFunction),
|
fork(watchPostContractFunction),
|
||||||
|
fork(watchPostContractDeploy),
|
||||||
fork(watchListenToMessages),
|
fork(watchListenToMessages),
|
||||||
fork(watchSendMessage),
|
fork(watchSendMessage),
|
||||||
fork(watchFetchContract),
|
fork(watchFetchContract),
|
||||||
|
|
|
@ -103,7 +103,7 @@ class ContractsManager {
|
||||||
account: (callback) => {
|
account: (callback) => {
|
||||||
self.events.request("blockchain:defaultAccount:get", (account) => callback(null, account));
|
self.events.request("blockchain:defaultAccount:get", (account) => callback(null, account));
|
||||||
}
|
}
|
||||||
}, function (error, result) {
|
}, (error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return res.send({error: error.message});
|
return res.send({error: error.message});
|
||||||
}
|
}
|
||||||
|
@ -117,10 +117,38 @@ class ContractsManager {
|
||||||
return res.send({result: error.message});
|
return res.send({result: error.message});
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.send({result});
|
res.send({result});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} 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});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue