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) { DynamicByteArray.prototype.decodeFromStorage = function (location, storageContent) {
var value = util.extractHexByte(location, storageContent, this.storageBytes) var value = util.extractHexByte(location, storageContent, this.storageBytes)
var bn = new BN(value.substr(62, 2), 16) var bn = new BN(value, 16)
bn = bn.toString(2) if (bn.testn(0)) {
if (bn[bn.length - 1] === '1') { var length = bn.div(new BN(2))
var key = util.sha3(location.slot) var dataPos = new BN(util.sha3(location.slot).replace('0x', ''), 16)
var ret = '' var ret = ''
var currentSlot = storageContent[key] var currentSlot = util.readFromStorage(dataPos, storageContent)
key = new BN(key.replace('0x', ''), 16) while (length.gt(ret.length) && ret.length < 32000) {
while (currentSlot) {
currentSlot = currentSlot.replace('0x', '') currentSlot = currentSlot.replace('0x', '')
ret += currentSlot ret += currentSlot
key = key.add(new BN(1)) dataPos = dataPos.add(new BN(1))
currentSlot = storageContent['0x' + key.toString(16)] currentSlot = util.readFromStorage(dataPos, storageContent)
}
return {
value: '0x' + ret.replace(/(00)+$/, ''),
length: '0x' + length.toString(16)
} }
return '0x' + ret.replace(/(00)+$/, '')
} else { } else {
var size = value.substr(value.length - 2, 2) var size = parseInt(value.substr(value.length - 2, 2), 16) / 2
return '0x' + value.substr(0, parseInt(size, 16)) 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) { 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 = '' var ret = ''
value = value.replace('0x', '') value = value.replace('0x', '')
for (var k = 0; k < value.length; k += 2) { 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)) var str = String.fromCharCode(parseInt(raw, 16))
ret += str ret += str
} }
return ret return {
value: ret,
length: decoded.length
}
} }
module.exports = StringType module.exports = StringType

@ -20,31 +20,32 @@ function decodeInt (location, storageContent, byteLength, signed) {
} }
function readFromStorage (slot, storageContent) { function readFromStorage (slot, storageContent) {
var ret
var hexSlot = ethutil.bufferToHex(slot) var hexSlot = ethutil.bufferToHex(slot)
if (storageContent[hexSlot] !== undefined) { if (storageContent[hexSlot] !== undefined) {
return storageContent[hexSlot] ret = storageContent[hexSlot].replace(/^0x/, '')
} else { } else {
hexSlot = ethutil.bufferToHex(ethutil.setLengthLeft(slot, 32)) hexSlot = ethutil.bufferToHex(ethutil.setLengthLeft(slot, 32))
if (storageContent[hexSlot] !== undefined) { if (storageContent[hexSlot] !== undefined) {
return storageContent[hexSlot] ret = storageContent[hexSlot].replace(/^0x/, '')
} else { } 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. * @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} 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 * @param {Int} offsetFromLSB - byte distance from the right end slot value to the right end of the byte slice
*/ */
function extractHexByteSlice (slotValue, byteLength, offsetFromLSB) { 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 var offset = slotValue.length - 2 * offsetFromLSB - 2 * byteLength
return slotValue.substr(offset, 2 * byteLength) return slotValue.substr(offset, 2 * byteLength)
} }

@ -59,7 +59,8 @@ function testByteStorage (st) {
st.equal(decoded['b1'], false) st.equal(decoded['b1'], false)
st.equal(decoded['a1'], '0xFE350F199F244AC9A79038D254400B632A633225') st.equal(decoded['a1'], '0xFE350F199F244AC9A79038D254400B632A633225')
st.equal(decoded['b2'], true) 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['stab'], '0x1')
st.equal(decoded['stab1'], '0x12') st.equal(decoded['stab1'], '0x12')
st.equal(decoded['stab2'], '0x1579') st.equal(decoded['stab2'], '0x1579')
@ -94,15 +95,16 @@ function testByteStorage (st) {
st.equal(decoded['stab31'], '0x3245435123') st.equal(decoded['stab31'], '0x3245435123')
st.equal(decoded['stab32'], '0x324324423432543543AB') st.equal(decoded['stab32'], '0x324324423432543543AB')
st.equal(decoded['enumDec'], 'e240') st.equal(decoded['enumDec'], 'e240')
st.equal(decoded['str1'], 'short') st.equal(decoded['str1'].value, '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['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') decoded = stateDecoder.solidityState({}, output.sources, 'byteStorage')
st.equal(decoded['b1'], false) st.equal(decoded['b1'], false)
st.equal(decoded['a1'], '0x0000000000000000000000000000000000000000') st.equal(decoded['a1'], '0x0000000000000000000000000000000000000000')
st.equal(decoded['b2'], false) 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['stab'], '0x')
st.equal(decoded['stab1'], '0x') st.equal(decoded['stab1'], '0x')
st.equal(decoded['stab2'], '0x') st.equal(decoded['stab2'], '0x')
@ -137,8 +139,10 @@ function testByteStorage (st) {
st.equal(decoded['stab31'], '0x') st.equal(decoded['stab31'], '0x')
st.equal(decoded['stab32'], '0x') st.equal(decoded['stab32'], '0x')
st.equal(decoded['enumDec'], 'e0') st.equal(decoded['enumDec'], 'e0')
st.equal(decoded['str1'], '') st.equal(decoded['str1'].length, '0x0')
st.equal(decoded['str2'], '') st.equal(decoded['str2'].length, '0x0')
st.equal(decoded['str1'].value, '')
st.equal(decoded['str2'].value, '')
} }
function shrinkStorage (storage) { function shrinkStorage (storage) {

Loading…
Cancel
Save