parent
a3b953ecd4
commit
6152eb41c8
@ -0,0 +1,61 @@ |
||||
/** |
||||
* determine what will be the start and end location of the current @arg type. |
||||
* |
||||
* @param {Object} type - current type ( see ./types/list.js ) |
||||
* @param {Object} positon - current position in storage |
||||
* @return {Object} returns the start and end location of the current @arg type. |
||||
*/ |
||||
function walkStorage (type, position) { |
||||
var usedLocation = locationToFitType(type, position) |
||||
return { |
||||
currentLocation: usedLocation, |
||||
endLocation: locationToEnd(type, usedLocation) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* determine the start location of #arg type |
||||
* |
||||
* @param {Object} type - current type ( see ./types/list.js ) |
||||
* @param {Object} positon - current position in storage |
||||
* @return {Object} returns the start position of the current @arg type. |
||||
*/ |
||||
function locationToFitType (type, position) { |
||||
if ((position.offset !== 0 && type.needsFreeStorageSlot) || (position.offset + type.storageBytes > 32 && !type.needsFreeStorageSlot)) { |
||||
return { |
||||
slot: position.slot + 1, |
||||
offset: 0 |
||||
} |
||||
} else { |
||||
return { |
||||
slot: position.slot, |
||||
offset: position.offset |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* determine the end location of #arg type |
||||
* |
||||
* @param {Object} type - current type ( see ./types/list.js ) |
||||
* @param {Object} positon - current position in storage |
||||
* @return {Object} returns the end position of the current @arg type. |
||||
*/ |
||||
function locationToEnd (type, positon) { |
||||
if (positon.offset + type.storageBytes > 32) { |
||||
var slots = Math.floor(type.storageBytes / 32) - 1 |
||||
return { |
||||
slot: positon.slot + slots, |
||||
offset: 32 |
||||
} |
||||
} else { |
||||
return { |
||||
slot: positon.slot, |
||||
offset: positon.offset + type.storageBytes |
||||
} |
||||
} |
||||
} |
||||
|
||||
module.exports = { |
||||
walkStorage: walkStorage |
||||
} |
@ -0,0 +1,89 @@ |
||||
var astHelper = require('./astHelper') |
||||
var decodeInfo = require('./decodeInfo') |
||||
var locationDecoder = require('./locationDecoder') |
||||
|
||||
/** |
||||
* decode the contract state storage |
||||
* |
||||
* @param {Array} storage location - location of all state variables |
||||
* @param {Map} storageContent - storage |
||||
* @return {Map} - decoded state variable |
||||
*/ |
||||
function decodeState (stateVars, storageContent) { |
||||
if (storageContent['0x']) { |
||||
storageContent['0x00'] = storageContent['0x'] |
||||
storageContent['0x'] = undefined |
||||
} |
||||
var ret = {} |
||||
for (var k in stateVars) { |
||||
var stateVar = stateVars[k] |
||||
ret[stateVar.name] = stateVar.type.decodeFromStorage(stateVar.location, storageContent) |
||||
} |
||||
return ret |
||||
} |
||||
|
||||
/** |
||||
* return all storage location variables of the given @arg contractName |
||||
* |
||||
* @param {String} contractName - name of the contract |
||||
* @param {Object} sourcesList - sources list |
||||
* @return {Object} - return the location of all contract variables in the storage |
||||
*/ |
||||
function extractStateVariables (contractName, sourcesList) { |
||||
var stateDefinitions = astHelper.extractStateVariables(contractName, sourcesList) |
||||
var ret = [] |
||||
if (!stateDefinitions) { |
||||
return ret |
||||
} |
||||
var location = { |
||||
offset: 0, |
||||
slot: 0 |
||||
} |
||||
for (var k in stateDefinitions) { |
||||
var variable = stateDefinitions[k] |
||||
if (variable.name === 'VariableDeclaration') { |
||||
var decoded = decodeInfo.decode(variable.attributes.type, stateDefinitions) |
||||
var type = new types[decoded.typeName](decoded) |
||||
var loc = locationDecoder.walkStorage(type, location) |
||||
ret.push({ |
||||
name: variable.attributes.name, |
||||
type: type, |
||||
location: loc.currentLocation |
||||
}) |
||||
location = loc.endLocation |
||||
} |
||||
} |
||||
return ret |
||||
} |
||||
|
||||
/** |
||||
* return the state of the given @a contractName as a json object |
||||
* |
||||
* @param {Map} storageContent - contract storage |
||||
* @param {astList} astList - AST nodes of all the sources |
||||
* @param {String} contractName - contract for which state var should be resolved |
||||
* @return {Map} - return the state of the contract |
||||
*/ |
||||
function solidityState (storageContent, astList, contractName) { |
||||
var stateVars = extractStateVariables(contractName, astList) |
||||
return decodeState(stateVars, storageContent) |
||||
} |
||||
|
||||
module.exports = { |
||||
solidityState: solidityState, |
||||
extractStateVariables: extractStateVariables, |
||||
decodeState: decodeState |
||||
} |
||||
|
||||
var types = { |
||||
'address': require('./types/Address'), |
||||
'array': require('./types/ArrayType'), |
||||
'bool': require('./types/Bool'), |
||||
'bytes': require('./types/DynamicByteArray'), |
||||
'bytesX': require('./types/FixedByteArray'), |
||||
'enum': require('./types/Enum'), |
||||
'string': require('./types/StringType'), |
||||
'struct': require('./types/Struct'), |
||||
'int': require('./types/Int'), |
||||
'uint': require('./types/Uint') |
||||
} |
Loading…
Reference in new issue