mirror of https://github.com/embarklabs/embark.git
224 lines
9.0 KiB
JavaScript
224 lines
9.0 KiB
JavaScript
class Function extends React.Component {
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
onRequest: false,
|
|
fields: {},
|
|
methodFields: {
|
|
from: '',
|
|
to: '',
|
|
value: 0,
|
|
data: '',
|
|
gasLimit: '7000000'
|
|
},
|
|
receipt: null
|
|
};
|
|
|
|
this.handleParameterChange = this.handleParameterChange.bind(this);
|
|
this.handleMethodFieldChange = this.handleMethodFieldChange.bind(this);
|
|
this.handleClick = this.handleClick.bind(this);
|
|
}
|
|
|
|
async handleClick(e, instanceUpdateCallback){
|
|
e.preventDefault();
|
|
|
|
this.setState({onRequest: true, receipt: null});
|
|
|
|
this.props.resultHandler(false, null, null);
|
|
|
|
let executionParams = {
|
|
from: this.state.methodFields.from,
|
|
gasLimit: this.state.methodFields.gasLimit
|
|
}
|
|
|
|
if(this.props.abi.payable)
|
|
executionParams.value = this.state.methodFields.value;
|
|
|
|
if(this.props.abi.type == 'fallback'){
|
|
executionParams.data = this.state.methodFields.data;
|
|
executionParams.to = this.props.contract.options.address;
|
|
}
|
|
|
|
let fields = this.state.fields;
|
|
|
|
let functionLabel = this._getFunctionLabel();
|
|
let functionParams = this._getFunctionParamString();
|
|
let methodParams = this._getMethodString();
|
|
if(this.props.abi.type == "constructor")
|
|
functionParams = `{arguments: [${functionParams}]}`;
|
|
|
|
console.log(`%cawait ${functionLabel}(${functionParams})${this.props.abi.type != 'fallback' ? '.' + this._getMethodType() : ''}${methodParams}`, 'font-weight: bold');
|
|
|
|
let _receipt;
|
|
|
|
try {
|
|
if(this.props.abi.type == 'constructor'){
|
|
let contractInstance = await this.props.contract.deploy({arguments: Object.keys(fields).map(val => fields[val])}).send(executionParams);
|
|
instanceUpdateCallback(contractInstance.options.address);
|
|
this.setState({onRequest: false});
|
|
console.log(contractInstance.options.address);
|
|
this.props.resultHandler(false, 'New instance: ' + contractInstance.options.address);
|
|
} else {
|
|
|
|
if(this.props.abi.type == 'fallback')
|
|
_receipt = await this.web3.eth.sendTransaction(executionParams);
|
|
else
|
|
_receipt = await this.props.contract
|
|
.methods[this.props.abi.name + '(' + this.props.abi.inputs.map(input => input.type).join(',') + ')']
|
|
.apply(null, Object.keys(fields).map(val => fields[val]))
|
|
[this._getMethodType()](executionParams)
|
|
|
|
if(this._getMethodType() == 'call'){
|
|
console.log("A");
|
|
this.props.resultHandler(false, _receipt, null);
|
|
} else {
|
|
this.props.resultHandler(false, null, _receipt);
|
|
}
|
|
|
|
this.setState({onRequest: false, receipt: _receipt});
|
|
console.log(_receipt);
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
console.error('%s: %s', e.name, e.message);
|
|
this.setState({onRequest: false});
|
|
this.props.resultHandler(true, e.name + ": " + e.message, _receipt);
|
|
}
|
|
}
|
|
|
|
handleParameterChange(e){
|
|
let newState = this.state;
|
|
newState.fields[e.target.getAttribute('data-name')] = e.target.value;
|
|
this.setState(newState);
|
|
}
|
|
|
|
handleMethodFieldChange(e){
|
|
let newState = this.state;
|
|
newState.methodFields[e.target.getAttribute('data-param')] = e.target.value;
|
|
|
|
if(e.target.getAttribute('data-param') == 'from'){
|
|
newState.selectedAccount = e.target.options[e.target.selectedIndex].text;
|
|
}
|
|
this.setState(newState);
|
|
}
|
|
|
|
_getFunctionLabel(){
|
|
if(this.props.abi.type == 'function')
|
|
if(!this.props.duplicated)
|
|
return `${this.props.contractName}.methods.${this.props.abi.name}`;
|
|
else {
|
|
return `${this.props.contractName}.methods['${this.props.abi.name + '(' + (this.props.abi.inputs != null ? this.props.abi.inputs.map(input => input.type).join(',') : '') + ')'}']`;
|
|
}
|
|
else if(this.props.abi.type == 'fallback'){
|
|
return `web3.eth.sendTransaction`;
|
|
}
|
|
else
|
|
return `${this.props.contractName}.deploy`;
|
|
}
|
|
|
|
_getMethodType(){
|
|
return (this.props.abi.constant == true || this.props.abi.stateMutability == 'view' || this.props.abi.stateMutability == 'pure') ? 'call' : 'send';
|
|
}
|
|
|
|
_getMethodFields(accounts){
|
|
let methodParams;
|
|
return <React.Fragment>
|
|
from: <select data-param="from" disabled={accounts.length == 0} value={this.state.from} onChange={this.handleMethodFieldChange}>
|
|
<option>-</option>
|
|
{
|
|
accounts.map(function (item, i) {
|
|
return <option key={i} value={item}>{`accounts[${i}]`}</option>;
|
|
})
|
|
}
|
|
</select>
|
|
{
|
|
this.props.abi.payable ?
|
|
<span>, value:
|
|
<input type="text" data-param="value" value={this.state.methodFields.value} size="6" onChange={this.handleMethodFieldChange} />
|
|
</span>
|
|
: ''
|
|
}
|
|
{
|
|
this._getMethodType() == 'send' ?
|
|
<span>, gasLimit:
|
|
<input type="text" data-param="gasLimit" value={this.state.methodFields.gasLimit} size="6" onChange={this.handleMethodFieldChange} />
|
|
</span>
|
|
: ''
|
|
}
|
|
{
|
|
this._getMethodType() == 'send' && this.props.abi.type == 'fallback' ?
|
|
<span>, data:
|
|
<input type="text" data-param="data" value={this.state.methodFields.data} size="6" onChange={this.handleMethodFieldChange} />
|
|
</span>
|
|
: ''
|
|
}
|
|
</React.Fragment>;
|
|
}
|
|
|
|
|
|
_getFunctionParamFields(){
|
|
return <React.Fragment>
|
|
{
|
|
this.props.abi.inputs
|
|
.map((input, i) => <input key={i} type="text" data-var-type={input.type} data-type="inputParam" data-name={input.name} placeholder={input.name} title={input.type + ' ' + input.name} size={input.name.length + 2} value={this.state.fields[input.name] || ''} onChange={this.handleParameterChange} />)
|
|
.reduce((accu, elem) => {
|
|
return accu === null ? [elem] : [...accu, ', ', elem]
|
|
}, null)
|
|
}
|
|
</React.Fragment>;
|
|
}
|
|
|
|
_getFunctionParamString(){
|
|
if(this.props.abi.type == 'fallback') return '';
|
|
return this.props.abi.inputs
|
|
.map((input, i) => (input.type.indexOf('int') == -1 ? '"' : '') + this.state.fields[input.name] + (input.type.indexOf('int') == -1 ? '"' : ''))
|
|
.join(', ');
|
|
}
|
|
|
|
_getMethodString(elem){
|
|
let methodParams = "({";
|
|
|
|
methodParams += `from: ` + this.state.selectedAccount;
|
|
if(this._getMethodType() == 'send'){
|
|
methodParams += ', gasLimit: ' + this.state.methodFields.gasLimit
|
|
if(this.props.abi.payable){
|
|
methodParams += ', value: ' + this.state.methodFields.value
|
|
}
|
|
if(this.props.abi.type == 'fallback'){
|
|
methodParams += ', data: "' + this.state.methodFields.data + '", to: "' + this.state.methodFields.to + '"'
|
|
}
|
|
}
|
|
return methodParams + "})";
|
|
}
|
|
|
|
render(){
|
|
return <ContractContext.Consumer>
|
|
{ (context) => (
|
|
<React.Fragment>
|
|
<div className="col-md-11">
|
|
<code>
|
|
await {this._getFunctionLabel()}
|
|
{ this.props.abi.type != 'fallback' ? '(' : '' }
|
|
{ this.props.abi.type != 'fallback' ? this._getFunctionParamFields() : '' }
|
|
{ this.props.abi.type != 'fallback' ? ')' : '' }
|
|
{ this.props.abi.type != 'fallback' ? '.' + this._getMethodType() : '' }
|
|
({ this._getMethodFields(context.accounts) })
|
|
</code>
|
|
</div>
|
|
<div className="col-md-1">
|
|
<button className="btn btn-primary ml-auto" onClick={event => this.handleClick(event, context.updateInstances)} disabled={this.state.onRequest}>
|
|
{ this.state.onRequest ?
|
|
<img src="../assets/images/loading.gif" className="loading" alt="" />
|
|
:
|
|
<React.Fragment>⏎</React.Fragment>
|
|
}
|
|
</button>
|
|
</div>
|
|
</React.Fragment>
|
|
)}
|
|
</ContractContext.Consumer>;
|
|
}
|
|
|
|
} |