From e6f86fac084c7042da02e014c3a5f398cc5bc644 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 28 Nov 2016 11:54:03 +0100 Subject: [PATCH] fix dynamic bytes --- src/solidity/types/DynamicByteArray.js | 29 +++++++++++++++----------- src/solidity/types/StringType.js | 8 +++++-- src/solidity/types/util.js | 17 ++++++++------- test/solidity/storageDecoder.js | 16 ++++++++------ 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/solidity/types/DynamicByteArray.js b/src/solidity/types/DynamicByteArray.js index f8e2c9cd7c..934ff58d4a 100644 --- a/src/solidity/types/DynamicByteArray.js +++ b/src/solidity/types/DynamicByteArray.js @@ -10,23 +10,28 @@ function DynamicByteArray () { DynamicByteArray.prototype.decodeFromStorage = function (location, storageContent) { var value = util.extractHexByte(location, storageContent, this.storageBytes) - var bn = new BN(value.substr(62, 2), 16) - bn = bn.toString(2) - if (bn[bn.length - 1] === '1') { - var key = util.sha3(location.slot) + var bn = new BN(value, 16) + if (bn.testn(0)) { + var length = bn.div(new BN(2)) + var dataPos = new BN(util.sha3(location.slot).replace('0x', ''), 16) var ret = '' - var currentSlot = storageContent[key] - key = new BN(key.replace('0x', ''), 16) - while (currentSlot) { + var currentSlot = util.readFromStorage(dataPos, storageContent) + while (length.gt(ret.length) && ret.length < 32000) { currentSlot = currentSlot.replace('0x', '') ret += currentSlot - key = key.add(new BN(1)) - currentSlot = storageContent['0x' + key.toString(16)] + dataPos = dataPos.add(new BN(1)) + currentSlot = util.readFromStorage(dataPos, storageContent) + } + return { + value: '0x' + ret.replace(/(00)+$/, ''), + length: '0x' + length.toString(16) } - return '0x' + ret.replace(/(00)+$/, '') } else { - var size = value.substr(value.length - 2, 2) - return '0x' + value.substr(0, parseInt(size, 16)) + var size = parseInt(value.substr(value.length - 2, 2), 16) / 2 + return { + value: '0x' + value.substr(0, size * 2), + length: '0x' + size.toString(16) + } } } diff --git a/src/solidity/types/StringType.js b/src/solidity/types/StringType.js index 36ee20707b..532665dfc4 100644 --- a/src/solidity/types/StringType.js +++ b/src/solidity/types/StringType.js @@ -9,7 +9,8 @@ function StringType () { } StringType.prototype.decodeFromStorage = function (location, storageContent) { - var value = this.dynamicBytes.decodeFromStorage(location, storageContent) + var decoded = this.dynamicBytes.decodeFromStorage(location, storageContent) + var value = decoded.value var ret = '' value = value.replace('0x', '') for (var k = 0; k < value.length; k += 2) { @@ -17,7 +18,10 @@ StringType.prototype.decodeFromStorage = function (location, storageContent) { var str = String.fromCharCode(parseInt(raw, 16)) ret += str } - return ret + return { + value: ret, + length: decoded.length + } } module.exports = StringType diff --git a/src/solidity/types/util.js b/src/solidity/types/util.js index cdb2077a8a..8855fa40a3 100644 --- a/src/solidity/types/util.js +++ b/src/solidity/types/util.js @@ -20,31 +20,32 @@ function decodeInt (location, storageContent, byteLength, signed) { } function readFromStorage (slot, storageContent) { + var ret var hexSlot = ethutil.bufferToHex(slot) if (storageContent[hexSlot] !== undefined) { - return storageContent[hexSlot] + ret = storageContent[hexSlot].replace(/^0x/, '') } else { hexSlot = ethutil.bufferToHex(ethutil.setLengthLeft(slot, 32)) if (storageContent[hexSlot] !== undefined) { - return storageContent[hexSlot] + ret = storageContent[hexSlot].replace(/^0x/, '') } else { - return '0x0' + ret = '0000000000000000000000000000000000000000000000000000000000000000' } } + if (ret.length < 64) { + ret = (new Array(64 - ret.length + 1).join('0')) + ret + } + return ret } /** * @returns a hex encoded byte slice of length @arg byteLength from inside @arg slotValue. * - * @param {String} slotValue - right aligned hex encoded value to extract the byte slice from (can have 0x prefix) + * @param {String} slotValue - hex encoded value to extract the byte slice from * @param {Int} byteLength - Length of the byte slice to extract * @param {Int} offsetFromLSB - byte distance from the right end slot value to the right end of the byte slice */ function extractHexByteSlice (slotValue, byteLength, offsetFromLSB) { - slotValue = slotValue.replace('0x', '') - if (slotValue.length < 64) { - slotValue = (new Array(64 - slotValue.length + 1).join('0')) + slotValue - } var offset = slotValue.length - 2 * offsetFromLSB - 2 * byteLength return slotValue.substr(offset, 2 * byteLength) } diff --git a/test/solidity/storageDecoder.js b/test/solidity/storageDecoder.js index 646512557f..f4ef31676f 100644 --- a/test/solidity/storageDecoder.js +++ b/test/solidity/storageDecoder.js @@ -59,7 +59,8 @@ function testByteStorage (st) { st.equal(decoded['b1'], false) st.equal(decoded['a1'], '0xFE350F199F244AC9A79038D254400B632A633225') st.equal(decoded['b2'], true) - st.equal(decoded['dynb1'], '0x64796e616d69636279746573') + st.equal(decoded['dynb1'].value, '0x64796e616d69636279746573') + st.equal(decoded['dynb1'].length, '0xc') st.equal(decoded['stab'], '0x1') st.equal(decoded['stab1'], '0x12') st.equal(decoded['stab2'], '0x1579') @@ -94,15 +95,16 @@ function testByteStorage (st) { st.equal(decoded['stab31'], '0x3245435123') st.equal(decoded['stab32'], '0x324324423432543543AB') st.equal(decoded['enumDec'], 'e240') - st.equal(decoded['str1'], 'short') - st.equal(decoded['str2'], 'long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long') + st.equal(decoded['str1'].value, 'short') + st.equal(decoded['str2'].value, 'long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long__long') } decoded = stateDecoder.solidityState({}, output.sources, 'byteStorage') st.equal(decoded['b1'], false) st.equal(decoded['a1'], '0x0000000000000000000000000000000000000000') st.equal(decoded['b2'], false) - st.equal(decoded['dynb1'], '0x') + st.equal(decoded['dynb1'].value, '0x') + st.equal(decoded['dynb1'].length, '0x0') st.equal(decoded['stab'], '0x') st.equal(decoded['stab1'], '0x') st.equal(decoded['stab2'], '0x') @@ -137,8 +139,10 @@ function testByteStorage (st) { st.equal(decoded['stab31'], '0x') st.equal(decoded['stab32'], '0x') st.equal(decoded['enumDec'], 'e0') - st.equal(decoded['str1'], '') - st.equal(decoded['str2'], '') + st.equal(decoded['str1'].length, '0x0') + st.equal(decoded['str2'].length, '0x0') + st.equal(decoded['str1'].value, '') + st.equal(decoded['str2'].value, '') } function shrinkStorage (storage) {