fix locals decoding

pull/7/head
yann300 8 years ago
parent 32d1f4b3eb
commit f06cc737da
  1. 9
      src/solidity/types/ArrayType.js
  2. 26
      src/solidity/types/DynamicByteArray.js
  3. 19
      src/solidity/types/RefType.js
  4. 15
      src/solidity/types/StringType.js
  5. 12
      src/solidity/types/Struct.js
  6. 8
      src/solidity/types/ValueType.js

@ -57,23 +57,24 @@ class ArrayType extends RefType {
} }
decodeFromMemory (offset, memory) { decodeFromMemory (offset, memory) {
offset = 2 * offset
var ret = [] var ret = []
var length = extractLength(this, offset, memory) var length = extractLength(this, offset, memory)
if (this.arraySize === 'dynamic') { if (this.arraySize === 'dynamic') {
offset = offset + 64 offset = offset + 64
} }
this.underlyingType.location = this.location
for (var k = 0; k < length; k++) { for (var k = 0; k < length; k++) {
var contentOffset = offset var contentOffset = offset
if (this.underlyingType.typeName === 'bytes' || this.underlyingType.typeName === 'string' || this.underlyingType.typeName === 'array' || this.underlyingType.typeName === 'struct') { if (this.underlyingType.basicType === 'RefType') {
contentOffset = memory.substr(offset, 64) contentOffset = memory.substr(offset, 64)
contentOffset = 2 * parseInt(contentOffset, 16) contentOffset = parseInt(contentOffset, 16)
} }
ret.push(this.underlyingType.decodeFromMemory(contentOffset, memory)) ret.push(this.underlyingType.decode(contentOffset, memory))
offset += 64 offset += 64
} }
return ret return ret
} }
} }
function extractLength (type, offset, memory) { function extractLength (type, offset, memory) {

@ -1,15 +1,11 @@
'use strict' 'use strict'
var util = require('./util') var util = require('./util')
var BN = require('ethereumjs-util').BN var BN = require('ethereumjs-util').BN
var ValueType = require('./ValueType') var RefType = require('./RefType')
class DynamicByteArray extends ValueType { class DynamicByteArray extends RefType {
constructor () { constructor (location) {
super(1, 32, 'bytes') super(1, 32, 'bytes', location)
}
decodeValue (value) {
return '0x' + value.toUpperCase()
} }
decodeFromStorage (location, storageContent) { decodeFromStorage (location, storageContent) {
@ -39,20 +35,8 @@ class DynamicByteArray extends ValueType {
} }
} }
decodeFromStack (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return {
value: '0x',
length: '0x0'
}
} else {
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
}
}
decodeFromMemory (offset, memory) { decodeFromMemory (offset, memory) {
offset = 2 * offset
var length = memory.substr(offset, 64) var length = memory.substr(offset, 64)
length = 2 * parseInt(length, 16) length = 2 * parseInt(length, 16)
return { return {

@ -7,20 +7,31 @@ class RefType {
this.storageSlots = storageSlots this.storageSlots = storageSlots
this.storageBytes = storageBytes this.storageBytes = storageBytes
this.typeName = typeName this.typeName = typeName
this.basicType = 'RefType'
} }
decodeFromStack (stackDepth, stack, memory, storage) { decodeFromStack (stackDepth, stack, memory, storage) {
if (!storage) {
storage = {} // TODO this is a fallback, should manage properly locals store in storage
}
if (stack.length - 1 < stackDepth) { if (stack.length - 1 < stackDepth) {
return [] return { error: '<decoding failed - stack underflow ' + stackDepth + '>' }
} }
var offset = stack[stack.length - 1 - stackDepth] var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16) offset = parseInt(offset, 16)
return this.decode(offset, memory, storage)
}
decode (offset, memory, storage) {
if (!storage) {
storage = {} // TODO this is a fallback, should manage properly locals store in storage
}
if (util.storageStore(this)) { if (util.storageStore(this)) {
return this.decodeFromStorage(offset, storage) return this.decodeFromStorage({ offset: 0, slot: offset }, storage)
} else if (util.memoryStore(this)) { } else if (util.memoryStore(this)) {
return this.decodeFromMemory(offset, memory) return this.decodeFromMemory(offset, memory)
} else { } else {
return '<decoding failed - no decoder for ' + this.location + '>' return { error: '<decoding failed - no decoder for ' + this.location + '>' }
} }
} }
} }

@ -2,24 +2,18 @@
var DynamicBytes = require('./DynamicByteArray') var DynamicBytes = require('./DynamicByteArray')
class StringType extends DynamicBytes { class StringType extends DynamicBytes {
constructor () { constructor (location) {
super() super(location)
this.typeName = 'string' this.typeName = 'string'
} }
decodeValue (value) {
var decoded = super.decodeValue(value)
return format(decoded)
}
decodeFromStorage (location, storageContent) { decodeFromStorage (location, storageContent) {
var decoded = super.decodeFromStorage(location, storageContent) var decoded = super.decodeFromStorage(location, storageContent)
return format(decoded) return format(decoded)
} }
decodeFromStack (stackDepth, stack, memory) { decodeFromStack (stackDepth, stack, memory) {
var decoded = super.decodeFromStack(stackDepth, stack, memory) return super.decodeFromStack(stackDepth, stack, memory)
return format(decoded)
} }
decodeFromMemory (offset, memory) { decodeFromMemory (offset, memory) {
@ -29,6 +23,9 @@ class StringType extends DynamicBytes {
} }
function format (decoded) { function format (decoded) {
if (decoded.error) {
return decoded
}
var value = decoded.value var value = decoded.value
value = value.replace('0x', '').replace(/(..)/g, '%$1') value = value.replace('0x', '').replace(/(..)/g, '%$1')
var ret = { var ret = {

@ -21,14 +21,16 @@ class Struct extends RefType {
} }
decodeFromMemory (offset, memory) { decodeFromMemory (offset, memory) {
offset = 2 * offset
var ret = {} var ret = {}
this.members.map(function (item, i) { this.members.map((item, i) => {
var contentOffset = offset var contentOffset = offset
if (item.type.typeName === 'bytes' || item.type.typeName === 'string' || item.type.typeName === 'array' || item.type.typeName === 'struct') { if (item.type.basicType === 'RefType') {
contentOffset = memory.substr(offset, 64) contentOffset = memory.substr(contentOffset, 64)
contentOffset = 2 * parseInt(contentOffset, 16) contentOffset = parseInt(contentOffset, 16)
} }
var member = item.type.decodeFromMemory(contentOffset, memory) item.type.location = this.location
var member = item.type.decode(contentOffset, memory)
ret[item.name] = member ret[item.name] = member
offset += 64 offset += 64
}) })

@ -6,6 +6,7 @@ class ValueType {
this.storageSlots = storageSlots this.storageSlots = storageSlots
this.storageBytes = storageBytes this.storageBytes = storageBytes
this.typeName = typeName this.typeName = typeName
this.basicType = 'ValueType'
} }
decodeFromStorage (location, storageContent) { decodeFromStorage (location, storageContent) {
@ -22,9 +23,14 @@ class ValueType {
} }
decodeFromMemory (offset, memory) { decodeFromMemory (offset, memory) {
var value = memory.substr(offset, 64) var value = memory.substr(2 * offset, 64)
return this.decodeValue(util.extractHexByteSlice(value, this.storageBytes, 0)) return this.decodeValue(util.extractHexByteSlice(value, this.storageBytes, 0))
} }
decode (offset, memory) {
offset = offset / 2
return this.decodeFromMemory(offset, memory)
}
} }
module.exports = ValueType module.exports = ValueType

Loading…
Cancel
Save