From d5651ae8fd9281e0ffa8ad96adaa0863c1b7d24a Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 8 Sep 2017 15:04:07 +0200 Subject: [PATCH 1/2] decoded ouput if VM --- src/app/execution/txFormat.js | 12 ++++++++---- src/app/execution/txListener.js | 14 ++++++++++++-- src/app/execution/txLogger.js | 10 ++++++++++ src/universal-dapp.js | 20 +++++++++++++------- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/app/execution/txFormat.js b/src/app/execution/txFormat.js index 72c8038c6e..3e700803b4 100644 --- a/src/app/execution/txFormat.js +++ b/src/app/execution/txFormat.js @@ -122,8 +122,7 @@ module.exports = { } }, - decodeResponse: function (response, fnabi, callback) { - // Only decode if there supposed to be fields + decodeResponseToTreeView: function (response, fnabi) { var treeView = new TreeView({ extractData: (item, parent, key) => { var ret = {} @@ -136,6 +135,11 @@ module.exports = { return ret } }) + return treeView.render(this.decodeResponse(response, fnabi)) + }, + + decodeResponse: function (response, fnabi) { + // Only decode if there supposed to be fields if (fnabi.outputs && fnabi.outputs.length > 0) { try { var i @@ -159,9 +163,9 @@ module.exports = { } } - return callback(null, treeView.render(json)) + return json } catch (e) { - return callback('Failed to decode output: ' + e) + return { error: 'Failed to decode output: ' + e } } } } diff --git a/src/app/execution/txListener.js b/src/app/execution/txListener.js index 2c067a42f0..4d6ee736a5 100644 --- a/src/app/execution/txListener.js +++ b/src/app/execution/txListener.js @@ -6,6 +6,7 @@ var EventManager = require('ethereum-remix').lib.EventManager var remix = require('ethereum-remix') var codeUtil = remix.util.code var executionContext = require('../../execution-context') +var txFormat = require('./txFormat') /** * poll web3 each 2s if web3 @@ -32,6 +33,7 @@ class TxListener { }) opt.event.udapp.register('transactionExecuted', (error, to, data, lookupOnly, txResult) => { if (error) return + if (lookupOnly) return // we go for that case if // in VM mode // in web3 mode && listen remix txs only @@ -39,6 +41,8 @@ class TxListener { if (this._loopId) return // we seems to already listen on the network executionContext.web3().eth.getTransaction(txResult.transactionHash, (error, tx) => { if (error) return console.log(error) + if (txResult && txResult.result && txResult.result.vm) tx.returnValue = txResult.result.vm.return + this._resolve([tx], () => { }) }) @@ -158,7 +162,9 @@ class TxListener { async.each(transactions, (tx, cb) => { this._resolveTx(tx, (error, resolvedData) => { if (error) cb(error) - if (resolvedData) this.event.trigger('txResolved', [tx, resolvedData]) + if (resolvedData) { + this.event.trigger('txResolved', [tx, resolvedData]) + } this.event.trigger('newTransaction', [tx]) cb() }) @@ -224,11 +230,15 @@ class TxListener { if (!isCtor) { for (var fn in compiledContracts[contractName].functionHashes) { if (compiledContracts[contractName].functionHashes[fn] === inputData.substring(0, 8)) { + var fnabi = getFunction(abi, fn) this._resolvedTransactions[tx.hash] = { contractName: contractName, to: tx.to, fn: fn, - params: this._decodeInputParams(inputData.substring(8), getFunction(abi, fn)) + params: this._decodeInputParams(inputData.substring(8), fnabi) + } + if (tx.returnValue) { + this._resolvedTransactions[tx.hash].decodedReturnValue = txFormat.decodeResponse(tx.returnValue, fnabi) } return this._resolvedTransactions[tx.hash] } diff --git a/src/app/execution/txLogger.js b/src/app/execution/txLogger.js index e847b10d7d..013f99522d 100644 --- a/src/app/execution/txLogger.js +++ b/src/app/execution/txLogger.js @@ -142,6 +142,7 @@ function renderKnownTransaction (self, data) { hash: data.tx.hash, input: data.tx.input, 'decoded input': data.resolvedData && data.resolvedData.params ? JSON.stringify(value(data.resolvedData.params), null, '\t') : ' - ', + 'decoded output': data.resolvedData && data.resolvedData.decodedReturnValue ? JSON.stringify(value(data.resolvedData.decodedReturnValue), null, '\t') : ' - ', logs: JSON.stringify(data.logs, null, '\t') || '0', val: data.tx.value }) @@ -314,6 +315,15 @@ function createTable (opts) { table.appendChild(inputDecoded) } + if (opts['decoded output']) { + var outputDecoded = yo` + + decoded output + ${opts['decoded output']} + ` + table.appendChild(outputDecoded) + } + var logs = yo` logs diff --git a/src/universal-dapp.js b/src/universal-dapp.js index 06feb38cb1..72ea2d877e 100644 --- a/src/universal-dapp.js +++ b/src/universal-dapp.js @@ -78,6 +78,8 @@ var css = csjs` } .buttonsContainer { margin-top: 2%; + } + .contractActions { display: flex; } .instanceButton {} @@ -319,9 +321,8 @@ UniversalDApp.prototype.getCallButton = function (args) { } } if (lookupOnly) { - txFormat.decodeResponse(executionContext.isVM() ? txResult.result.vm.return : ethJSUtil.toBuffer(txResult.result), args.funABI, (error, decoded) => { - $outputOverride.html(error ? 'error' + error : decoded) - }) + var decoded = txFormat.decodeResponseToTreeView(executionContext.isVM() ? txResult.result.vm.return : ethJSUtil.toBuffer(txResult.result), args.funABI) + $outputOverride.html(decoded) } } else { modalDialogCustom.alert(error) @@ -332,12 +333,17 @@ UniversalDApp.prototype.getCallButton = function (args) { } }) } - // TODO the auto call to constant function has been removed. needs to readd it later. var $contractProperty = $(`
`) - $contractProperty - .append(button) - .append((lookupOnly && !inputs.length) ? $outputOverride : inputField) + var $contractActions = $(`
`) + $contractProperty.append($contractActions) + $contractActions.append(button) + if (inputs.length) { + $contractActions.append(inputField) + } + if (lookupOnly) { + $contractProperty.append($outputOverride) + } if (lookupOnly) { $contractProperty.addClass('constant') From 3a41c86d804d0775d11621f0be7bfd2943713bcc Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 11 Sep 2017 11:29:14 +0200 Subject: [PATCH 2/2] add tests --- src/app/execution/txLogger.js | 2 +- test-browser/tests/compiling.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/execution/txLogger.js b/src/app/execution/txLogger.js index 013f99522d..0556e54f9e 100644 --- a/src/app/execution/txLogger.js +++ b/src/app/execution/txLogger.js @@ -319,7 +319,7 @@ function createTable (opts) { var outputDecoded = yo` decoded output - ${opts['decoded output']} + ${opts['decoded output']} ` table.appendChild(outputDecoded) } diff --git a/test-browser/tests/compiling.js b/test-browser/tests/compiling.js index 696f12cd45..e82f95f4d4 100644 --- a/test-browser/tests/compiling.js +++ b/test-browser/tests/compiling.js @@ -34,6 +34,8 @@ function runTests (browser) { .click('.instance button[title="f - transact (not payable)"]') .waitForElementPresent('#editor-container div[class^="terminal"] span[id="tx0xa178c603400a184ce5fedbcfab392d9b77822f6ffa7facdec693aded214523bc"]') .assert.containsText('#editor-container div[class^="terminal"] span[id="tx0xa178c603400a184ce5fedbcfab392d9b77822f6ffa7facdec693aded214523bc"]', '[vm] from:0xca3...a733c, to:browser/Untitled.sol:TestContract.f() 0x692...77b3a, value:0 wei, data:0x261...21ff0, 0 logs, hash:0xa17...523bc') + .click('#editor-container div[class^="terminal"] span[id="tx0xa178c603400a184ce5fedbcfab392d9b77822f6ffa7facdec693aded214523bc"] button[class^="details"]') + .assert.containsText('#editor-container div[class^="terminal"] span[id="tx0xa178c603400a184ce5fedbcfab392d9b77822f6ffa7facdec693aded214523bc"] table[class^="txTable"] #decodedoutput', `"uint256": "8"`) .end() /* @TODO: need to check now the return value of the function