mirror of
https://github.com/status-im/contracts.git
synced 2025-02-23 12:08:47 +00:00
Added fallback support
This commit is contained in:
parent
2b8a18f382
commit
9e67fe4d49
@ -1,6 +1,10 @@
|
||||
class ContractUI {
|
||||
|
||||
constructor(name, contract, sourceURL){
|
||||
// TODO
|
||||
// 1 Fallback
|
||||
|
||||
constructor(web3, name, contract, sourceURL){
|
||||
this.web3 = web3;
|
||||
this.instances = [];
|
||||
this.name = name;
|
||||
this.contract = contract;
|
||||
@ -36,16 +40,19 @@ class ContractUI {
|
||||
this._loadAccounts();
|
||||
$('#getAccounts button').on('click', this._loadAccounts);
|
||||
|
||||
this._setupInstanceSelector();
|
||||
|
||||
this.contract.options.jsonInterface.forEach((elem, i) => {
|
||||
if(elem.type != "function" && elem.type != 'constructor') return;
|
||||
|
||||
if(elem.type != "function" && elem.type != 'constructor' && elem.type != 'fallback') return;
|
||||
|
||||
const isDuplicated = this.contract.options.jsonInterface.filter(x => x.name == elem.name).length > 1;
|
||||
const functionLabel = this._getFunctionLabel(elem, isDuplicated);
|
||||
const functionElem = $(`<div class="function" id="${this.name}-${i}">
|
||||
<h4>${elem.type == 'function' ? elem.name : this.name}</h4>
|
||||
<h4>${elem.type == 'function' ? elem.name : (elem.type == 'fallback' ? '(fallback)' : this.name)}</h4>
|
||||
<div class="scenario">
|
||||
<div class="code">
|
||||
await ${functionLabel}(${this._getFunctionParamFields(elem)}).${this._getMethodType(elem)}(${this.getMethodFields(elem)}) <button>⏎</button>
|
||||
await ${functionLabel}${this._getFunctionParamFields(elem)}${elem.type != 'fallback' ? '.' + this._getMethodType(elem) : ''}${this.getMethodFields(elem)} <button>⏎</button>
|
||||
<img src="images/loading.gif" class="loading" alt="" />
|
||||
</div>
|
||||
<p class="error"></p>
|
||||
@ -57,7 +64,7 @@ class ContractUI {
|
||||
|
||||
$('.loading', functionElem).hide();
|
||||
|
||||
if(elem.type == 'function'){
|
||||
if(elem.type == 'function' || elem.type == 'fallback'){
|
||||
functionContainer.append(functionElem);
|
||||
} else {
|
||||
constructorContainer.append(functionElem);
|
||||
@ -74,14 +81,66 @@ class ContractUI {
|
||||
}
|
||||
|
||||
|
||||
_setupInstanceSelector(){
|
||||
$('#changeLnk, #cancelLnk').on('click', function(){
|
||||
|
||||
$('#functions .function').toggle();
|
||||
$('#changeLnk').toggleClass('hidden');
|
||||
$('#cancelLnk').toggleClass('hidden');
|
||||
$('.contractSelection .form-group').toggleClass('hidden');
|
||||
|
||||
if($('.contractSelection select').val() == ''){
|
||||
$('.contractSelection select').val('custom');
|
||||
}
|
||||
|
||||
if($('#cancelLnk').is(':visible')){
|
||||
$('.contractSelection select').val($('.contractSelection span').text());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('.contractSelection select').on('change', function(){
|
||||
if($(this).val() == 'custom'){
|
||||
$('.contractSelection input').removeClass('hidden');
|
||||
} else {
|
||||
$('.contractSelection input').addClass('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
$('.contractSelection button').on('click', function(){
|
||||
let contractAddress;
|
||||
if($('.contractSelection select').val() == 'custom'){
|
||||
if(!/^0x[0-9a-f]{40}$/i.test($('.contractSelection input').val())){
|
||||
console.log('Not a valid Ethereum address.');
|
||||
return;
|
||||
}
|
||||
contractAddress = $('.contractSelection input').val();
|
||||
} else {
|
||||
contractAddress = $('.contractSelection select').val();
|
||||
}
|
||||
|
||||
this.contract.options.address = contractAddress;
|
||||
$('.contractSelection span').text(contractAddress);
|
||||
|
||||
$('#cancelLnk').trigger('click');
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
|
||||
_populateInstances(){
|
||||
$('.constructor p.note').html('');
|
||||
$('.constructor h5').remove();
|
||||
$('.constructor p.note').before('<h5>Available instances</h5>');
|
||||
|
||||
$('.contractSelection select option:not(:last-child)').remove();
|
||||
|
||||
if(this.contract.options.address != null)
|
||||
$('.contractSelection span').text(this.contract.options.address);
|
||||
|
||||
let instanceHtml = $('<ul></ul>');
|
||||
this.instances.forEach((elem, i) => {
|
||||
instanceHtml.append($(`<li>${elem}</li>`));
|
||||
$('.contractSelection select').prepend($(`<option>${elem}</option>`));
|
||||
});
|
||||
|
||||
$('.constructor p.note').append(instanceHtml);
|
||||
@ -108,20 +167,28 @@ class ContractUI {
|
||||
if(elem.payable)
|
||||
executionParams.value = $('input.value', parentDiv).val();
|
||||
|
||||
if(elem.type == 'fallback'){
|
||||
executionParams.data = $('input.data', parentDiv).val();
|
||||
executionParams.to = this.contract.options.address
|
||||
}
|
||||
|
||||
|
||||
let functionParams = this._getFunctionParamString(elem, parentDiv);
|
||||
|
||||
let methodParams = this._getMethodString(elem);
|
||||
methodParams = methodParams.replace('$account', $('select.accountList option:selected', parentDiv).text());
|
||||
methodParams = methodParams.replace('$gasLimit', executionParams.gasLimit);
|
||||
methodParams = methodParams.replace('$value', executionParams.value);
|
||||
methodParams = methodParams.replace('$to', '"' + executionParams.to + '"');
|
||||
methodParams = methodParams.replace('$data', '"' + executionParams.data + '"');
|
||||
|
||||
if(elem.type == "constructor")
|
||||
functionParams = `{arguments: [${functionParams}]}`;
|
||||
|
||||
console.log(`%cawait ${functionLabel}(${functionParams}).${this._getMethodType(elem)}(${methodParams})`, 'font-weight: bold');
|
||||
|
||||
console.log(`%cawait ${functionLabel}${functionParams}${elem.type != 'fallback' ? '.' + this._getMethodType(elem) : ''}${methodParams}`, 'font-weight: bold');
|
||||
|
||||
const funcArguments = this._getFuncArguments(parentDiv);
|
||||
|
||||
|
||||
try {
|
||||
if(elem.type == 'constructor'){
|
||||
let contractInstance = await this.contract.deploy({arguments: funcArguments}).send(executionParams);
|
||||
@ -133,7 +200,12 @@ class ContractUI {
|
||||
} else {
|
||||
resultContainer.text('');
|
||||
|
||||
const receipt = await this.contract
|
||||
let receipt;
|
||||
|
||||
if(elem.type == 'fallback')
|
||||
receipt = await this.web3.eth.sendTransaction(executionParams);
|
||||
else
|
||||
receipt = await this.contract
|
||||
.methods[elem.name + '(' + elem.inputs.map(input => input.type).join(',') + ')']
|
||||
.apply(null, funcArguments)
|
||||
[this._getMethodType(elem)](executionParams)
|
||||
@ -157,7 +229,7 @@ class ContractUI {
|
||||
}
|
||||
eventList.append(`<li>${ev}(${props.join(', ')})</li>`);
|
||||
}
|
||||
resultContainer.append($('<b>Transaction Hash:</b> ' + receipt.transactionHash + '<br /><b>Events:</b>'));
|
||||
resultContainer.append($('<b>Transaction Hash:</b> ' + receipt.transactionHash + '<br /><b>Status:</b> ' + receipt.status + '<br /><b>Events:</b>'));
|
||||
resultContainer.append(eventList);
|
||||
}
|
||||
|
||||
@ -199,21 +271,27 @@ class ContractUI {
|
||||
if(!isDuplicated)
|
||||
return `${this.name}.methods.${elem.name}`;
|
||||
else {
|
||||
return `${this.name}.methods['${elem.name + '(' + elem.inputs.map(input => input.type).join(',') + ')'}']`;
|
||||
return `${this.name}.methods['${elem.name + '(' + (elem.inputs != null ? elem.inputs.map(input => input.type).join(',') : '') + ')'}']`;
|
||||
}
|
||||
else if(elem.type == 'fallback'){
|
||||
return `web3.eth.sendTransaction`;
|
||||
}
|
||||
else
|
||||
return `${this.name}.deploy`;
|
||||
}
|
||||
|
||||
|
||||
_getFunctionParamFields(elem){
|
||||
return elem.inputs
|
||||
if(elem.type == 'fallback') return '';
|
||||
|
||||
return '(' + elem.inputs
|
||||
.map((input, i) => `<input 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}" />`)
|
||||
.join(', ');
|
||||
.join(', ') + ')';
|
||||
}
|
||||
|
||||
|
||||
_getFunctionParamString(elem, container){
|
||||
if(elem.type == 'fallback') return '';
|
||||
return elem.inputs
|
||||
.map((input, i) => (input.type.indexOf('int') == -1 ? '"' : '') + $('input[data-name="' + input.name + '"]', container).val() + (input.type.indexOf('int') == -1 ? '"' : ''))
|
||||
.join(', ');
|
||||
@ -235,6 +313,9 @@ class ContractUI {
|
||||
if(elem.payable){
|
||||
methodParams += ', value: <input type="text" class="value" value="0" size="6" />'
|
||||
}
|
||||
if(elem.type == 'fallback'){
|
||||
methodParams += ', data: <input type="text" class="data" value="" size="6" />'
|
||||
}
|
||||
}
|
||||
|
||||
return methodParams + "})";
|
||||
@ -250,6 +331,9 @@ class ContractUI {
|
||||
if(elem.payable){
|
||||
methodParams += ', value: $value'
|
||||
}
|
||||
if(elem.type == 'fallback'){
|
||||
methodParams += ', data: $data, to: $to'
|
||||
}
|
||||
}
|
||||
return methodParams + "})";
|
||||
}
|
||||
|
11
app/dapp.js
11
app/dapp.js
@ -3,20 +3,17 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import './dapp.css';
|
||||
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import IdentityFactory from 'Embark/contracts/IdentityFactory';
|
||||
import Identity from 'Embark/contracts/Identity';
|
||||
|
||||
import ContractUI from './contract-ui.js';
|
||||
|
||||
__embarkContext.execWhenReady(function(){
|
||||
|
||||
let contractUI = new ContractUI('IdentityFactory',
|
||||
IdentityFactory,
|
||||
let contractUI = new ContractUI( web3,
|
||||
'Identity',
|
||||
Identity,
|
||||
'https://raw.githubusercontent.com/status-im/contracts/contracts-ui-demo/contracts/identity/IdentityFactory.sol');
|
||||
|
||||
contractUI.buildFunctionSection($('#functions'), $('#constructor'));
|
||||
contractUI.buildSourceCodeSection($('#contract'));
|
||||
|
||||
// TODO
|
||||
// 1 Use specific contract address
|
||||
// 2 Fallback / Value
|
||||
});
|
||||
|
@ -33,7 +33,19 @@
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="functions">
|
||||
<h2>Functions</h2>
|
||||
<div class="contractSelection">
|
||||
<h5><b>Instance Selected:</b> <span><b style="color:red">none</b></span>
|
||||
<a href="#" id="changeLnk">Change</a>
|
||||
<a href="#" id="cancelLnk" class="hidden">Cancel</a></h5>
|
||||
<div class="form-group hidden">
|
||||
<select class="form-control" id="contracts" placeholder="Contract Address">
|
||||
<option value="custom">Specific contract address</option>
|
||||
</select>
|
||||
<input type="text" class="form-control hidden" id="specificAddress" placeholder="0x" />
|
||||
<button class="btn btn-default">Change</button>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="function">Functions</h2>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="contract">
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user