diff --git a/assets/css/browser-solidity.css b/assets/css/browser-solidity.css index de9ce5a89d..2fb0aa8510 100644 --- a/assets/css/browser-solidity.css +++ b/assets/css/browser-solidity.css @@ -208,6 +208,7 @@ body { #header #optionViews.settingsView #settingsView { display: block; } #header #optionViews.publishView #publishView { display: block; } #header #optionViews.envView #envView { display: block; } +#header #optionViews.debugView #debugView { display: block; } #header #optionViews.txView input, #header #optionViews.txView select { diff --git a/assets/css/universal-dapp.css b/assets/css/universal-dapp.css index 14e4a7b051..4d4f7c289e 100644 --- a/assets/css/universal-dapp.css +++ b/assets/css/universal-dapp.css @@ -87,7 +87,7 @@ .udapp .output .result { position: relative; - margin-bottom: 0.5em; + margin-bottom: 3.5em; white-space: pre; } @@ -205,6 +205,11 @@ border-color: #FF8B8B; } +.udapp .contractProperty .debug { + background-color: #9DC1F5; + border-color: #9DC1F5; +} + .udapp .contractProperty.constant .call { background-color: #9DC1F5; border-color: #9DC1F5; diff --git a/index.html b/index.html index 8fb97ee614..cd2b5b43d9 100644 --- a/index.html +++ b/index.html @@ -64,6 +64,7 @@
  • +
  • Solidity realtime compiler and runtime @@ -121,7 +122,9 @@ - +
    +
    +
    diff --git a/package.json b/package.json index a65469a329..8591daab70 100644 --- a/package.json +++ b/package.json @@ -55,5 +55,8 @@ "nightwatch.js", "ci/sauceDisconnect.js" ] + }, + "dependencies": { + "ethereum-remix": "0.0.1" } } diff --git a/src/app.js b/src/app.js index 54ac440bc8..8a64458658 100644 --- a/src/app.js +++ b/src/app.js @@ -13,6 +13,7 @@ var Editor = require('./app/editor'); var Renderer = require('./app/renderer'); var Compiler = require('./app/compiler'); var ExecutionContext = require('./app/execution-context'); +var Debugger = require('./app/debugger'); // The event listener needs to be registered as early as possible, because the // parent will send the message upon the "load" event. @@ -89,21 +90,23 @@ var run = function () { var editor = new Editor(loadingFromGist, storage); // ----------------- tabbed menu ------------------- - $('#options li').click(function (ev) { var $el = $(this); - var match = /[a-z]+View/.exec($el.get(0).className); + document.querySelector('ul#options').selectTab($el); + }); + document.querySelector('ul#options').selectTab = function (el) { + var match = /[a-z]+View/.exec(el.get(0).className); if (!match) return; var cls = match[0]; - if (!$el.hasClass('active')) { - $el.parent().find('li').removeClass('active'); + if (!el.hasClass('active')) { + el.parent().find('li').removeClass('active'); $('#optionViews').attr('class', '').addClass(cls); - $el.addClass('active'); + el.addClass('active'); } else { - $el.removeClass('active'); + el.removeClass('active'); $('#optionViews').removeClass(cls); } - }); + }; // ------------------ gist publish -------------- @@ -423,7 +426,8 @@ var run = function () { } var executionContext = new ExecutionContext(); - var renderer = new Renderer(editor, executionContext, updateFiles); + var transactionDebugger = new Debugger(executionContext, '#debugger'); + var renderer = new Renderer(editor, executionContext, updateFiles, transactionDebugger); var compiler = new Compiler(editor, renderer, queryParams, handleGithubCall, $('#output'), getHidingRHP, updateFiles); executionContext.setCompiler(compiler); diff --git a/src/app/debugger.js b/src/app/debugger.js new file mode 100644 index 0000000000..a5b7ad0b5b --- /dev/null +++ b/src/app/debugger.js @@ -0,0 +1,22 @@ +var Remix = require('ethereum-remix'); +var $ = require('jquery'); + +function Debugger (executionContext, _id) { + this.el = document.querySelector(_id); + this.debugger = new Remix(executionContext.web3()); + this.el.appendChild(this.debugger.render()); + this.web3 = executionContext.web3(); + this.debugView = $('ul#options li.debugView'); + + Debugger.prototype.debug = function (receipt) { + document.querySelector('ul#options').selectTab(this.debugView); + var self = this; + this.web3.eth.getTransaction(receipt.transactionHash, function (error, tx) { + if (!error) { + self.debugger.debug(tx); + } + }); + }; +} + +module.exports = Debugger; diff --git a/src/app/renderer.js b/src/app/renderer.js index cc44945434..c82e7551db 100644 --- a/src/app/renderer.js +++ b/src/app/renderer.js @@ -4,7 +4,7 @@ var UniversalDApp = require('../universal-dapp.js'); var utils = require('./utils'); -function Renderer (editor, executionContext, updateFiles) { +function Renderer (editor, executionContext, updateFiles, transactionDebugger) { var detailsOpen = {}; function renderError (message) { @@ -78,7 +78,7 @@ function Renderer (editor, executionContext, updateFiles) { .append(textRow('uDApp', combined(contractName, contract['interface'], contract.bytecode), 'deploy')) .append(getDetails(contract, source, contractName)); } - }); + }, transactionDebugger); var $contractOutput = dapp.render(); diff --git a/src/universal-dapp.js b/src/universal-dapp.js index 54a27e341a..60cd808541 100644 --- a/src/universal-dapp.js +++ b/src/universal-dapp.js @@ -8,7 +8,7 @@ var ethJSABI = require('ethereumjs-abi'); var EthJSBlock = require('ethereumjs-block'); var BN = ethJSUtil.BN; -function UniversalDApp (contracts, options) { +function UniversalDApp (contracts, options, transactionDebugger) { var self = this; self.options = options || {}; @@ -17,7 +17,7 @@ function UniversalDApp (contracts, options) { self.renderOutputModifier = options.renderOutputModifier || function (name, content) { return content; }; self.web3 = options.web3; - + self.transactionDebugger = transactionDebugger; if (options.mode === 'vm') { // FIXME: use `options.vm` or `self.vm` consistently options.vm = true; @@ -352,6 +352,16 @@ UniversalDApp.prototype.getCallButton = function (args) { return $('
    ').html('' + returnName + ': ' + JSON.stringify(result, null, 2)); }; + var getDebugTransaction = function (result) { + var $debugTx = $('
    '); + var $button = $(''); + $button.click(function () { + self.transactionDebugger.debug(result); + }); + $debugTx.append($button); + return $debugTx; + }; + var getGasUsedOutput = function (result, vmResult) { var $gasUsed = $('
    '); var caveat = lookupOnly ? '(caveat)' : ''; @@ -514,6 +524,7 @@ UniversalDApp.prototype.getCallButton = function (args) { } else { clearOutput($result); $result.append(getReturnOutput(result)).append(getGasUsedOutput(result)); + $result.append(getDebugTransaction(result)); } }); };