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 @@
+
@@ -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));
}
});
};