add locationdecoder & statedecoder

pull/7/head
yann300 8 years ago
parent a3b953ecd4
commit 6152eb41c8
  1. 61
      src/solidity/locationDecoder.js
  2. 89
      src/solidity/stateDecoder.js

@ -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…
Cancel
Save