fix dynamic bytes

pull/7/head
yann300 8 years ago
parent 8b22007cba
commit e6f86fac08
  1. 29
      src/solidity/types/DynamicByteArray.js
  2. 8
      src/solidity/types/StringType.js
  3. 17
      src/solidity/types/util.js
  4. 16
      test/solidity/storageDecoder.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)
}
}
}

@ -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

@ -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)
}

@ -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) {

Loading…
Cancel
Save