|
|
|
@ -3,6 +3,8 @@ var DropdownPanel = require('./DropdownPanel') |
|
|
|
|
var stateDecoder = require('../solidity/stateDecoder') |
|
|
|
|
var solidityTypeFormatter = require('./SolidityTypeFormatter') |
|
|
|
|
var StorageViewer = require('../storage/storageViewer') |
|
|
|
|
var util = require('../solidity/types/util') |
|
|
|
|
var ethutil = require('ethereumjs-util') |
|
|
|
|
var yo = require('yo-yo') |
|
|
|
|
|
|
|
|
|
function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy) { |
|
|
|
@ -64,6 +66,23 @@ SolidityState.prototype.init = function () { |
|
|
|
|
tx: self.parent.tx, |
|
|
|
|
address: address |
|
|
|
|
}, self.storageResolver, self.traceManager) |
|
|
|
|
|
|
|
|
|
var storageJSON = {} |
|
|
|
|
storageViewer.storageRange(function (error, result) { |
|
|
|
|
if (!error) { |
|
|
|
|
storageJSON = result |
|
|
|
|
var sha3Preimages = self.traceManager.traceCache.sha3Preimages |
|
|
|
|
var mappingPreimages = getMappingPreimages(stateVars, storageJSON, sha3Preimages) |
|
|
|
|
|
|
|
|
|
for (var k in stateVars) { |
|
|
|
|
var stateVar = stateVars[k] |
|
|
|
|
if (stateVar.type.typeName.indexOf('mapping') === 0) { |
|
|
|
|
var mapSlot = util.toBN(stateVar.storagelocation.slot).toString(16) |
|
|
|
|
mapSlot = ethutil.setLengthLeft('0x' + mapSlot, 32).toString('hex') |
|
|
|
|
stateVar.type.setMappingElements(mappingPreimages[mapSlot]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
stateDecoder.decodeState(stateVars, storageViewer).then((result) => { |
|
|
|
|
if (!result.error) { |
|
|
|
|
self.basicPanel.update(result) |
|
|
|
@ -73,7 +92,50 @@ SolidityState.prototype.init = function () { |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getMappingPreimages (stateVars, storage, preimages) { |
|
|
|
|
// loop over stateVars and get the locations of all the mappings
|
|
|
|
|
// then on each mapping, pass its specific preimage keys
|
|
|
|
|
|
|
|
|
|
// first filter out all non-mapping storage slots
|
|
|
|
|
|
|
|
|
|
var ignoreSlots = [] |
|
|
|
|
for (var k in stateVars) { |
|
|
|
|
var stateVar = stateVars[k] |
|
|
|
|
if (stateVar.type.typeName.indexOf('mapping') !== 0) { |
|
|
|
|
ignoreSlots.push(stateVar.storagelocation.slot.toString()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var possibleMappings = [] |
|
|
|
|
for (var hashedLoc in storage) { |
|
|
|
|
var slotNum = util.toBN(storage[hashedLoc].key).toString(10) |
|
|
|
|
if (ignoreSlots.indexOf(slotNum) === -1) { |
|
|
|
|
possibleMappings.push(storage[hashedLoc].key) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var storageMappings = {} |
|
|
|
|
for (var pk in possibleMappings) { |
|
|
|
|
var possMapKey = possibleMappings[pk].replace('0x', '') |
|
|
|
|
if (preimages[possMapKey]) { |
|
|
|
|
// got preimage!
|
|
|
|
|
var preimage = preimages[possMapKey].preimage |
|
|
|
|
// get mapping position (i.e. storage slot), its the last 32 bytes
|
|
|
|
|
var slotByteOffset = preimage.length - 64 |
|
|
|
|
var mappingSlot = preimage.substr(slotByteOffset) |
|
|
|
|
var mappingKey = preimage.substr(0, slotByteOffset) |
|
|
|
|
if (!storageMappings[mappingSlot]) { |
|
|
|
|
storageMappings[mappingSlot] = [] |
|
|
|
|
} |
|
|
|
|
storageMappings[mappingSlot].push(mappingKey) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return storageMappings |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
module.exports = SolidityState |
|
|
|
|