Edit ETH value, gas and gas price in Contract Deployment (#4919)
* Fix typo * Add Value capabilities to Contract Deployment * Add Extras settings for Contract Deployment (#4483) * Fix deploy in API
This commit is contained in:
parent
57d718fde1
commit
7846544c1b
@ -107,13 +107,25 @@ export default class Contract {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deploy (options, values, statecb = () => {}) {
|
deploy (options, values, statecb = () => {}, skipGasEstimate = false) {
|
||||||
statecb(null, { state: 'estimateGas' });
|
let gasEstPromise;
|
||||||
|
|
||||||
return this
|
if (skipGasEstimate) {
|
||||||
.deployEstimateGas(options, values)
|
gasEstPromise = Promise.resolve(null);
|
||||||
.then(([gasEst, gas]) => {
|
} else {
|
||||||
options.gas = gas.toFixed(0);
|
statecb(null, { state: 'estimateGas' });
|
||||||
|
|
||||||
|
gasEstPromise = this.deployEstimateGas(options, values)
|
||||||
|
.then(([gasEst, gas]) => gas);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gasEstPromise
|
||||||
|
.then((_gas) => {
|
||||||
|
if (_gas) {
|
||||||
|
options.gas = _gas.toFixed(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gas = _gas || options.gas;
|
||||||
|
|
||||||
statecb(null, { state: 'postTransaction', gas });
|
statecb(null, { state: 'postTransaction', gas });
|
||||||
|
|
||||||
|
@ -16,12 +16,16 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { MenuItem } from 'material-ui';
|
import { Checkbox, MenuItem } from 'material-ui';
|
||||||
|
|
||||||
import { AddressSelect, Form, Input, Select } from '~/ui';
|
import { AddressSelect, Form, Input, Select } from '~/ui';
|
||||||
import { validateAbi } from '~/util/validation';
|
import { validateAbi } from '~/util/validation';
|
||||||
import { parseAbiType } from '~/util/abi';
|
import { parseAbiType } from '~/util/abi';
|
||||||
|
|
||||||
|
const CHECK_STYLE = {
|
||||||
|
marginTop: '1em'
|
||||||
|
};
|
||||||
|
|
||||||
export default class DetailsStep extends Component {
|
export default class DetailsStep extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
api: PropTypes.object.isRequired
|
api: PropTypes.object.isRequired
|
||||||
@ -30,8 +34,10 @@ export default class DetailsStep extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
accounts: PropTypes.object.isRequired,
|
accounts: PropTypes.object.isRequired,
|
||||||
onAbiChange: PropTypes.func.isRequired,
|
onAbiChange: PropTypes.func.isRequired,
|
||||||
|
onAmountChange: PropTypes.func.isRequired,
|
||||||
onCodeChange: PropTypes.func.isRequired,
|
onCodeChange: PropTypes.func.isRequired,
|
||||||
onDescriptionChange: PropTypes.func.isRequired,
|
onDescriptionChange: PropTypes.func.isRequired,
|
||||||
|
onExtrasChange: PropTypes.func.isRequired,
|
||||||
onFromAddressChange: PropTypes.func.isRequired,
|
onFromAddressChange: PropTypes.func.isRequired,
|
||||||
onInputsChange: PropTypes.func.isRequired,
|
onInputsChange: PropTypes.func.isRequired,
|
||||||
onNameChange: PropTypes.func.isRequired,
|
onNameChange: PropTypes.func.isRequired,
|
||||||
@ -39,11 +45,14 @@ export default class DetailsStep extends Component {
|
|||||||
|
|
||||||
abi: PropTypes.string,
|
abi: PropTypes.string,
|
||||||
abiError: PropTypes.string,
|
abiError: PropTypes.string,
|
||||||
|
amount: PropTypes.string,
|
||||||
|
amountError: PropTypes.string,
|
||||||
balances: PropTypes.object,
|
balances: PropTypes.object,
|
||||||
code: PropTypes.string,
|
code: PropTypes.string,
|
||||||
codeError: PropTypes.string,
|
codeError: PropTypes.string,
|
||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
descriptionError: PropTypes.string,
|
descriptionError: PropTypes.string,
|
||||||
|
extras: PropTypes.bool,
|
||||||
fromAddress: PropTypes.string,
|
fromAddress: PropTypes.string,
|
||||||
fromAddressError: PropTypes.string,
|
fromAddressError: PropTypes.string,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
@ -52,6 +61,7 @@ export default class DetailsStep extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
extras: false,
|
||||||
readOnly: false
|
readOnly: false
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,7 +93,7 @@ export default class DetailsStep extends Component {
|
|||||||
fromAddress, fromAddressError,
|
fromAddress, fromAddressError,
|
||||||
name, nameError,
|
name, nameError,
|
||||||
description, descriptionError,
|
description, descriptionError,
|
||||||
abiError,
|
abiError, extras,
|
||||||
code, codeError
|
code, codeError
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@ -189,10 +199,70 @@ export default class DetailsStep extends Component {
|
|||||||
value={ code }
|
value={ code }
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{ this.renderValueInput() }
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Checkbox
|
||||||
|
checked={ extras }
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='deployContract.details.advanced.label'
|
||||||
|
defaultMessage='advanced sending options'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onCheck={ this.onCheckExtras }
|
||||||
|
style={ CHECK_STYLE }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderValueInput () {
|
||||||
|
const { abi, amount, amountError } = this.props;
|
||||||
|
|
||||||
|
let payable = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsedAbi = JSON.parse(abi);
|
||||||
|
|
||||||
|
payable = parsedAbi.find((method) => method.type === 'constructor' && method.payable);
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!payable) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
error={ amountError }
|
||||||
|
hint={
|
||||||
|
<FormattedMessage
|
||||||
|
id='deployContract.details.amount.hint'
|
||||||
|
defaultMessage='the amount to transfer to the contract'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='deployContract.details.amount.label'
|
||||||
|
defaultMessage='amount to transfer (in {tag})'
|
||||||
|
values={ {
|
||||||
|
tag: 'ETH'
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
min={ 0 }
|
||||||
|
step={ 0.1 }
|
||||||
|
type='number'
|
||||||
|
onChange={ this.onAmountChange }
|
||||||
|
value={ amount }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
renderContractSelect () {
|
renderContractSelect () {
|
||||||
const { contracts } = this.state;
|
const { contracts } = this.state;
|
||||||
|
|
||||||
@ -295,6 +365,16 @@ export default class DetailsStep extends Component {
|
|||||||
onDescriptionChange(description);
|
onDescriptionChange(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAmountChange = (event, value) => {
|
||||||
|
const { onAmountChange } = this.props;
|
||||||
|
|
||||||
|
onAmountChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCheckExtras = () => {
|
||||||
|
this.props.onExtrasChange(!this.props.extras);
|
||||||
|
}
|
||||||
|
|
||||||
onAbiChange = (abi) => {
|
onAbiChange = (abi) => {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
const { onAbiChange, onParamsChange, onInputsChange } = this.props;
|
const { onAbiChange, onParamsChange, onInputsChange } = this.props;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
@ -22,12 +23,13 @@ import { connect } from 'react-redux';
|
|||||||
|
|
||||||
import { BusyStep, Button, CompletedStep, CopyToClipboard, GasPriceEditor, IdentityIcon, Portal, TxHash, Warning } from '~/ui';
|
import { BusyStep, Button, CompletedStep, CopyToClipboard, GasPriceEditor, IdentityIcon, Portal, TxHash, Warning } from '~/ui';
|
||||||
import { CancelIcon, DoneIcon } from '~/ui/Icons';
|
import { CancelIcon, DoneIcon } from '~/ui/Icons';
|
||||||
import { ERRORS, validateAbi, validateCode, validateName } from '~/util/validation';
|
import { ERRORS, validateAbi, validateCode, validateName, validatePositiveNumber } from '~/util/validation';
|
||||||
import { deploy, deployEstimateGas } from '~/util/tx';
|
import { deploy, deployEstimateGas } from '~/util/tx';
|
||||||
|
|
||||||
import DetailsStep from './DetailsStep';
|
import DetailsStep from './DetailsStep';
|
||||||
import ParametersStep from './ParametersStep';
|
import ParametersStep from './ParametersStep';
|
||||||
import ErrorStep from './ErrorStep';
|
import ErrorStep from './ErrorStep';
|
||||||
|
import Extras from '../Transfer/Extras';
|
||||||
|
|
||||||
import styles from './deployContract.css';
|
import styles from './deployContract.css';
|
||||||
|
|
||||||
@ -50,6 +52,14 @@ const STEPS = {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
EXTRAS: {
|
||||||
|
title: (
|
||||||
|
<FormattedMessage
|
||||||
|
id='deployContract.title.extras'
|
||||||
|
defaultMessage='extra information'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
DEPLOYMENT: {
|
DEPLOYMENT: {
|
||||||
waiting: true,
|
waiting: true,
|
||||||
title: (
|
title: (
|
||||||
@ -97,12 +107,16 @@ class DeployContract extends Component {
|
|||||||
state = {
|
state = {
|
||||||
abi: '',
|
abi: '',
|
||||||
abiError: ERRORS.invalidAbi,
|
abiError: ERRORS.invalidAbi,
|
||||||
|
amount: '0',
|
||||||
|
amountValue: new BigNumber(0),
|
||||||
|
amountError: '',
|
||||||
code: '',
|
code: '',
|
||||||
codeError: ERRORS.invalidCode,
|
codeError: ERRORS.invalidCode,
|
||||||
deployState: '',
|
deployState: '',
|
||||||
deployError: null,
|
deployError: null,
|
||||||
description: '',
|
description: '',
|
||||||
descriptionError: null,
|
descriptionError: null,
|
||||||
|
extras: false,
|
||||||
fromAddress: Object.keys(this.props.accounts)[0],
|
fromAddress: Object.keys(this.props.accounts)[0],
|
||||||
fromAddressError: null,
|
fromAddressError: null,
|
||||||
name: '',
|
name: '',
|
||||||
@ -144,7 +158,19 @@ class DeployContract extends Component {
|
|||||||
|
|
||||||
const realStepKeys = deployError || rejected
|
const realStepKeys = deployError || rejected
|
||||||
? []
|
? []
|
||||||
: Object.keys(STEPS).filter((k) => k !== 'CONTRACT_PARAMETERS' || inputs.length > 0);
|
: Object.keys(STEPS)
|
||||||
|
.filter((k) => {
|
||||||
|
if (k === 'CONTRACT_PARAMETERS') {
|
||||||
|
return inputs.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k === 'EXTRAS') {
|
||||||
|
return this.state.extras;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
const realStep = realStepKeys.findIndex((k) => k === step);
|
const realStep = realStepKeys.findIndex((k) => k === step);
|
||||||
const realSteps = realStepKeys.length
|
const realSteps = realStepKeys.length
|
||||||
? realStepKeys.map((k) => STEPS[k])
|
? realStepKeys.map((k) => STEPS[k])
|
||||||
@ -207,8 +233,8 @@ class DeployContract extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderDialogActions () {
|
renderDialogActions () {
|
||||||
const { deployError, abiError, codeError, nameError, descriptionError, fromAddressError, fromAddress, step } = this.state;
|
const { deployError, abiError, amountError, codeError, nameError, descriptionError, fromAddressError, fromAddress, step } = this.state;
|
||||||
const isValid = !nameError && !fromAddressError && !descriptionError && !abiError && !codeError;
|
const isValid = !nameError && !fromAddressError && !descriptionError && !abiError && !codeError && !amountError;
|
||||||
|
|
||||||
const cancelBtn = (
|
const cancelBtn = (
|
||||||
<Button
|
<Button
|
||||||
@ -256,48 +282,69 @@ class DeployContract extends Component {
|
|||||||
return closeBtn;
|
return closeBtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createButton = (
|
||||||
|
<Button
|
||||||
|
icon={
|
||||||
|
<IdentityIcon
|
||||||
|
address={ fromAddress }
|
||||||
|
button
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
key='create'
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='deployContract.button.create'
|
||||||
|
defaultMessage='Create'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onClick={ this.onDeployStart }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextButton = (
|
||||||
|
<Button
|
||||||
|
disabled={ !isValid }
|
||||||
|
key='next'
|
||||||
|
icon={
|
||||||
|
<IdentityIcon
|
||||||
|
address={ fromAddress }
|
||||||
|
button
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='deployContract.button.next'
|
||||||
|
defaultMessage='Next'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onClick={ this.onNextStep }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasParameters = this.state.inputs.length > 0;
|
||||||
|
const showExtras = this.state.extras;
|
||||||
|
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 'CONTRACT_DETAILS':
|
case 'CONTRACT_DETAILS':
|
||||||
return [
|
return [
|
||||||
cancelBtn,
|
cancelBtn,
|
||||||
<Button
|
hasParameters || showExtras
|
||||||
disabled={ !isValid }
|
? nextButton
|
||||||
key='next'
|
: createButton
|
||||||
icon={
|
|
||||||
<IdentityIcon
|
|
||||||
address={ fromAddress }
|
|
||||||
button
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={
|
|
||||||
<FormattedMessage
|
|
||||||
id='deployContract.button.next'
|
|
||||||
defaultMessage='Next'
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onClick={ this.onParametersStep }
|
|
||||||
/>
|
|
||||||
];
|
];
|
||||||
|
|
||||||
case 'CONTRACT_PARAMETERS':
|
case 'CONTRACT_PARAMETERS':
|
||||||
return [
|
return [
|
||||||
cancelBtn,
|
cancelBtn,
|
||||||
<Button
|
showExtras
|
||||||
icon={
|
? nextButton
|
||||||
<IdentityIcon
|
: createButton
|
||||||
address={ fromAddress }
|
];
|
||||||
button
|
|
||||||
/>
|
case 'EXTRAS':
|
||||||
}
|
return [
|
||||||
key='create'
|
cancelBtn,
|
||||||
label={
|
createButton
|
||||||
<FormattedMessage
|
|
||||||
id='deployContract.button.create'
|
|
||||||
defaultMessage='Create'
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onClick={ this.onDeployStart }
|
|
||||||
/>
|
|
||||||
];
|
];
|
||||||
|
|
||||||
case 'DEPLOYMENT':
|
case 'DEPLOYMENT':
|
||||||
@ -344,6 +391,8 @@ class DeployContract extends Component {
|
|||||||
{ ...this.state }
|
{ ...this.state }
|
||||||
accounts={ accounts }
|
accounts={ accounts }
|
||||||
balances={ balances }
|
balances={ balances }
|
||||||
|
onAmountChange={ this.onAmountChange }
|
||||||
|
onExtrasChange={ this.onExtrasChange }
|
||||||
onFromAddressChange={ this.onFromAddressChange }
|
onFromAddressChange={ this.onFromAddressChange }
|
||||||
onDescriptionChange={ this.onDescriptionChange }
|
onDescriptionChange={ this.onDescriptionChange }
|
||||||
onNameChange={ this.onNameChange }
|
onNameChange={ this.onNameChange }
|
||||||
@ -365,6 +414,9 @@ class DeployContract extends Component {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
case 'EXTRAS':
|
||||||
|
return this.renderExtrasPage();
|
||||||
|
|
||||||
case 'DEPLOYMENT':
|
case 'DEPLOYMENT':
|
||||||
const body = txhash
|
const body = txhash
|
||||||
? <TxHash hash={ txhash } />
|
? <TxHash hash={ txhash } />
|
||||||
@ -411,17 +463,32 @@ class DeployContract extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderExtrasPage () {
|
||||||
|
if (!this.gasStore.histogram) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Extras
|
||||||
|
gasStore={ this.gasStore }
|
||||||
|
hideData
|
||||||
|
isEth
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
estimateGas = () => {
|
estimateGas = () => {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
const { abiError, abiParsed, code, codeError, fromAddress, fromAddressError, params } = this.state;
|
const { abiError, abiParsed, amountValue, amountError, code, codeError, fromAddress, fromAddressError, params } = this.state;
|
||||||
|
|
||||||
if (abiError || codeError || fromAddressError) {
|
if (abiError || codeError || fromAddressError || amountError) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
data: code,
|
data: code,
|
||||||
from: fromAddress
|
from: fromAddress,
|
||||||
|
value: amountValue
|
||||||
};
|
};
|
||||||
|
|
||||||
const contract = api.newContract(abiParsed);
|
const contract = api.newContract(abiParsed);
|
||||||
@ -437,6 +504,19 @@ class DeployContract extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onNextStep = () => {
|
||||||
|
switch (this.state.step) {
|
||||||
|
case 'CONTRACT_DETAILS':
|
||||||
|
return this.onParametersStep();
|
||||||
|
|
||||||
|
case 'CONTRACT_PARAMETERS':
|
||||||
|
return this.onExtrasStep();
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.warn('wrong call of "onNextStep" from', this.state.step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onParametersStep = () => {
|
onParametersStep = () => {
|
||||||
const { inputs } = this.state;
|
const { inputs } = this.state;
|
||||||
|
|
||||||
@ -444,6 +524,14 @@ class DeployContract extends Component {
|
|||||||
return this.setState({ step: 'CONTRACT_PARAMETERS' });
|
return this.setState({ step: 'CONTRACT_PARAMETERS' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.onExtrasStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
onExtrasStep = () => {
|
||||||
|
if (this.state.extras) {
|
||||||
|
return this.setState({ step: 'EXTRAS' });
|
||||||
|
}
|
||||||
|
|
||||||
return this.onDeployStart();
|
return this.onDeployStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,10 +576,24 @@ class DeployContract extends Component {
|
|||||||
this.setState(validateCode(code), this.estimateGas);
|
this.setState(validateCode(code), this.estimateGas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAmountChange = (amount) => {
|
||||||
|
const { numberError } = validatePositiveNumber(amount);
|
||||||
|
const nextAmountValue = numberError
|
||||||
|
? new BigNumber(0)
|
||||||
|
: this.context.api.util.toWei(amount);
|
||||||
|
|
||||||
|
this.gasStore.setEthValue(nextAmountValue);
|
||||||
|
this.setState({ amount, amountValue: nextAmountValue, amountError: numberError }, this.estimateGas);
|
||||||
|
}
|
||||||
|
|
||||||
|
onExtrasChange = (extras) => {
|
||||||
|
this.setState({ extras });
|
||||||
|
}
|
||||||
|
|
||||||
onDeployStart = () => {
|
onDeployStart = () => {
|
||||||
const { api, store } = this.context;
|
const { api, store } = this.context;
|
||||||
const { source } = this.props;
|
const { source } = this.props;
|
||||||
const { abiParsed, code, description, name, params, fromAddress } = this.state;
|
const { abiParsed, amountValue, code, description, name, params, fromAddress } = this.state;
|
||||||
|
|
||||||
const metadata = {
|
const metadata = {
|
||||||
abi: abiParsed,
|
abi: abiParsed,
|
||||||
@ -503,16 +605,17 @@ class DeployContract extends Component {
|
|||||||
source
|
source
|
||||||
};
|
};
|
||||||
|
|
||||||
const options = {
|
const options = this.gasStore.overrideTransaction({
|
||||||
data: code,
|
data: code,
|
||||||
from: fromAddress
|
from: fromAddress,
|
||||||
};
|
value: amountValue
|
||||||
|
});
|
||||||
|
|
||||||
this.setState({ step: 'DEPLOYMENT' });
|
this.setState({ step: 'DEPLOYMENT' });
|
||||||
|
|
||||||
const contract = api.newContract(abiParsed);
|
const contract = api.newContract(abiParsed);
|
||||||
|
|
||||||
deploy(contract, options, params, metadata, this.onDeploymentState)
|
deploy(contract, options, params, metadata, this.onDeploymentState, true)
|
||||||
.then((address) => {
|
.then((address) => {
|
||||||
// No contract address given, might need some confirmations
|
// No contract address given, might need some confirmations
|
||||||
// from the wallet owners...
|
// from the wallet owners...
|
||||||
|
@ -24,7 +24,7 @@ import { nullableProptype } from '~/util/proptypes';
|
|||||||
import TokenSelect from './tokenSelect';
|
import TokenSelect from './tokenSelect';
|
||||||
import styles from '../transfer.css';
|
import styles from '../transfer.css';
|
||||||
|
|
||||||
const CHECK_STYLE = {
|
export const CHECK_STYLE = {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: '38px',
|
top: '38px',
|
||||||
left: '1em'
|
left: '1em'
|
||||||
|
@ -25,12 +25,17 @@ export default class Extras extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
data: PropTypes.string,
|
data: PropTypes.string,
|
||||||
dataError: PropTypes.string,
|
dataError: PropTypes.string,
|
||||||
|
hideData: PropTypes.bool,
|
||||||
gasStore: PropTypes.object.isRequired,
|
gasStore: PropTypes.object.isRequired,
|
||||||
isEth: PropTypes.bool,
|
isEth: PropTypes.bool,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func,
|
||||||
total: PropTypes.string,
|
total: PropTypes.string,
|
||||||
totalError: PropTypes.string
|
totalError: PropTypes.string
|
||||||
}
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
hideData: false
|
||||||
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { gasStore, onChange } = this.props;
|
const { gasStore, onChange } = this.props;
|
||||||
@ -49,9 +54,9 @@ export default class Extras extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderData () {
|
renderData () {
|
||||||
const { isEth, data, dataError } = this.props;
|
const { isEth, data, dataError, hideData } = this.props;
|
||||||
|
|
||||||
if (!isEth) {
|
if (!isEth || hideData) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ export default class Input extends Component {
|
|||||||
tabIndex: PropTypes.number,
|
tabIndex: PropTypes.number,
|
||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
submitOnBlur: PropTypes.bool,
|
submitOnBlur: PropTypes.bool,
|
||||||
|
step: PropTypes.number,
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
value: PropTypes.oneOfType([
|
value: PropTypes.oneOfType([
|
||||||
PropTypes.number,
|
PropTypes.number,
|
||||||
@ -124,7 +125,7 @@ export default class Input extends Component {
|
|||||||
render () {
|
render () {
|
||||||
const { value } = this.state;
|
const { value } = this.state;
|
||||||
const { autoFocus, children, className, hideUnderline, disabled, error, focused, label } = this.props;
|
const { autoFocus, children, className, hideUnderline, disabled, error, focused, label } = this.props;
|
||||||
const { hint, onClick, multiLine, rows, type, min, max, style, tabIndex } = this.props;
|
const { hint, onClick, multiLine, rows, type, min, max, step, style, tabIndex } = this.props;
|
||||||
|
|
||||||
const readOnly = this.props.readOnly || disabled;
|
const readOnly = this.props.readOnly || disabled;
|
||||||
|
|
||||||
@ -179,6 +180,7 @@ export default class Input extends Component {
|
|||||||
readOnly={ readOnly }
|
readOnly={ readOnly }
|
||||||
ref='input'
|
ref='input'
|
||||||
rows={ rows }
|
rows={ rows }
|
||||||
|
step={ step }
|
||||||
style={ textFieldStyle }
|
style={ textFieldStyle }
|
||||||
tabIndex={ tabIndex }
|
tabIndex={ tabIndex }
|
||||||
type={ type || 'text' }
|
type={ type || 'text' }
|
||||||
|
@ -107,7 +107,7 @@ class MethodDecoding extends Component {
|
|||||||
|
|
||||||
renderGas () {
|
renderGas () {
|
||||||
const { historic, transaction } = this.props;
|
const { historic, transaction } = this.props;
|
||||||
const { gas, gasPrice } = transaction;
|
const { gas, gasPrice, value } = transaction;
|
||||||
|
|
||||||
if (!gas || !gasPrice) {
|
if (!gas || !gasPrice) {
|
||||||
return null;
|
return null;
|
||||||
@ -126,9 +126,9 @@ class MethodDecoding extends Component {
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
const gasProvidedEth = (
|
const totalEthValue = (
|
||||||
<span className={ styles.highlight }>
|
<span className={ styles.highlight }>
|
||||||
{ this.renderEtherValue(gas.mul(gasPrice)) }
|
{ this.renderEtherValue(gas.mul(gasPrice).plus(value || 0)) }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
const gasUsed = transaction.gasUsed
|
const gasUsed = transaction.gasUsed
|
||||||
@ -149,12 +149,12 @@ class MethodDecoding extends Component {
|
|||||||
<div className={ styles.gasDetails }>
|
<div className={ styles.gasDetails }>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='ui.methodDecoding.txValues'
|
id='ui.methodDecoding.txValues'
|
||||||
defaultMessage='{historic, select, true {Provided} false {Provides}} {gasProvided}{gasUsed} for a total transaction value of {gasProvidedEth}'
|
defaultMessage='{historic, select, true {Provided} false {Provides}} {gasProvided}{gasUsed} for a total transaction value of {totalEthValue}'
|
||||||
values={ {
|
values={ {
|
||||||
historic,
|
historic,
|
||||||
gasProvided,
|
gasProvided,
|
||||||
gasProvidedEth,
|
gasUsed,
|
||||||
gasUsed
|
totalEthValue
|
||||||
} }
|
} }
|
||||||
/>
|
/>
|
||||||
{ this.renderMinBlock() }
|
{ this.renderMinBlock() }
|
||||||
@ -349,6 +349,7 @@ class MethodDecoding extends Component {
|
|||||||
renderDeploy () {
|
renderDeploy () {
|
||||||
const { historic, transaction } = this.props;
|
const { historic, transaction } = this.props;
|
||||||
const { methodInputs } = this.state;
|
const { methodInputs } = this.state;
|
||||||
|
const { value } = transaction;
|
||||||
|
|
||||||
if (!historic) {
|
if (!historic) {
|
||||||
return (
|
return (
|
||||||
@ -357,6 +358,19 @@ class MethodDecoding extends Component {
|
|||||||
id='ui.methodDecoding.deploy.willDeploy'
|
id='ui.methodDecoding.deploy.willDeploy'
|
||||||
defaultMessage='Will deploy a contract'
|
defaultMessage='Will deploy a contract'
|
||||||
/>
|
/>
|
||||||
|
{
|
||||||
|
value && value.gt(0)
|
||||||
|
? (
|
||||||
|
<FormattedMessage
|
||||||
|
id='ui.methodDecoding.deploy.withValue'
|
||||||
|
defaultMessage=', sending {value}'
|
||||||
|
values={ {
|
||||||
|
value: this.renderEtherValue(value)
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
: null
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ export function postTransaction (_func, _options, _values = []) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deploy (contract, _options, values, metadata = {}, statecb = () => {}) {
|
export function deploy (contract, _options, values, metadata = {}, statecb = () => {}, skipGasEstimate = false) {
|
||||||
const options = { ..._options };
|
const options = { ..._options };
|
||||||
const { api } = contract;
|
const { api } = contract;
|
||||||
const address = options.from;
|
const address = options.from;
|
||||||
@ -82,16 +82,27 @@ export function deploy (contract, _options, values, metadata = {}, statecb = ()
|
|||||||
.isWallet(api, address)
|
.isWallet(api, address)
|
||||||
.then((isWallet) => {
|
.then((isWallet) => {
|
||||||
if (!isWallet) {
|
if (!isWallet) {
|
||||||
return contract.deploy(options, values, statecb);
|
return contract.deploy(options, values, statecb, skipGasEstimate);
|
||||||
}
|
}
|
||||||
|
|
||||||
statecb(null, { state: 'estimateGas' });
|
let gasEstPromise;
|
||||||
|
|
||||||
return deployEstimateGas(contract, options, values)
|
if (skipGasEstimate) {
|
||||||
.then(([gasEst, gas]) => {
|
gasEstPromise = Promise.resolve(null);
|
||||||
options.gas = gas.toFixed(0);
|
} else {
|
||||||
|
statecb(null, { state: 'estimateGas' });
|
||||||
|
|
||||||
statecb(null, { state: 'postTransaction', gas });
|
gasEstPromise = deployEstimateGas(contract, options, values)
|
||||||
|
.then(([gasEst, gas]) => gas);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gasEstPromise
|
||||||
|
.then((gas) => {
|
||||||
|
if (gas) {
|
||||||
|
options.gas = gas.toFixed(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
statecb(null, { state: 'postTransaction', gas: options.gas });
|
||||||
|
|
||||||
return WalletsUtils.getDeployArgs(contract, options, values);
|
return WalletsUtils.getDeployArgs(contract, options, values);
|
||||||
})
|
})
|
||||||
|
@ -105,7 +105,7 @@ class WriteContract extends Component {
|
|||||||
className={ styles.editor }
|
className={ styles.editor }
|
||||||
style={ { flex: `${size}%` } }
|
style={ { flex: `${size}%` } }
|
||||||
>
|
>
|
||||||
<h2>asd{ this.renderTitle() }</h2>
|
<h2>{ this.renderTitle() }</h2>
|
||||||
|
|
||||||
<Editor
|
<Editor
|
||||||
ref='editor'
|
ref='editor'
|
||||||
|
Loading…
Reference in New Issue
Block a user