diff --git a/package.json b/package.json index 1981fed635..49176ed002 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,11 @@ ], "main": "index.js", "dependencies": { - "react": "^15.0.1", - "react-dom": "^15.0.1", - "web3": "^0.15.3" + "browserify": "^13.0.1", + "web3": "^0.15.3", + "yo-yo": "^1.2.1" }, "devDependencies": { - "babel-preset-react": "^6.5.0", - "babelify": "^7.2.0", "nightwatch": "^0.9.4", "standard": "^7.0.1", "standard-reporter": "^1.0.5", @@ -28,7 +26,7 @@ }, "scripts": { "start_node": "eth --rpccorsdomain \"*\" -j -v 0", - "build": "mkdir -p build; browserify -t [ babelify --presets [ react ] ] src/index.js -o build/app.js", + "build": "mkdir -p build; browserify src/index.js -o build/app.js", "test": "standard && tape ./test/tests.js", "serve": "http-server ." }, diff --git a/src/ASMCode.js b/src/ASMCode.js new file mode 100644 index 0000000000..d9be836ea6 --- /dev/null +++ b/src/ASMCode.js @@ -0,0 +1,60 @@ +'use strict' +var style = require('./basicStyles') +var yo = require('yo-yo') +var CodeManager = require('./code/codeManager') +var ui = require('./helpers/ui') + +function ASMCode (_parent, _traceManager, _web3) { + this.parent = _parent + this.codeManager = new CodeManager(_web3, _traceManager) + this.code + this.address + this.codeView + + this.init() +} + +ASMCode.prototype.render = function () { + this.view = ( + yo`` + ) + return this.view +} + +ASMCode.prototype.init = function () { + var self = this + this.codeManager.register('indexChanged', this, this.indexChanged) + this.codeManager.register('codeChanged', this, this.codeChanged) + this.codeManager.register('loadingCode', this, function (address) {}) + this.parent.register('indexChanged', this, function (index) { + self.codeManager.resolveStep(index, self.parent.tx) + }) +} + +ASMCode.prototype.indexChanged = function (index) { + document.getElementById('asmitems').value = index +} + +ASMCode.prototype.codeChanged = function (code, address, index) { + this.code = code + this.address = address + this.instructionIndex = index + this.renderAssemblyItems() + yo.update(this.view, this.render()) + document.getElementById('asmitems').value = index +} + +ASMCode.prototype.renderAssemblyItems = function () { + if (this.code) { + this.codeView = this.code.map(function (item, i) { + return yo`` + }) + return this.codeView + } +} + +module.exports = ASMCode diff --git a/src/BasicPanel.js b/src/BasicPanel.js new file mode 100644 index 0000000000..4e5bddf72e --- /dev/null +++ b/src/BasicPanel.js @@ -0,0 +1,32 @@ +'use strict' +var style = require('./basicStyles') +var yo = require('yo-yo') +var ui = require('./helpers/ui') + +function BasicPanel (_name) { + this.data + this.name = _name + + this.view +} + +BasicPanel.prototype.update = function () { + yo.update(this.view, this.render()) +} + +BasicPanel.prototype.render = function () { + var view = yo`
+
+ ${this.name} +
+
+
${this.data}
+
+
` + if (!this.view) { + this.view = view + } + return view +} + +module.exports = BasicPanel diff --git a/src/ButtonNavigator.js b/src/ButtonNavigator.js new file mode 100644 index 0000000000..684667def6 --- /dev/null +++ b/src/ButtonNavigator.js @@ -0,0 +1,73 @@ +'use strict' +var util = require('./helpers/global') +var EventManager = require('./lib/eventManager') +var yo = require('yo-yo') + +function ButtonNavigator (_traceManager) { + util.extend(this, new EventManager()) + this.intoBackDisabled = true + this.overBackDisabled = true + this.intoForwardDisabled = true + this.overForwardDisabled = true + this.nextCallDisabled = true + + this.traceManager = _traceManager + + this.view +} + +module.exports = ButtonNavigator + +ButtonNavigator.prototype.render = function () { + var self = this + var view = yo`
+ + + + + +
` + if (!this.view) { + this.view = view + } + return view +} + +ButtonNavigator.prototype.stepChanged = function (step) { + this.intoBackDisabled = step <= 0 + this.overBackDisabled = step <= 0 + if (!this.traceManager) { + this.intoForwardDisabled = true + this.overForwardDisabled = true + this.NextCallDisabled = true + } else { + var self = this + this.traceManager.getLength(function (error, length) { + if (error) { + self.intoBackDisabled = true + self.overBackDisabled = true + self.intoForwardDisabled = true + self.overForwardDisabled = true + self.NextcallDisabled = true + console.log(error) + } else { + self.intoForwardDisabled = step >= length - 1 + self.overForwardDisabled = step >= length - 1 + self.NextcallDisabled = step >= length - 1 + } + }) + } + yo.update(this.view, this.render()) +} + +module.exports = ButtonNavigator diff --git a/src/CalldataPanel.js b/src/CalldataPanel.js new file mode 100644 index 0000000000..baf3c96adb --- /dev/null +++ b/src/CalldataPanel.js @@ -0,0 +1,43 @@ +'use strict' +var BasicPanel = require('./BasicPanel') +var yo = require('yo-yo') + +function CalldataPanel (_parent, _traceManager) { + this.parent = _parent + this.traceManager = _traceManager + this.basicPanel = new BasicPanel('Call Data') + this.init() +} + +CalldataPanel.prototype.render = function () { + return ( + yo`${this.basicPanel.render()}` + ) +} + +CalldataPanel.prototype.init = function () { + var self = this + this.parent.register('indexChanged', this, function (index) { + if (index < 0) return + if (self.parent.currentStepIndex !== index) return + + self.traceManager.getCallDataAt(index, function (error, calldata) { + if (error) { + console.log(error) + } else if (self.parent.currentStepIndex === index) { + self.basicPanel.data = self.format(calldata) + self.basicPanel.update() + } + }) + }) +} + +CalldataPanel.prototype.format = function (calldata) { + var ret = '' + for (var key in calldata) { + ret += calldata[key] + '\n' + } + return ret +} + +module.exports = CalldataPanel diff --git a/src/CallstackPanel.js b/src/CallstackPanel.js new file mode 100644 index 0000000000..c2c83e4e89 --- /dev/null +++ b/src/CallstackPanel.js @@ -0,0 +1,43 @@ +'use strict' +var BasicPanel = require('./BasicPanel') +var yo = require('yo-yo') + +function CallstackPanel (_parent, _traceManager) { + this.parent = _parent + this.traceManager = _traceManager + this.basicPanel = new BasicPanel('Call Stack') + this.init() +} + +CallstackPanel.prototype.render = function () { + return ( + yo`${this.basicPanel.render()}` + ) +} + +CallstackPanel.prototype.init = function () { + var self = this + this.parent.register('indexChanged', this, function (index) { + if (index < 0) return + if (self.parent.currentStepIndex !== index) return + + self.traceManager.getCallStackAt(index, function (error, callstack) { + if (error) { + console.log(error) + } else if (self.parent.currentStepIndex === index) { + self.basicPanel.data = self.format(callstack) + self.basicPanel.update() + } + }) + }) +} + +CallstackPanel.prototype.format = function (callstack) { + var ret = '' + for (var key in callstack) { + ret += callstack[key] + '\n' + } + return ret +} + +module.exports = CallstackPanel diff --git a/src/Ethdebugger.js b/src/Ethdebugger.js new file mode 100644 index 0000000000..db30ac3479 --- /dev/null +++ b/src/Ethdebugger.js @@ -0,0 +1,75 @@ +'use strict' +var TxBrowser = require('./TxBrowser') +var StepManager = require('./StepManager') +var TraceManager = require('./trace/traceManager') +var VmDebugger = require('./VmDebugger') +var style = require('./basicStyles') +var util = require('./helpers/global') +var EventManager = require('./lib/eventManager') +var yo = require('yo-yo') +var init = require('./helpers/init') +var ui = require('./helpers/ui') + +function Ethdebugger (_context) { + util.extend(this, new EventManager()) + this.context = _context + this.currentStepIndex = -1 + this.tx + + this.web3 = init.loadWeb3() + this.traceManager = new TraceManager(this.web3) + + var self = this + this.txBrowser = new TxBrowser(this.web3) + this.txBrowser.register('newTxRequested', this, function (blockNumber, txIndex, tx) { + self.startDebugging(blockNumber, txIndex, tx) + }) + this.stepManager = new StepManager(this, this.traceManager) + this.stepManager.register('stepChanged', this, function (stepIndex) { + self.stepChanged(stepIndex) + }) + this.vmDebugger = new VmDebugger(this, this.traceManager, this.web3) +} + +Ethdebugger.prototype.render = function () { + var self = this + return ( + yo`
+

Eth Debugger

+
X
+ ${this.txBrowser.render()} + ${this.stepManager.render()} + ${this.vmDebugger.render()} +
` + ) +} + +Ethdebugger.prototype.unLoad = function () { + this.traceManager.init() + this.stepManager.init() + this.trigger('traceUnloaded') +} + +Ethdebugger.prototype.stepChanged = function (stepIndex) { + this.currentStepIndex = stepIndex + this.trigger('indexChanged', [stepIndex]) +} + +Ethdebugger.prototype.startDebugging = function (blockNumber, txIndex, tx) { + if (this.traceManager.isLoading) { + return + } + console.log('loading trace...') + this.tx = tx + var self = this + this.traceManager.resolveTrace(tx, function (success) { + console.log('trace loaded ' + success) + if (success) { + self.trigger('newTraceLoaded') + } else { + console.log('trace not loaded') + } + }) +} + +module.exports = Ethdebugger diff --git a/src/MemoryPanel.js b/src/MemoryPanel.js new file mode 100644 index 0000000000..aa2439b4b1 --- /dev/null +++ b/src/MemoryPanel.js @@ -0,0 +1,36 @@ +'use strict' +var BasicPanel = require('./BasicPanel') +var util = require('./helpers/ui') +var yo = require('yo-yo') + +function MemoryPanel (_parent, _traceManager) { + this.parent = _parent + this.traceManager = _traceManager + this.basicPanel = new BasicPanel('Memory') + this.init() +} + +MemoryPanel.prototype.render = function () { + return ( + yo`${this.basicPanel.render()}` + ) +} + +MemoryPanel.prototype.init = function () { + var self = this + this.parent.register('indexChanged', this, function (index) { + if (index < 0) return + if (self.parent.currentStepIndex !== index) return + + self.traceManager.getMemoryAt(index, function (error, memory) { + if (error) { + console.log(error) + } else if (self.parent.currentStepIndex === index) { + self.basicPanel.data = util.formatMemory(memory, 16) + self.basicPanel.update() + } + }) + }) +} + +module.exports = MemoryPanel diff --git a/src/Slider.js b/src/Slider.js new file mode 100644 index 0000000000..669375a03b --- /dev/null +++ b/src/Slider.js @@ -0,0 +1,64 @@ +'use strict' +var style = require('./sliderStyles') +var util = require('./helpers/global') +var EventManager = require('./lib/eventManager') +var yo = require('yo-yo') +var ui = require('./helpers/ui') + +function Slider (_traceManager) { + util.extend(this, new EventManager()) + this.traceManager = _traceManager + this.max + this.disabled = true + this.view +} + +Slider.prototype.render = function () { + var self = this + var view = yo`
+ +
` + if (!this.view) { + this.view = view + } + return view +} + +Slider.prototype.init = function () { + var self = this + this.traceManager.getLength(function (error, length) { + if (error) { + console.log(error) + } else { + self.max = length + self.disabled = length === 0 + yo.update(self.view, self.render()) + self.setValue(0) + } + }) +} + +Slider.prototype.onMouseUp = function (event) { + var value = document.getElementById('slider').value + this.trigger('moved', [parseInt(value)]) +} + +Slider.prototype.setValue = function (value) { + var slider = document.getElementById('slider') + var diff = value - slider.value + if (diff > 0) { + slider.stepUp(diff) + } else { + slider.stepDown(Math.abs(diff)) + } +} + +module.exports = Slider diff --git a/src/StackPanel.js b/src/StackPanel.js new file mode 100644 index 0000000000..80e97a0185 --- /dev/null +++ b/src/StackPanel.js @@ -0,0 +1,43 @@ +'use strict' +var BasicPanel = require('./BasicPanel') +var yo = require('yo-yo') + +function StackPanel (_parent, _traceManager) { + this.parent = _parent + this.traceManager = _traceManager + this.basicPanel = new BasicPanel('Stack') + this.init() +} + +StackPanel.prototype.render = function () { + return ( + yo`${this.basicPanel.render()}` + ) +} + +StackPanel.prototype.init = function () { + var self = this + this.parent.register('indexChanged', this, function (index) { + if (index < 0) return + if (self.parent.currentStepIndex !== index) return + + self.traceManager.getStackAt(index, function (error, stack) { + if (error) { + console.log(error) + } else if (self.parent.currentStepIndex === index) { + self.basicPanel.data = self.format(stack) + self.basicPanel.update() + } + }) + }) +} + +StackPanel.prototype.format = function (stack) { + var ret = '' + for (var key in stack) { + ret += stack[key] + '\n' + } + return ret +} + +module.exports = StackPanel diff --git a/src/StepManager.js b/src/StepManager.js new file mode 100644 index 0000000000..9564662ead --- /dev/null +++ b/src/StepManager.js @@ -0,0 +1,129 @@ +'use strict' +var ButtonNavigator = require('./ButtonNavigator') +var Slider = require('./Slider') +var style = require('./basicStyles') +var util = require('./helpers/global') +var EventManager = require('./lib/eventManager') +var yo = require('yo-yo') +var ui = require('./helpers/ui') + +function StepManager (_parent, _traceManager) { + util.extend(this, new EventManager()) + this.parent = _parent + this.traceManager = _traceManager + + var self = this + this.parent.register('newTraceLoaded', this, function () { + self.traceManager.getLength(function (length) { + self.slider.max = length + self.slider.init() + self.init() + }) + }) + + this.slider = new Slider(this.traceManager) + this.slider.register('moved', this, function (step) { + self.sliderMoved(step) + }) + + this.buttonNavigator = new ButtonNavigator(this.traceManager) + this.buttonNavigator.register('stepIntoBack', this, function () { + self.stepIntoBack() + }) + this.buttonNavigator.register('stepIntoForward', this, function () { + self.stepIntoForward() + }) + this.buttonNavigator.register('stepOverBack', this, function () { + self.stepOverBack() + }) + this.buttonNavigator.register('stepOverForward', this, function () { + self.stepOverForward() + }) + this.buttonNavigator.register('jumpNextCall', this, function () { + self.jumpNextCall() + }) +} + +StepManager.prototype.render = function () { + return ( + yo`
+ ${this.slider.render()} + ${this.buttonNavigator.render()} +
` + ) +} + +StepManager.prototype.init = function () { + this.slider.setValue(0) + this.changeState(0) +} + +StepManager.prototype.newTraceAvailable = function () { + this.init() +} + +StepManager.prototype.sliderMoved = function (step) { + if (!this.traceManager.inRange(step)) { + return + } + this.changeState(step) +} + +StepManager.prototype.stepIntoForward = function () { + if (!this.traceManager.isLoaded()) { + return + } + var step = this.currentStepIndex + 1 + if (!this.traceManager.inRange(step)) { + return + } + this.slider.setValue(step) + this.changeState(step) +} + +StepManager.prototype.stepIntoBack = function () { + if (!this.traceManager.isLoaded()) { + return + } + var step = this.currentStepIndex - 1 + if (!this.traceManager.inRange(step)) { + return + } + this.slider.setValue(step) + this.changeState(step) +} + +StepManager.prototype.stepOverForward = function () { + if (!this.traceManager.isLoaded()) { + return + } + var step = this.traceManager.findStepOverForward(this.currentStepIndex) + this.slider.setValue(step) + this.changeState(step) +} + +StepManager.prototype.stepOverBack = function () { + if (!this.traceManager.isLoaded()) { + return + } + var step = this.traceManager.findStepOverBack(this.currentStepIndex) + this.slider.setValue(step) + this.changeState(step) +} + +StepManager.prototype.jumpNextCall = function () { + if (!this.traceManager.isLoaded()) { + return + } + var step = this.traceManager.findNextCall(this.currentStepIndex) + this.slider.setValue(step) + this.changeState(step) +} + +StepManager.prototype.changeState = function (step) { + this.currentStepIndex = step + this.buttonNavigator.stepChanged(step) + this.trigger('stepChanged', [step]) +} + +module.exports = StepManager diff --git a/src/Sticker.js b/src/Sticker.js new file mode 100644 index 0000000000..cf5f0f5406 --- /dev/null +++ b/src/Sticker.js @@ -0,0 +1,116 @@ +'use strict' +var yo = require('yo-yo') + +function Sticker (_parent, _traceManager) { + this.parent = _parent + this.traceManager = _traceManager + + this.vmTraceStep + this.step + this.addmemory + this.gas + this.remainingGas + + this.view + this.init() +} + +Sticker.prototype.render = function () { + var view = yo`
+ + + + + + + + + + + + + + + + + + + + + + + +
+ vmtracestep + + ${this.vmTraceStep} +
+ step + + ${this.step} +
+ add memory + + ${this.addmemory} +
+ gas + + ${this.gas} +
+ remaining gas + + ${this.remainingGas} +
+
` + if (!this.view) { + this.view = view + } + return view +} + +Sticker.prototype.init = function () { + var self = this + this.parent.register('indexChanged', this, function (index) { + if (index < 0) return + + self.vmTraceStep = index + + self.traceManager.getCurrentStep(index, function (error, step) { + if (error) { + console.log(error) + } else { + self.step = step + yo.update(self.view, self.render()) + } + }) + + self.traceManager.getMemExpand(index, function (error, addmem) { + if (error) { + console.log(error) + } else { + self.addmemory = addmem + yo.update(self.view, self.render()) + } + }) + + self.traceManager.getStepCost(index, function (error, gas) { + if (error) { + console.log(error) + } else { + self.gas = gas + yo.update(self.view, self.render()) + } + }) + + self.traceManager.getRemainingGas(index, function (error, remaingas) { + if (error) { + console.log(error) + } else { + self.remainingGas = remaingas + yo.update(self.view, self.render()) + } + }) + }) +} + +module.exports = Sticker diff --git a/src/StoragePanel.js b/src/StoragePanel.js new file mode 100644 index 0000000000..016875e25d --- /dev/null +++ b/src/StoragePanel.js @@ -0,0 +1,43 @@ +'use strict' +var BasicPanel = require('./BasicPanel') +var yo = require('yo-yo') + +function StoragePanel (_parent, _traceManager) { + this.parent = _parent + this.traceManager = _traceManager + this.basicPanel = new BasicPanel('Storage') + this.init() +} + +StoragePanel.prototype.render = function () { + return ( + yo`${this.basicPanel.render()}` + ) +} + +StoragePanel.prototype.init = function () { + var self = this + this.parent.register('indexChanged', this, function (index) { + if (index < 0) return + if (self.parent.currentStepIndex !== index) return + + self.traceManager.getStorageAt(index, self.parent.tx, function (error, storage) { + if (error) { + console.log(error) + } else if (self.parent.currentStepIndex === index) { + self.basicPanel.data = self.formatStorage(storage) + self.basicPanel.update() + } + }) + }) +} + +StoragePanel.prototype.formatStorage = function (storage) { + var ret = '' + for (var key in storage) { + ret += key + ' ' + storage[key] + '\n' + } + return ret +} + +module.exports = StoragePanel diff --git a/src/TxBrowser.js b/src/TxBrowser.js new file mode 100644 index 0000000000..2cb0838ef3 --- /dev/null +++ b/src/TxBrowser.js @@ -0,0 +1,118 @@ +var style = require('./basicStyles') +var util = require('./helpers/global') +var EventManager = require('./lib/eventManager') +var traceHelper = require('./helpers/traceHelper') +var yo = require('yo-yo') +var ui = require('./helpers/ui') + +function TxBrowser (_web3) { + util.extend(this, new EventManager()) + this.web3 = _web3 + + this.blockNumber + this.txNumber = '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51' + this.hash + this.from + this.to + this.view +} + +/* +getInitialState: function () { + return {blockNumber: '1000110', txNumber: '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51', from: '', to: '', hash: ''} +}, +*/ + +// creation 0xa9619e1d0a35b2c1d686f5b661b3abd87f998d2844e8e9cc905edb57fc9ce349 +// invokation 0x71a6d583d16d142c5c3e8903060e8a4ee5a5016348a9448df6c3e63b68076ec4 +// test: +// creation: 0x72908de76f99fca476f9e3a3b5d352f350a98cd77d09cebfc59ffe32a6ecaa0b +// invokation: 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51 + +TxBrowser.prototype.submit = function () { + if (!this.txNumber) { + return + } + var tx + try { + if (this.txNumber.indexOf('0x') !== -1) { + tx = this.web3.eth.getTransaction(this.txNumber) + } else { + tx = this.web3.eth.getTransactionFromBlock(this.blockNumber, this.txNumber) + } + } catch (e) { + console.log(e) + } + console.log(JSON.stringify(tx)) + if (tx) { + if (!tx.to) { + tx.to = traceHelper.contractCreationToken('0') + } + this.from = tx.from + this.to = tx.to + this.hash = tx.hash + yo.update(this.view, this.render()) + this.trigger('newTxRequested', [this.blockNumber, this.txNumber, tx]) + } else { + console.log('cannot find ' + this.blockNumber + ' ' + this.txNumber) + } +} + +TxBrowser.prototype.updateTxhash = function (ev) { + this.hash = ev.target.value +} + +TxBrowser.prototype.updateBlockN = function (ev) { + this.blockNumber = ev.target.value +} + +TxBrowser.prototype.updateTxN = function (ev) { + this.txNumber = ev.target.value +} + +TxBrowser.prototype.render = function () { + var self = this + var view = yo`
+ + + +
+ + + + + + + + + + + + + + + +
+ Hash: + + ${this.hash} +
+ From: + + ${this.from} +
+ To: + + ${this.to} +
+
+
` + if (!this.view) { + this.view = view + } + return view +} + +module.exports = TxBrowser diff --git a/src/VmDebugger.js b/src/VmDebugger.js new file mode 100644 index 0000000000..4c7beab263 --- /dev/null +++ b/src/VmDebugger.js @@ -0,0 +1,73 @@ +'use strict' +var Sticker = require('./Sticker') +var style = require('./basicStyles') +var ASMCode = require('./ASMCode') +var CalldataPanel = require('./CalldataPanel') +var MemoryPanel = require('./MemoryPanel') +var CallstackPanel = require('./CallstackPanel') +var StackPanel = require('./StackPanel') +var StoragePanel = require('./StoragePanel') +var yo = require('yo-yo') +var ui = require('./helpers/ui') + +function VmDebugger (_parent, _traceManager, _web3) { + this.sticker = new Sticker(_parent, _traceManager, _web3) + this.asmCode = new ASMCode(_parent, _traceManager, _web3) + this.stackPanel = new StackPanel(_parent, _traceManager) + this.storagePanel = new StoragePanel(_parent, _traceManager) + this.memoryPanel = new MemoryPanel(_parent, _traceManager) + this.calldataPanel = new CalldataPanel(_parent, _traceManager) + this.CallstackPanel = new CallstackPanel(_parent, _traceManager) + this.view + var self = this + _parent.register('newTraceLoaded', this, function () { + self.view.style.display = 'block' + }) + _parent.register('traceUnloaded', this, function () { + self.view.style.display = 'none' + }) +} + +VmDebugger.prototype.render = function () { + var view = yo`
+
+ + + + + + + + + + + + + + + +
+ ${this.asmCode.render()} +
+ ${this.sticker.render()} +
+
+ ${this.stackPanel.render()} +
+ ${this.storagePanel.render()} + + ${this.memoryPanel.render()} +
+ ${this.calldataPanel.render()} + + ${this.CallstackPanel.render()} +
+
+
` + if (!this.view) { + this.view = view + } + return view +} + +module.exports = VmDebugger diff --git a/src/asmCode.js b/src/asmCode.js deleted file mode 100644 index 28186bd2e9..0000000000 --- a/src/asmCode.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict' -var React = require('react') -var style = require('./basicStyles') - -module.exports = React.createClass({ - contextTypes: { - codeManager: React.PropTypes.object, - root: React.PropTypes.object, - tx: React.PropTypes.object - }, - - getInitialState: function () { - return { - code: '', - address: '' - } - }, - - render: function () { - return ( - - ) - }, - - componentDidMount: function () { - var self = this - this.context.codeManager.register('indexChanged', this, this.indexChanged) - this.context.codeManager.register('codeChanged', this, this.codeChanged) - this.context.codeManager.register('loadingCode', this, function (address) { - }) - this.context.root.register('indexChanged', this, function (index) { - self.context.codeManager.resolveStep(index, self.context.tx) - }) - }, - - indexChanged: function (index) { - this.refs.itemsList.value = index - }, - - codeChanged: function (code, address, index) { - this.setState({ - code: code, - address: address - }) - this.refs.itemsList.value = index - }, - - shouldComponentUpdate: function (nextProps, nextState) { - if (nextState.address === this.state.address) { - return false - } - return true - }, - - renderAssemblyItems: function () { - if (this.state && this.state.code) { - return this.state.code.map(function (item, i) { - return - }) - } - } -}) diff --git a/src/basicPanel.js b/src/basicPanel.js deleted file mode 100644 index cda0818765..0000000000 --- a/src/basicPanel.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict' -var React = require('react') -var style = require('./basicStyles') - -module.exports = React.createClass({ - getDefaultProps: function () { - return { - data: null, - name: null - } - }, - - render: function () { - return ( -
-
- {this.props.name} -
-
-
{this.props.data}
-
-
- ) - } -}) diff --git a/src/basicStyles.js b/src/basicStyles.js index 4d319b988b..eb15ecbf2a 100644 --- a/src/basicStyles.js +++ b/src/basicStyles.js @@ -1,21 +1,21 @@ 'use strict' module.exports = { font: { - 'fontFamily': 'arial,sans-serif' + 'font-family': 'arial,sans-serif' }, container: { 'margin': '10px', 'padding': '5px' }, address: { - 'fontStyle': 'italic' + 'font-style': 'italic' }, instructionsList: { 'width': '320px', 'height': '300px' }, transactionInfo: { - 'marginTop': '5px' + 'margin-top': '5px' }, panel: { container: { @@ -24,14 +24,14 @@ module.exports = { }, tableContainer: { 'height': '300px', - 'overflowY': 'auto' + 'overflow-y': 'auto' }, table: { 'padding': '5px' }, title: { 'padding': '5px', - 'fontStyle': 'italic' + 'font-style': 'italic' } }, hidden: { @@ -41,7 +41,7 @@ module.exports = { 'display': 'block' }, sticker: { - 'verticalAlign': 'top', + 'vertical-align': 'top', 'margin': '5px' }, inline: { diff --git a/src/buttonNavigator.js b/src/buttonNavigator.js deleted file mode 100644 index 8c32238d52..0000000000 --- a/src/buttonNavigator.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict' -var React = require('react') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object - }, - - propTypes: { - stepIntoBack: React.PropTypes.func.isRequired, - stepIntoForward: React.PropTypes.func.isRequired, - stepOverBack: React.PropTypes.func.isRequired, - stepOverForward: React.PropTypes.func.isRequired, - jumpNextCall: React.PropTypes.func.isRequired - }, - - render: function () { - return ( -
- - - - - -
- ) - }, - - shouldComponentUpdate: function () { - return false - }, - - stepChanged: function (step) { - this.refs.intoback.disabled = step <= 0 - this.refs.overback.disabled = step <= 0 - if (!this.context.traceManager) { - this.refs.intoforward.disabled = true - this.refs.overforward.disabled = true - this.refs.nextcall.disabled = true - } else { - var self = this - this.context.traceManager.getLength(function (error, length) { - if (error) { - console.log(error) - } else { - self.refs.intoforward.disabled = step >= length - 1 - self.refs.overforward.disabled = step >= length - 1 - self.refs.nextcall.disabled = step >= length - 1 - } - }) - } - } -}) diff --git a/src/calldataPanel.js b/src/calldataPanel.js deleted file mode 100644 index 70fe32046b..0000000000 --- a/src/calldataPanel.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict' -var React = require('react') -var BasicPanel = require('./basicPanel') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object, - codeManager: React.PropTypes.object, - root: React.PropTypes.object - }, - - getInitialState: function () { - return { - data: null - } - }, - - render: function () { - return ( - - ) - }, - - componentDidMount: function () { - var self = this - this.context.root.register('indexChanged', this, function (index) { - if (index < 0) return - if (self.context.root.ethDebuggerSelectedItem !== index) return - - self.context.traceManager.getCallDataAt(index, function (error, calldata) { - if (error) { - console.log(error) - } else if (self.context.root.ethDebuggerSelectedItem === index) { - self.setState({ - data: self.format(calldata) - }) - } - }) - }) - }, - - format: function (calldata) { - var ret = '' - for (var key in calldata) { - ret += calldata[key] + '\n' - } - return ret - } -}) diff --git a/src/callstackPanel.js b/src/callstackPanel.js deleted file mode 100644 index 7ae7341f73..0000000000 --- a/src/callstackPanel.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict' -var React = require('react') -var BasicPanel = require('./basicPanel') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object, - codeManager: React.PropTypes.object, - root: React.PropTypes.object - }, - - getInitialState: function () { - return { - data: null - } - }, - - render: function () { - return ( - - ) - }, - - componentDidMount: function () { - var self = this - this.context.root.register('indexChanged', this, function (index) { - if (index < 0) return - if (self.context.root.ethDebuggerSelectedItem !== index) return - - self.context.traceManager.getCallStackAt(index, function (error, callstack) { - if (error) { - console.log(error) - } else if (self.context.root.ethDebuggerSelectedItem === index) { - self.setState({ - data: self.format(callstack) - }) - } - }) - }) - }, - - format: function (callstack) { - var ret = '' - for (var key in callstack) { - ret += callstack[key] + '\n' - } - return ret - } -}) diff --git a/src/debugger.js b/src/debugger.js deleted file mode 100644 index 8baa0b8a9a..0000000000 --- a/src/debugger.js +++ /dev/null @@ -1,78 +0,0 @@ -'use strict' -var React = require('react') -var TxBrowser = require('./txBrowser') -var StepManager = require('./stepManager') -var VmDebugger = require('./vmDebugger') -var style = require('./basicStyles') -var util = require('./helpers/global') -var EventManager = require('./lib/eventManager') - -module.exports = React.createClass({ - ethDebuggerSelectedItem: -1, - - getInitialState: function () { - return { - currentStepIndex: -1, // index of the selected item in the vmtrace - tx: null - } - }, - - childContextTypes: { - web3: React.PropTypes.object, - traceManager: React.PropTypes.object, - codeManager: React.PropTypes.object, - root: React.PropTypes.object, - tx: React.PropTypes.object - }, - - getChildContext: function () { - return { - web3: this.props.context.web3, - traceManager: this.props.context.traceManager, - codeManager: this.props.context.codeManager, - root: this, - tx: this.state.tx - } - }, - - render: function () { - return ( -
-

Eth Debugger

- - - -
- ) - }, - - stepChanged: function (stepIndex) { - this.trigger('indexChanged', [stepIndex]) - this.setState({ - currentStepIndex: stepIndex - }) - }, - - componentWillMount: function () { - util.extend(this, new EventManager()) - }, - - startDebugging: function (blockNumber, txIndex, tx) { - if (this.props.context.traceManager.isLoading) { - return - } - console.log('loading trace...') - this.setState({ - tx: tx - }) - var self = this - this.props.context.traceManager.resolveTrace(tx, function (success) { - console.log('trace loaded ' + success) - if (success) { - self.trigger('newTraceLoaded') - } else { - console.log('trace not loaded') - } - }) - } -}) diff --git a/src/helpers/init.js b/src/helpers/init.js index e4c93ae891..7fd4196646 100644 --- a/src/helpers/init.js +++ b/src/helpers/init.js @@ -1,19 +1,12 @@ 'use strict' var Web3 = require('web3') var Web3Admin = require('../util/web3Admin') -var TraceManager = require('../trace/traceManager') -var CodeManager = require('../code/codeManager') module.exports = { - loadContext: function () { + loadWeb3: function () { var web3 = new Web3() web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')) Web3Admin.extend(web3) - var traceManager = new TraceManager(web3) - return { - web3: web3, - traceManager: traceManager, - codeManager: new CodeManager(web3, traceManager) - } + return web3 } } diff --git a/src/helpers/ui.js b/src/helpers/ui.js index 615c9959ce..41705701d1 100644 --- a/src/helpers/ui.js +++ b/src/helpers/ui.js @@ -31,5 +31,15 @@ module.exports = { ret.raw += ' ' + raw } return ret + }, + + formatCss: function (css1, css2) { + var ret = '' + for (var arg in arguments) { + for (var k in arguments[arg]) { + ret += k + ':' + arguments[arg][k] + ';' + } + } + return ret } } diff --git a/src/index.js b/src/index.js index a3b608a91f..ae6298f679 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,9 @@ 'use strict' -var ReactDOM = require('react-dom') -var React = require('react') -var util = require('./helpers/init') -var Debugger = require('./debugger') +var Debugger = require('./Ethdebugger') -ReactDOM.render( - , - document.getElementById('app') -) +function init () { + var ethdebugger = new Debugger() + document.getElementById('app').appendChild(ethdebugger.render()) +} + +init() diff --git a/src/memoryPanel.js b/src/memoryPanel.js deleted file mode 100644 index 804055ec0b..0000000000 --- a/src/memoryPanel.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict' -var React = require('react') -var BasicPanel = require('./basicPanel') -var util = require('./helpers/ui') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object, - web3: React.PropTypes.object, - codeManager: React.PropTypes.object, - root: React.PropTypes.object - }, - - getInitialState: function () { - return { - data: null - } - }, - - render: function () { - return ( - - ) - }, - - componentDidMount: function () { - var self = this - this.context.root.register('indexChanged', this, function (index) { - if (index < 0) return - if (self.context.root.ethDebuggerSelectedItem !== index) return - - self.context.traceManager.getMemoryAt(index, function (error, memory) { - if (error) { - console.log(error) - } else if (self.context.root.ethDebuggerSelectedItem === index) { - self.setState({ - data: util.formatMemory(memory, 16) - }) - } - }) - }) - } -}) diff --git a/src/slider.js b/src/slider.js deleted file mode 100644 index 6b0186cdb8..0000000000 --- a/src/slider.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict' -var React = require('react') -var style = require('./sliderStyles') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object - }, - - propTypes: { - onChange: React.PropTypes.func.isRequired - }, - - getDefaultProps: function () { - return { - min: 0, - max: 1 - } - }, - - render: function () { - return ( -
- -
- ) - }, - - shouldComponentUpdate: function (nextProps, nextState) { - return (nextProps.max !== this.props.max || nextProps.min !== this.props.min) - }, - - componentDidMount: function () { - this.setValue(0) - }, - - onMouseUp: function (event) { - this.props.onChange(parseInt(this.refs.rule.value)) - }, - - setValue: function (value) { - var diff = value - this.refs.rule.value - if (diff > 0) { - this.refs.rule.stepUp(diff) - } else { - this.refs.rule.stepDown(Math.abs(diff)) - } - } -}) diff --git a/src/stackPanel.js b/src/stackPanel.js deleted file mode 100644 index ca4eabf21b..0000000000 --- a/src/stackPanel.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict' -var React = require('react') -var BasicPanel = require('./basicPanel') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object, - codeManager: React.PropTypes.object, - root: React.PropTypes.object - }, - - getInitialState: function () { - return { - data: null - } - }, - - render: function () { - return ( - - ) - }, - - componentDidMount: function () { - var self = this - this.context.root.register('indexChanged', this, function (index) { - if (index < 0) return - if (self.context.root.ethDebuggerSelectedItem !== index) return - - self.context.traceManager.getStackAt(index, function (error, stack) { - if (error) { - console.log(error) - } else if (self.context.root.ethDebuggerSelectedItem === index) { - self.setState({ - data: self.format(stack) - }) - } - }) - }) - }, - - format: function (stack) { - var ret = '' - for (var key in stack) { - ret += stack[key] + '\n' - } - return ret - } -}) diff --git a/src/stepManager.js b/src/stepManager.js deleted file mode 100644 index edd30f6002..0000000000 --- a/src/stepManager.js +++ /dev/null @@ -1,139 +0,0 @@ -'use strict' -var React = require('react') -var ButtonNavigator = require('./buttonNavigator') -var Slider = require('./slider') -var style = require('./basicStyles') - -module.exports = React.createClass({ - propTypes: { - onStepChanged: React.PropTypes.func.isRequired - }, - - contextTypes: { - traceManager: React.PropTypes.object, - root: React.PropTypes.object - }, - - getInitialState: function () { - return { - currentStepIndex: 0, - traceLength: 0 - } - }, - - render: function () { - return ( -
- - -
- ) - }, - - componentDidMount: function () { - var self = this - this.context.root.register('newTraceLoaded', this, function () { - self.newTraceAvailable() - }) - this.changeState(-1) - }, - - updateGlobalSelectedItem: function (value) { - this.context.root.ethDebuggerSelectedItem = value - }, - - init: function () { - this.refs.slider.setValue(0) - this.changeState(0) - }, - - newTraceAvailable: function () { - this.init() - var self = this - this.context.traceManager.getLength(function (error, length) { - if (error) { - console.log(error) - } else { - self.setState({ traceLength: length }) - } - }) - }, - - sliderMoved: function (step) { - if (!this.context.traceManager.inRange(step)) { - return - } - this.changeState(step) - }, - - stepIntoForward: function () { - if (!this.context.traceManager.isLoaded()) { - return - } - var step = this.state.currentStepIndex + 1 - if (!this.context.traceManager.inRange(step)) { - return - } - this.refs.slider.setValue(step) - this.changeState(step) - }, - - stepIntoBack: function () { - if (!this.context.traceManager.isLoaded()) { - return - } - var step = this.state.currentStepIndex - 1 - if (!this.context.traceManager.inRange(step)) { - return - } - this.refs.slider.setValue(step) - this.changeState(step) - }, - - stepOverForward: function () { - if (!this.context.traceManager.isLoaded()) { - return - } - var step = this.context.traceManager.findStepOverForward(this.state.currentStepIndex) - this.refs.slider.setValue(step) - this.changeState(step) - }, - - stepOverBack: function () { - if (!this.context.traceManager.isLoaded()) { - return - } - var step = this.context.traceManager.findStepOverBack(this.state.currentStepIndex) - this.refs.slider.setValue(step) - this.changeState(step) - }, - - jumpToNextCall: function () { - if (!this.context.traceManager.isLoaded()) { - return - } - var step = this.context.traceManager.findNextCall(this.state.currentStepIndex) - this.refs.slider.setValue(step) - this.changeState(step) - }, - - changeState: function (step) { - this.updateGlobalSelectedItem(step) - this.setState({ - currentStepIndex: step - }) - this.refs.buttons.stepChanged(step) - this.props.onStepChanged(step) - } -}) diff --git a/src/sticker.js b/src/sticker.js deleted file mode 100644 index de2413e4f6..0000000000 --- a/src/sticker.js +++ /dev/null @@ -1,138 +0,0 @@ -'use strict' -var React = require('react') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object, - codeManager: React.PropTypes.object, - root: React.PropTypes.object - }, - - getInitialState: function () { - return { - vmTraceStep: '', - step: '', - addmemory: '', - gas: '', - remainingGas: '' - } - }, - - render: function () { - return ( -
- - - - - - - - - - - - - - - - - - - - - - - -
- vmtracestep - - {this.state.vmTraceStep} -
- step - - {this.state.step} -
- add memory - - {this.state.addmemory} -
- gas - - {this.state.gas} -
- remaining gas - - {this.state.remainingGas} -
-
- ) - }, - - renderItems: function () { - if (this.state.data) { - var ret = [] - for (var key in this.state.data) { - ret.push( - - - {this.props.data[key]} - - ) - } - return ret - } - return null - }, - - componentDidMount: function () { - var self = this - this.context.root.register('indexChanged', this, function (index) { - if (index < 0) return - - self.setState({ - vmTraceStep: index - }) - - self.context.traceManager.getCurrentStep(index, function (error, step) { - if (error) { - console.log(error) - } else { - self.setState({ - step: step - }) - } - }) - - self.context.traceManager.getMemExpand(index, function (error, addmem) { - if (error) { - console.log(error) - } else { - self.setState({ - addmemory: addmem - }) - } - }) - - self.context.traceManager.getStepCost(index, function (error, gas) { - if (error) { - console.log(error) - } else { - self.setState({ - gas: gas - }) - } - }) - - self.context.traceManager.getRemainingGas(index, function (error, remaingas) { - if (error) { - console.log(error) - } else { - self.setState({ - remainingGas: remaingas - }) - } - }) - }) - } -}) diff --git a/src/storagePanel.js b/src/storagePanel.js deleted file mode 100644 index 8ed5804bbd..0000000000 --- a/src/storagePanel.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict' -var React = require('react') -var BasicPanel = require('./basicPanel') - -module.exports = React.createClass({ - contextTypes: { - traceManager: React.PropTypes.object, - tx: React.PropTypes.object, - codeManager: React.PropTypes.object, - root: React.PropTypes.object - }, - - getInitialState: function () { - return { - data: null - } - }, - - render: function () { - return ( - - ) - }, - - componentDidMount: function () { - var self = this - this.context.root.register('indexChanged', this, function (index) { - if (index < 0) return - if (self.context.root.ethDebuggerSelectedItem !== index) return - - self.context.traceManager.getStorageAt(index, self.context.tx, function (error, storage) { - if (error) { - console.log(error) - } else if (self.context.root.ethDebuggerSelectedItem === index) { - self.setState({ - data: self.formatStorage(storage) - }) - } - }) - }) - }, - - formatStorage: function (storage) { - var ret = '' - for (var key in storage) { - ret += key + ' ' + storage[key] + '\n' - } - return ret - } -}) diff --git a/src/txBrowser.js b/src/txBrowser.js deleted file mode 100644 index 68efe933ed..0000000000 --- a/src/txBrowser.js +++ /dev/null @@ -1,97 +0,0 @@ -'use strict' -var React = require('react') -var style = require('./basicStyles') -var traceHelper = require('./helpers/traceHelper') - -module.exports = React.createClass({ - contextTypes: { - web3: React.PropTypes.object - }, - - propTypes: { - onNewTxRequested: React.PropTypes.func.isRequired - }, - - getInitialState: function () { - return {blockNumber: '1000110', txNumber: '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51', from: '', to: '', hash: ''} - }, - - // creation 0xa9619e1d0a35b2c1d686f5b661b3abd87f998d2844e8e9cc905edb57fc9ce349 - // invokation 0x71a6d583d16d142c5c3e8903060e8a4ee5a5016348a9448df6c3e63b68076ec4 - // test: - // creation: 0x72908de76f99fca476f9e3a3b5d352f350a98cd77d09cebfc59ffe32a6ecaa0b - // invokation: 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51 - - submit: function () { - var tx - if (this.state.txNumber.indexOf('0x') !== -1) { - tx = this.context.web3.eth.getTransaction(this.state.txNumber) - } else { - tx = this.context.web3.eth.getTransactionFromBlock(this.state.blockNumber, this.state.txNumber) - } - console.log(JSON.stringify(tx)) - if (tx) { - if (!tx.to) { - tx.to = traceHelper.contractCreationToken('0') - } - this.setState({from: tx.from, to: tx.to, hash: tx.hash}) - this.props.onNewTxRequested(this.state.blockNumber, parseInt(this.state.txNumber), tx) - } else { - console.log('cannot find ' + this.state.blockNumber + ' ' + this.state.txNumber) - } - }, - - updateTxhash: function (ev) { - this.state.hash = ev.target.value - }, - - updateBlockN: function (ev) { - this.state.blockNumber = ev.target.value - }, - - updateTxN: function (ev) { - this.state.txNumber = ev.target.value - }, - - render: function () { - return ( -
- - - -
- - - - - - - - - - - - - - - -
- Hash: - - {this.state.hash} -
- From: - - {this.state.from} -
- To: - - {this.state.to} -
-
-
- ) - } -}) diff --git a/src/vmDebugger.js b/src/vmDebugger.js deleted file mode 100644 index 3aba62c327..0000000000 --- a/src/vmDebugger.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict' -var React = require('react') -var Sticker = require('./sticker') -var style = require('./basicStyles') -var ASMCode = require('./asmCode') -var CalldataPanel = require('./calldataPanel') -var MemoryPanel = require('./memoryPanel') -var CallstackPanel = require('./callstackPanel') -var StackPanel = require('./stackPanel') -var StoragePanel = require('./storagePanel') - -module.exports = React.createClass({ - render: function () { - return ( -
-
- - - - - - - - - - - - - - - -
- -
- -
-
- -
- - - -
- - - -
-
-
- ) - } -}) diff --git a/test/codeManager.js b/test/codeManager.js index 542ebcf730..fc9615fda8 100644 --- a/test/codeManager.js +++ b/test/codeManager.js @@ -4,14 +4,17 @@ var init = require('../src/helpers/init') var txInvokation = require('./resources/contractInvokationTx') var TestTraceRetriever = require('./TestTraceRetriever') var contractCode = require('./resources/contractInvokationCode') +var TraceManager = require('../src/trace/traceManager') +var CodeManager = require('../src/code/codeManager') tape('CodeManager', function (t) { var codeManager - var context = init.loadContext() - codeManager = context.codeManager - context.traceManager.traceRetriever = new TestTraceRetriever() + var web3 = init.loadWeb3() + var traceManager = new TraceManager(web3) + traceManager.traceRetriever = new TestTraceRetriever() + codeManager = new CodeManager(web3, traceManager) codeManager.codeResolver.cacheExecutingCode('0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5', contractCode) // so a call to web3 is not necessary - context.traceManager.resolveTrace(txInvokation, function (success) { + traceManager.resolveTrace(txInvokation, function (success) { if (!success) { t.fail(' - traceManager.resolveTrace - failed') } else { diff --git a/test/index.js b/test/index.js index 00b04e0274..3dc4dc0e23 100644 --- a/test/index.js +++ b/test/index.js @@ -3,9 +3,9 @@ var tape = require('tape') var init = require('../src/helpers/init') tape('index', function (t) { t.test('loadContext - web3', function (st) { - var context = init.loadContext() - st.notEqual(context.web3, undefined) - st.notEqual(context.web3, null) + var web3 = init.loadWeb3() + st.notEqual(web3, undefined) + st.notEqual(web3, null) st.end() }) }) diff --git a/test/traceManager.js b/test/traceManager.js index 89fe262ca5..43b2f85ea3 100644 --- a/test/traceManager.js +++ b/test/traceManager.js @@ -9,8 +9,8 @@ tape('TraceManager', function (t) { var traceManager t.test('TraceManager.init', function (st) { - var context = init.loadContext() - traceManager = new TraceManager(context.web3) + var web3 = init.loadWeb3() + traceManager = new TraceManager(web3) traceManager.traceRetriever = new TestTraceRetriever() st.end() })