From a8d89aa416f2a7897c867786d44922a53b22363c Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 10 Jan 2017 13:47:13 +0100 Subject: [PATCH] Add RefType + provide location --- src/solidity/decodeInfo.js | 12 +++++++----- src/solidity/types/ArrayType.js | 30 ++++++++++-------------------- src/solidity/types/RefType.js | 28 ++++++++++++++++++++++++++++ src/solidity/types/Struct.js | 19 ++++--------------- src/solidity/types/util.js | 12 +++++++++++- 5 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 src/solidity/types/RefType.js diff --git a/src/solidity/decodeInfo.js b/src/solidity/decodeInfo.js index 3246a1cf36..f045b19308 100644 --- a/src/solidity/decodeInfo.js +++ b/src/solidity/decodeInfo.js @@ -118,7 +118,8 @@ function Array (type, stateDefinitions, contractName) { console.log('unable to parse type ' + type) return null } - return new ArrayType(underlyingType, arraySize) + var location = match[3].trim() + return new ArrayType(underlyingType, arraySize, location) } /** @@ -149,12 +150,13 @@ function Enum (type, stateDefinitions, contractName) { */ function Struct (type, stateDefinitions, contractName) { var match = type.match(/struct (.*?)( storage ref| storage pointer| memory| calldata)?$/) - if (!match) { + if (match && match.length > 2) { + var memberDetails = getStructMembers(match[1], stateDefinitions, contractName) // type is used to extract the ast struct definition + if (!memberDetails) return null + return new StructType(memberDetails, match[2].trim()) + } else { return null } - var memberDetails = getStructMembers(match[1], stateDefinitions, contractName) // type is used to extract the ast struct definition - if (!memberDetails) return null - return new StructType(memberDetails) } /** diff --git a/src/solidity/types/ArrayType.js b/src/solidity/types/ArrayType.js index 62afc195c2..56aaf3b147 100644 --- a/src/solidity/types/ArrayType.js +++ b/src/solidity/types/ArrayType.js @@ -1,25 +1,25 @@ 'use strict' var util = require('./util') var BN = require('ethereumjs-util').BN +var RefType = require('./RefType') -class ArrayType { +class ArrayType extends RefType { - constructor (underlyingType, arraySize) { - this.typeName = 'array' - this.storageBytes = 32 - this.underlyingType = underlyingType - this.arraySize = arraySize - this.storageSlots = null + constructor (underlyingType, arraySize, location) { + var storageSlots = null if (arraySize === 'dynamic') { - this.storageSlots = 1 + storageSlots = 1 } else { if (underlyingType.storageBytes < 32) { var itemPerSlot = Math.floor(32 / underlyingType.storageBytes) - this.storageSlots = Math.ceil(arraySize / itemPerSlot) + storageSlots = Math.ceil(arraySize / itemPerSlot) } else { - this.storageSlots = arraySize * underlyingType.storageSlots + storageSlots = arraySize * underlyingType.storageSlots } } + super(storageSlots, 32, 'array', location) + this.underlyingType = underlyingType + this.arraySize = arraySize } decodeFromStorage (location, storageContent) { @@ -56,16 +56,6 @@ class ArrayType { } } - decodeFromStack (stackDepth, stack, memory) { - if (stack.length - 1 < stackDepth) { - return [] - } else { // TODO manage decoding locals from storage - var offset = stack[stack.length - 1 - stackDepth] - offset = 2 * parseInt(offset, 16) - return this.decodeFromMemory(offset, memory) - } - } - decodeFromMemory (offset, memory) { var ret = [] var length = extractLength(this, offset, memory) diff --git a/src/solidity/types/RefType.js b/src/solidity/types/RefType.js new file mode 100644 index 0000000000..7426d17396 --- /dev/null +++ b/src/solidity/types/RefType.js @@ -0,0 +1,28 @@ +'use strict' +var util = require('./util') + +class RefType { + constructor (storageSlots, storageBytes, typeName, location) { + this.location = location + this.storageSlots = storageSlots + this.storageBytes = storageBytes + this.typeName = typeName + } + + decodeFromStack (stackDepth, stack, memory, storage) { + if (stack.length - 1 < stackDepth) { + return [] + } + var offset = stack[stack.length - 1 - stackDepth] + offset = 2 * parseInt(offset, 16) + if (util.storageStore(this)) { + return this.decodeFromStorage(offset, storage) + } else if (util.memoryStore(this)) { + return this.decodeFromMemory(offset, memory) + } else { + return '' + } + } +} + +module.exports = RefType diff --git a/src/solidity/types/Struct.js b/src/solidity/types/Struct.js index ecdbded5e8..276ea04dfb 100644 --- a/src/solidity/types/Struct.js +++ b/src/solidity/types/Struct.js @@ -1,12 +1,11 @@ 'use strict' var util = require('./util') +var RefType = require('./RefType') -class Struct { - constructor (memberDetails) { - this.storageSlots = memberDetails.storageSlots - this.storageBytes = 32 +class Struct extends RefType { + constructor (memberDetails, location) { + super(memberDetails.storageSlots, 32, 'struct', location) this.members = memberDetails.members - this.typeName = 'struct' } decodeFromStorage (location, storageContent) { @@ -21,16 +20,6 @@ class Struct { return ret } - decodeFromStack (stackDepth, stack, memory) { - if (stack.length - 1 < stackDepth) { - return {} - } else { // TODO manage decoding locals from storage - var offset = stack[stack.length - 1 - stackDepth] - offset = 2 * parseInt(offset, 16) - return this.decodeFromMemory(offset, memory) - } - } - decodeFromMemory (offset, memory) { var ret = {} this.members.map(function (item, i) { diff --git a/src/solidity/types/util.js b/src/solidity/types/util.js index aea200d5ed..db752bb130 100644 --- a/src/solidity/types/util.js +++ b/src/solidity/types/util.js @@ -10,7 +10,9 @@ module.exports = { extractHexByteSlice: extractHexByteSlice, sha3: sha3, toBN: toBN, - add: add + add: add, + storageStore: storageStore, + memoryStore: memoryStore } function decodeInt (location, storageContent, byteLength, signed) { @@ -91,3 +93,11 @@ function toBN (value) { function add (value1, value2) { return toBN(value1).add(toBN(value2)) } + +function storageStore (type) { + return type.location.indexOf('storage') === 0 +} + +function memoryStore (type) { + return type.location.indexOf('memory') === 0 +}