parent
c1a72fb5a0
commit
c2be6045ae
@ -0,0 +1,103 @@ |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var remixDebug = require('remix-debug') |
||||
var stateDecoder = remixDebug.SolidityDecoder.stateDecoder |
||||
var solidityTypeFormatter = require('./utils/SolidityTypeFormatter') |
||||
var StorageViewer = remixDebug.storage.StorageViewer |
||||
var yo = require('yo-yo') |
||||
|
||||
function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy) { |
||||
this.storageResolver = null |
||||
this.parent = _parent |
||||
this.traceManager = _traceManager |
||||
this.codeManager = _codeManager |
||||
this.solidityProxy = _solidityProxy |
||||
this.basicPanel = new DropdownPanel('Solidity State', { |
||||
json: true, |
||||
formatSelf: solidityTypeFormatter.formatSelf, |
||||
extractData: solidityTypeFormatter.extractData |
||||
}) |
||||
this.init() |
||||
this.view |
||||
this.stateVariablesByAddresses = {} |
||||
_parent.event.register('traceUnloaded', () => { this.stateVariablesByAddresses = {} }) |
||||
_parent.event.register('newTraceLoaded', () => { this.stateVariablesByAddresses = {} }) |
||||
} |
||||
|
||||
SolidityState.prototype.render = function () { |
||||
if (!this.view) { |
||||
this.view = yo`<div id='soliditystate' >
|
||||
${this.basicPanel.render()} |
||||
</div>` |
||||
} |
||||
return this.view |
||||
} |
||||
|
||||
SolidityState.prototype.init = function () { |
||||
var self = this |
||||
var decodeTimeout = null |
||||
this.parent.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) { |
||||
self.basicPanel.setMessage('invalid step index') |
||||
return |
||||
} |
||||
|
||||
if (self.parent.currentStepIndex !== index) return |
||||
if (!self.solidityProxy.loaded()) { |
||||
self.basicPanel.setMessage('no source has been specified') |
||||
return |
||||
} |
||||
|
||||
if (!self.storageResolver) { |
||||
return |
||||
} |
||||
if (decodeTimeout) { |
||||
window.clearTimeout(decodeTimeout) |
||||
} |
||||
self.basicPanel.setUpdating() |
||||
decodeTimeout = setTimeout(() => { |
||||
decode(self, index) |
||||
}, 500) |
||||
}) |
||||
} |
||||
|
||||
function decode (self, index) { |
||||
self.traceManager.getCurrentCalledAddressAt(self.parent.currentStepIndex, (error, address) => { |
||||
if (error) { |
||||
self.basicPanel.update({}) |
||||
console.log(error) |
||||
} else { |
||||
if (self.stateVariablesByAddresses[address]) { |
||||
extractStateVariables(self, self.stateVariablesByAddresses[address], address) |
||||
} else { |
||||
self.solidityProxy.extractStateVariablesAt(index, function (error, stateVars) { |
||||
if (error) { |
||||
self.basicPanel.update({}) |
||||
console.log(error) |
||||
} else { |
||||
self.stateVariablesByAddresses[address] = stateVars |
||||
extractStateVariables(self, stateVars, address) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
|
||||
function extractStateVariables (self, stateVars, address) { |
||||
var storageViewer = new StorageViewer({ |
||||
stepIndex: self.parent.currentStepIndex, |
||||
tx: self.parent.tx, |
||||
address: address |
||||
}, self.storageResolver, self.traceManager) |
||||
stateDecoder.decodeState(stateVars, storageViewer).then((result) => { |
||||
self.basicPanel.setMessage('') |
||||
if (!result.error) { |
||||
self.basicPanel.update(result) |
||||
} else { |
||||
self.basicPanel.setMessage(result.error) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
module.exports = SolidityState |
||||
|
@ -0,0 +1,71 @@ |
||||
var yo = require('yo-yo') |
||||
var BN = require('ethereumjs-util').BN |
||||
|
||||
module.exports = { |
||||
formatSelf: formatSelf, |
||||
extractData: extractData |
||||
} |
||||
|
||||
function formatSelf (key, data) { |
||||
var style = fontColor(data) |
||||
var keyStyle = data.isProperty ? 'color:#847979' : '' |
||||
if (data.type === 'string') { |
||||
data.self = JSON.stringify(data.self) |
||||
} |
||||
return yo`<label style=${keyStyle}>${key}: <label style=${style}>${data.self}</label><label style='font-style:italic'> ${data.isProperty || !data.type ? '' : ' ' + data.type}</label></label>` |
||||
} |
||||
|
||||
function extractData (item, parent, key) { |
||||
var ret = {} |
||||
if (item.isProperty) { |
||||
return item |
||||
} |
||||
if (item.type.lastIndexOf(']') === item.type.length - 1) { |
||||
ret.children = (item.value || []).map(function (item, index) { |
||||
return {key: index, value: item} |
||||
}) |
||||
ret.children.unshift({ |
||||
key: 'length', |
||||
value: { |
||||
self: (new BN(item.length.replace('0x', ''), 16)).toString(10), |
||||
type: 'uint', |
||||
isProperty: true |
||||
} |
||||
}) |
||||
ret.isArray = true |
||||
ret.self = parent.isArray ? '' : item.type |
||||
} else if (item.type.indexOf('struct') === 0) { |
||||
ret.children = Object.keys((item.value || {})).map(function (key) { |
||||
return {key: key, value: item.value[key]} |
||||
}) |
||||
ret.self = item.type |
||||
ret.isStruct = true |
||||
} else if (item.type.indexOf('mapping') === 0) { |
||||
ret.children = Object.keys((item.value || {})).map(function (key) { |
||||
return {key: key, value: item.value[key]} |
||||
}) |
||||
ret.isMapping = true |
||||
ret.self = item.type |
||||
} else { |
||||
ret.children = null |
||||
ret.self = item.value |
||||
ret.type = item.type |
||||
} |
||||
return ret |
||||
} |
||||
|
||||
function fontColor (data) { |
||||
var color = '#124B46' |
||||
if (data.isArray || data.isStruct || data.isMapping) { |
||||
color = '#847979' |
||||
} else if (data.type.indexOf('uint') === 0 || |
||||
data.type.indexOf('int') === 0 || |
||||
data.type.indexOf('bool') === 0 || |
||||
data.type.indexOf('enum') === 0) { |
||||
color = '#0F0CE9' |
||||
} else if (data.type === 'string') { |
||||
color = '#E91E0C' |
||||
} |
||||
return 'color:' + color |
||||
} |
||||
|
Loading…
Reference in new issue