decode array

pull/7/head
yann300 8 years ago
parent 6e43844de2
commit 3a4a36d0c9
  1. 39
      src/solidity/types/ArrayType.js
  2. 3
      src/solidity/types/Struct.js
  3. 29
      src/solidity/types/util.js
  4. 177
      test/solidity/contracts/structArrayStorage.js
  5. 72
      test/solidity/storageDecoder.js

@ -1,4 +1,6 @@
'use strict'
var util = require('./util')
var BN = require('ethereumjs-util').BN
function ArrayType (underlyingType, arraySize) {
this.typeName = 'array'
@ -19,7 +21,42 @@ function ArrayType (underlyingType, arraySize) {
}
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

@ -1,4 +1,5 @@
'use strict'
var util = require('./util')
function Struct (memberDetails) {
this.storageSlots = memberDetails.storageSlots
@ -12,7 +13,7 @@ Struct.prototype.decodeFromStorage = function (location, storageContent) {
this.members.map(function (item, i) {
var globalLocation = {
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)
})

@ -34,15 +34,21 @@ function readFromStorage (slot, storageContent) {
return extractSlotValue(storageContent[slot], storageBytes, location)
},
dynamicTypePointer: function getDynamicPointer (location) {
var remoteSlot = formatSlot(location.slot)
dynamicTypePointer: function (slot) {
var remoteSlot = toLongHex(slot)
var key = ethutil.sha3(remoteSlot)
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))
}
@ -74,6 +80,21 @@ function extractHexByteSlice (slotValue, byteLength, offsetFromLSB) {
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.
*

@ -11,6 +11,20 @@ module.exports = {
int32 i32;
}
intStruct intStructDec;
int64[7] i5;
int64[] idyn5;
int32[][4] dyn1;
int32[][4][] dyn2;
struct simpleStruct {
int8 i8;
string str;
}
simpleStruct[][3] arrayStruct;
function structArrayStorage () {
intStructDec.i8 = 32;
intStructDec.i16 = -54;
@ -18,12 +32,173 @@ module.exports = {
intStructDec.i256 = -1243565465756;
intStructDec.ui16 = 34556;
intStructDec.i32 = -345446546;
i5[0] = -2134;
i5[1] = 345;
i5[2] = -3246;
i5[3] = 4357;
i5[4] = 324;
i5[5] = -2344;
i5[6] = 3254;
idyn5.length = 9;
idyn5[0] = -2134;
idyn5[1] = 345;
idyn5[2] = -3246;
idyn5[3] = 4357;
idyn5[4] = 324;
idyn5[5] = -2344;
idyn5[6] = 3254;
idyn5[7] = -254;
idyn5[8] = -2354;
dyn1[0].length = 1;
dyn1[1].length = 3;
dyn1[2].length = 10;
dyn1[3].length = 2;
dyn1[0][0] = 3;
dyn1[1][0] = 12;
dyn1[1][1] = -12;
dyn1[1][2] = -1234;
dyn1[2][0] = 1;
dyn1[2][1] = 12;
dyn1[2][2] = 1235;
dyn1[2][3] = -12;
dyn1[2][4] = -123456;
dyn1[2][5] = -23435435;
dyn1[2][6] = 543543;
dyn1[2][7] = 2;
dyn1[2][8] = -1;
dyn1[2][9] = 232432;
dyn1[3][0] = 232432;
dyn1[3][1] = 232432;
dyn2.length = 2;
dyn2[0][0].length = 3;
dyn2[0][1].length = 3;
dyn2[0][2].length = 3;
dyn2[0][3].length = 3;
dyn2[1][0].length = 3;
dyn2[1][1].length = 3;
dyn2[1][2].length = 3;
dyn2[1][3].length = 3;
dyn2[0][0][0] = 23;
dyn2[0][0][1] = -23;
dyn2[0][0][2] = -28;
dyn2[0][1][0] = 23;
dyn2[0][1][1] = -23;
dyn2[0][1][2] = -28;
dyn2[0][2][0] = 23;
dyn2[0][2][1] = -23;
dyn2[0][2][2] = -28;
dyn2[0][3][0] = 23;
dyn2[0][3][1] = -23;
dyn2[0][3][2] = -28;
dyn2[1][0][0] = 23;
dyn2[1][0][1] = -23;
dyn2[1][0][2] = -28;
dyn2[1][1][0] = 23;
dyn2[1][1][1] = -23;
dyn2[1][1][2] = -28;
dyn2[1][2][0] = 23;
dyn2[1][2][1] = -23;
dyn2[1][2][2] = -28;
dyn2[1][3][0] = 23;
dyn2[1][3][1] = -23;
dyn2[1][3][2] = -28;
arrayStruct[0].length = 2;
arrayStruct[1].length = 1;
arrayStruct[2].length = 3;
arrayStruct[0][0].i8 = 34;
arrayStruct[0][0].str = 'test_str_short';
arrayStruct[0][1].i8 = -123;
arrayStruct[0][1].str = 'test_str_long test_str_lo ngtest_str_longtest_str_ longtest_str_longtest_ str_longtest_str_l ongtest_str_long';
arrayStruct[1][0].i8 = 50;
arrayStruct[1][0].str = 'test_str_short';
arrayStruct[2][0].i8 = 60;
arrayStruct[2][0].str = 'test_str_short';
arrayStruct[2][1].i8 = 84;
arrayStruct[2][1].str = 'test_str_long test_str_lo ngtest_str_longtest_str_ longtest_str_longtest_ str_longtest_str_l ongtest_str_long';
arrayStruct[2][2].i8 = -34;
arrayStruct[2][2].str = 'test_str_short';
}
}
`,
storage: {
'0x0000000000000000000000000000000000000000000000000000000000000000': '0x0000000000000000000000000000000000000000000000000000000080ffca20',
'0x0000000000000000000000000000000000000000000000000000000000000001': '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffede75b8df64',
'0x0000000000000000000000000000000000000000000000000000000000000002': '0x0000000000000000000000000000000000000000000000000000eb68e76e86fc'
'0x0000000000000000000000000000000000000000000000000000000000000002': '0x0000000000000000000000000000000000000000000000000000eb68e76e86fc',
'0x0000000000000000000000000000000000000000000000000000000000000003': '0x0000000000001105fffffffffffff3520000000000000159fffffffffffff7aa',
'0x0000000000000000000000000000000000000000000000000000000000000004': '0x00000000000000000000000000000cb6fffffffffffff6d80000000000000144',
'0x0000000000000000000000000000000000000000000000000000000000000005': '0x0000000000000000000000000000000000000000000000000000000000000009',
'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0': '0x0000000000001105fffffffffffff3520000000000000159fffffffffffff7aa',
'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db1': '0xffffffffffffff020000000000000cb6fffffffffffff6d80000000000000144',
'0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db2': '0x000000000000000000000000000000000000000000000000fffffffffffff6ce',
'0x0000000000000000000000000000000000000000000000000000000000000006': '0x0000000000000000000000000000000000000000000000000000000000000001',
'0x0000000000000000000000000000000000000000000000000000000000000007': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0x0000000000000000000000000000000000000000000000000000000000000008': '0x000000000000000000000000000000000000000000000000000000000000000a',
'0x0000000000000000000000000000000000000000000000000000000000000009': '0x0000000000000000000000000000000000000000000000000000000000000002',
'0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688': '0x0000000000000000000000000000000000000000fffffb2efffffff40000000c',
'0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3': '0x0000000200084b37fe9a6755fffe1dc0fffffff4000004d30000000c00000001',
'0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee4': '0x00000000000000000000000000000000000000000000000000038bf0ffffffff',
'0x6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af': '0x00000000000000000000000000000000000000000000000000038bf000038bf0',
'0x000000000000000000000000000000000000000000000000000000000000000a': '0x0000000000000000000000000000000000000000000000000000000000000002',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a9': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2aa': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ab': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ac': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ad': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2ae': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2af': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0x410c2796757c1866e144712b649ab035b22d7295530f125d2b7bc17fa7b793b5': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0x06b493c1ca289c5326ef56c162cd187bf96c737c2c9bbda318cc345be15042af': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0x7a0b543a77c72a2154fae01417d93ab4a7f07c9a6bbce5febfeb9904a41b7914': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0x5370eae143cc2f6260640bd734b0cdaf587bbcfc81362df39d56d5a29a7e663b': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0xd5211e5652076f058928f5b24e1816690291c298b337ea927f8d0f3aabb8a05a': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0xf232dee5d9edbb879fab95c81a3867fe42b8d79b05e9c99336c5297487f94e8d': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0x8a82e6d20ae2c2a82dd8e575dac6354ce964fd35e3d1cdb79bb1757c6a7675b6': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0xa9e6724ab7d0ccf2de69222bc5703c9df2049038736e6d57f437315272b76a3a': '0x0000000000000000000000000000000000000000ffffffe4ffffffe900000017',
'0x000000000000000000000000000000000000000000000000000000000000000b': '0x0000000000000000000000000000000000000000000000000000000000000002',
'0x000000000000000000000000000000000000000000000000000000000000000c': '0x0000000000000000000000000000000000000000000000000000000000000001',
'0x000000000000000000000000000000000000000000000000000000000000000d': '0x0000000000000000000000000000000000000000000000000000000000000003',
'0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9': '0x0000000000000000000000000000000000000000000000000000000000000022',
'0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dba': '0x746573745f7374725f73686f727400000000000000000000000000000000001c',
'0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb': '0x0000000000000000000000000000000000000000000000000000000000000085',
'0x0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbc': '0x00000000000000000000000000000000000000000000000000000000000000db',
'0x40abea1508c7557b93b3e219e777ce8530b60f9f8452ef1c627dbc62b53708fc': '0x746573745f7374725f6c6f6e6720746573745f7374725f6c6f206e6774657374',
'0x40abea1508c7557b93b3e219e777ce8530b60f9f8452ef1c627dbc62b53708fd': '0x5f7374725f6c6f6e67746573745f7374725f206c6f6e67746573745f7374725f',
'0x40abea1508c7557b93b3e219e777ce8530b60f9f8452ef1c627dbc62b53708fe': '0x6c6f6e67746573745f207374725f6c6f6e67746573745f7374725f6c206f6e67',
'0x40abea1508c7557b93b3e219e777ce8530b60f9f8452ef1c627dbc62b53708ff': '0x746573745f7374725f6c6f6e6700000000000000000000000000000000000000',
'0xdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7': '0x0000000000000000000000000000000000000000000000000000000000000032',
'0xdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c8': '0x746573745f7374725f73686f727400000000000000000000000000000000001c',
'0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5': '0x000000000000000000000000000000000000000000000000000000000000003c',
'0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb6': '0x746573745f7374725f73686f727400000000000000000000000000000000001c',
'0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb7': '0x0000000000000000000000000000000000000000000000000000000000000054',
'0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb8': '0x00000000000000000000000000000000000000000000000000000000000000db',
'0x87466a1ae97409dd9d9cd9368751b439509d8b3f8fc2bb47a4264e5d6fd4d324': '0x746573745f7374725f6c6f6e6720746573745f7374725f6c6f206e6774657374',
'0x87466a1ae97409dd9d9cd9368751b439509d8b3f8fc2bb47a4264e5d6fd4d325': '0x5f7374725f6c6f6e67746573745f7374725f206c6f6e67746573745f7374725f',
'0x87466a1ae97409dd9d9cd9368751b439509d8b3f8fc2bb47a4264e5d6fd4d326': '0x6c6f6e67746573745f207374725f6c6f6e67746573745f7374725f6c206f6e67',
'0x87466a1ae97409dd9d9cd9368751b439509d8b3f8fc2bb47a4264e5d6fd4d327': '0x746573745f7374725f6c6f6e6700000000000000000000000000000000000000',
'0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb9': '0x00000000000000000000000000000000000000000000000000000000000000de',
'0xd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eba': '0x746573745f7374725f73686f727400000000000000000000000000000000001c'
}
}

@ -209,4 +209,76 @@ function testStructArrayStorage (st) {
st.equal(decoded['intStructDec']['i256'], '-1243565465756')
st.equal(decoded['intStructDec']['ui16'], '34556')
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')
}

Loading…
Cancel
Save