Commit 3a4a36d0 authored by yann300's avatar yann300

decode array

parent 6e43844d
'use strict' 'use strict'
var util = require('./util')
var BN = require('ethereumjs-util').BN
function ArrayType (underlyingType, arraySize) { function ArrayType (underlyingType, arraySize) {
this.typeName = 'array' this.typeName = 'array'
...@@ -19,7 +21,42 @@ function ArrayType (underlyingType, arraySize) { ...@@ -19,7 +21,42 @@ function ArrayType (underlyingType, arraySize) {
} }
ArrayType.prototype.decodeFromStorage = function (location, storageContent) { ArrayType.prototype.decodeFromStorage = function (location, storageContent) {
return '<not implemented yet>' var ret = []
var size = null
var slotValue = util.extractValue(location, storageContent, this.storageBytes)
if (!slotValue) {
return []
}
var currentLocation = {
offset: 0,
slot: location.slot
}
if (this.arraySize === 'dynamic') {
size = util.toBN(slotValue)
currentLocation.slot = util.dynamicTypePointer(location.slot)
if (!storageContent[currentLocation.slot]) {
return []
}
} else {
size = new BN(this.arraySize)
}
var k = util.toBN(0)
var one = util.toBN(1)
while (k.lt(size)) {
if (currentLocation.offset + this.underlyingType.storageBytes > 32) {
currentLocation.offset = 0
currentLocation.slot = '0x' + util.add(currentLocation.slot, one).toString(16)
}
ret.push(this.underlyingType.decodeFromStorage(currentLocation, storageContent))
if (this.underlyingType.storageSlots === 1 && location.offset + this.underlyingType.storageBytes <= 32) {
currentLocation.offset += this.underlyingType.storageBytes
} else {
currentLocation.slot = '0x' + util.add(currentLocation.slot, this.underlyingType.storageSlots).toString(16)
currentLocation.offset = 0
}
k = k.add(one)
}
return ret
} }
module.exports = ArrayType module.exports = ArrayType
'use strict' 'use strict'
var util = require('./util')
function Struct (memberDetails) { function Struct (memberDetails) {
this.storageSlots = memberDetails.storageSlots this.storageSlots = memberDetails.storageSlots
...@@ -12,7 +13,7 @@ Struct.prototype.decodeFromStorage = function (location, storageContent) { ...@@ -12,7 +13,7 @@ Struct.prototype.decodeFromStorage = function (location, storageContent) {
this.members.map(function (item, i) { this.members.map(function (item, i) {
var globalLocation = { var globalLocation = {
offset: location.offset + item.location.offset, offset: location.offset + item.location.offset,
slot: location.slot + item.location.slot slot: util.add(location.slot, item.location.slot)
} }
ret[item.name] = item.type.decodeFromStorage(globalLocation, storageContent) ret[item.name] = item.type.decodeFromStorage(globalLocation, storageContent)
}) })
......
...@@ -34,15 +34,21 @@ function readFromStorage (slot, storageContent) { ...@@ -34,15 +34,21 @@ function readFromStorage (slot, storageContent) {
return extractSlotValue(storageContent[slot], storageBytes, location) return extractSlotValue(storageContent[slot], storageBytes, location)
}, },
dynamicTypePointer: function getDynamicPointer (location) { dynamicTypePointer: function (slot) {
var remoteSlot = formatSlot(location.slot) var remoteSlot = toLongHex(slot)
var key = ethutil.sha3(remoteSlot) var key = ethutil.sha3(remoteSlot)
return ethutil.bufferToHex(key) return ethutil.bufferToHex(key)
} },
toLongHex: toLongHex,
toBN: toBN,
add: add
} }
function formatSlot (slot) { function toLongHex (slot) {
if (slot instanceof BN) {
slot = '0x' + slot.toString(16)
}
return ethutil.bufferToHex(ethutil.setLengthLeft(slot, 32)) return ethutil.bufferToHex(ethutil.setLengthLeft(slot, 32))
} }
...@@ -74,6 +80,21 @@ function extractHexByteSlice (slotValue, byteLength, offsetFromLSB) { ...@@ -74,6 +80,21 @@ function extractHexByteSlice (slotValue, byteLength, offsetFromLSB) {
return slotValue.substr(offset, 2 * byteLength) return slotValue.substr(offset, 2 * byteLength)
} }
function toBN (value) {
if (value instanceof BN) {
return value
} else if (value.indexOf && value.indexOf('0x') === 0) {
value = ethutil.unpad(value.replace('Ox', ''))
value = new BN(value === '' ? '0' : value, 16)
} else if (!isNaN(value)) {
value = new BN(value)
}
return value
}
function add (value1, value2) {
return toBN(value1).add(toBN(value2))
}
/** /**
* @returns a hex encoded storage content at the given @arg location. it does not have Ox prefix but always has the full length. * @returns a hex encoded storage content at the given @arg location. it does not have Ox prefix but always has the full length.
* *
......
...@@ -209,4 +209,76 @@ function testStructArrayStorage (st) { ...@@ -209,4 +209,76 @@ function testStructArrayStorage (st) {
st.equal(decoded['intStructDec']['i256'], '-1243565465756') st.equal(decoded['intStructDec']['i256'], '-1243565465756')
st.equal(decoded['intStructDec']['ui16'], '34556') st.equal(decoded['intStructDec']['ui16'], '34556')
st.equal(decoded['intStructDec']['i32'], '-345446546') st.equal(decoded['intStructDec']['i32'], '-345446546')
st.equal(decoded['i5'][0], '-2134')
st.equal(decoded['i5'][1], '345')
st.equal(decoded['i5'][2], '-3246')
st.equal(decoded['i5'][3], '4357')
st.equal(decoded['i5'][4], '324')
st.equal(decoded['i5'][5], '-2344')
st.equal(decoded['i5'][6], '3254')
st.equal(decoded['idyn5'][0], '-2134')
st.equal(decoded['idyn5'][1], '345')
st.equal(decoded['idyn5'][2], '-3246')
st.equal(decoded['idyn5'][3], '4357')
st.equal(decoded['idyn5'][4], '324')
st.equal(decoded['idyn5'][5], '-2344')
st.equal(decoded['idyn5'][6], '3254')
st.equal(decoded['idyn5'][7], '-254')
st.equal(decoded['idyn5'][8], '-2354')
st.equal(decoded['dyn1'][0][0], '3')
st.equal(decoded['dyn1'][1][0], '12')
st.equal(decoded['dyn1'][1][1], '-12')
st.equal(decoded['dyn1'][1][2], '-1234')
st.equal(decoded['dyn1'][2][0], '1')
st.equal(decoded['dyn1'][2][1], '12')
st.equal(decoded['dyn1'][2][2], '1235')
st.equal(decoded['dyn1'][2][3], '-12')
st.equal(decoded['dyn1'][2][4], '-123456')
st.equal(decoded['dyn1'][2][5], '-23435435')
st.equal(decoded['dyn1'][2][6], '543543')
st.equal(decoded['dyn1'][2][7], '2')
st.equal(decoded['dyn1'][2][8], '-1')
st.equal(decoded['dyn1'][2][9], '232432')
st.equal(decoded['dyn1'][3][0], '232432')
st.equal(decoded['dyn1'][3][0], '232432')
st.equal(decoded['dyn2'][0][0][0], '23')
st.equal(decoded['dyn2'][0][0][1], '-23')
st.equal(decoded['dyn2'][0][0][2], '-28')
st.equal(decoded['dyn2'][0][1][0], '23')
st.equal(decoded['dyn2'][0][1][1], '-23')
st.equal(decoded['dyn2'][0][1][2], '-28')
st.equal(decoded['dyn2'][0][2][0], '23')
st.equal(decoded['dyn2'][0][2][1], '-23')
st.equal(decoded['dyn2'][0][2][2], '-28')
st.equal(decoded['dyn2'][0][3][0], '23')
st.equal(decoded['dyn2'][0][3][1], '-23')
st.equal(decoded['dyn2'][0][3][2], '-28')
st.equal(decoded['dyn2'][1][0][0], '23')
st.equal(decoded['dyn2'][1][0][1], '-23')
st.equal(decoded['dyn2'][1][0][2], '-28')
st.equal(decoded['dyn2'][1][1][0], '23')
st.equal(decoded['dyn2'][1][1][1], '-23')
st.equal(decoded['dyn2'][1][1][2], '-28')
st.equal(decoded['dyn2'][1][2][0], '23')
st.equal(decoded['dyn2'][1][2][1], '-23')
st.equal(decoded['dyn2'][1][2][2], '-28')
st.equal(decoded['dyn2'][1][3][0], '23')
st.equal(decoded['dyn2'][1][3][1], '-23')
st.equal(decoded['dyn2'][1][3][2], '-28')
st.equal(decoded['arrayStruct'][0][0].i8, '34')
st.equal(decoded['arrayStruct'][0][0].str, 'test_str_short')
st.equal(decoded['arrayStruct'][0][1].i8, '-123')
st.equal(decoded['arrayStruct'][0][1].str, 'test_str_long test_str_lo ngtest_str_longtest_str_ longtest_str_longtest_ str_longtest_str_l ongtest_str_long')
st.equal(decoded['arrayStruct'][1][0].i8, '50')
st.equal(decoded['arrayStruct'][1][0].str, 'test_str_short')
st.equal(decoded['arrayStruct'][2][0].i8, '60')
st.equal(decoded['arrayStruct'][2][0].str, 'test_str_short')
st.equal(decoded['arrayStruct'][2][1].i8, '84')
st.equal(decoded['arrayStruct'][2][1].str, 'test_str_long test_str_lo ngtest_str_longtest_str_ longtest_str_longtest_ str_longtest_str_l ongtest_str_long')
st.equal(decoded['arrayStruct'][2][2].i8, '-34')
st.equal(decoded['arrayStruct'][2][2].str, 'test_str_short')
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment