Commit e7c45d29 authored by yann300's avatar yann300

use es6 class for type

parent d2da5fd6
'use strict'
var util = require('./util')
var ValueType = require('./ValueType')
function Address () {
this.storageSlots = 1
this.storageBytes = 20
this.typeName = 'address'
}
class Address extends ValueType {
constructor () {
super(1, 20, 'address')
}
Address.prototype.decodeFromStorage = function (location, storageContent) {
var value = util.extractHexValue(location, storageContent, this.storageBytes)
return '0x' + value.toUpperCase()
}
decodeFromStorage (location, storageContent) {
var value = util.extractHexValue(location, storageContent, this.storageBytes)
return '0x' + value.toUpperCase()
}
Address.prototype.decodeLocals = function (stackDepth, stack, memory) {
if (stackDepth >= stack.length) {
return '0x0000000000000000000000000000000000000000'
} else {
return '0x' + util.extractHexByteSlice(stack[stack.length - 1 - stackDepth], this.storageBytes, 0)
decodeLocals (stackDepth, stack, memory) {
if (stackDepth >= stack.length) {
return '0x0000000000000000000000000000000000000000'
} else {
return '0x' + util.extractHexByteSlice(stack[stack.length - 1 - stackDepth], this.storageBytes, 0)
}
}
}
Address.prototype.decodeFromMemory = function (offset, memory) {
var value = memory.substr(offset, 64)
value = util.extractHexByteSlice(value, this.storageBytes, 0)
return value
decodeFromMemory (offset, memory) {
var value = memory.substr(offset, 64)
value = util.extractHexByteSlice(value, this.storageBytes, 0)
return value
}
}
module.exports = Address
......@@ -2,84 +2,88 @@
var util = require('./util')
var BN = require('ethereumjs-util').BN
function ArrayType (underlyingType, arraySize) {
this.typeName = 'array'
this.storageBytes = 32
this.underlyingType = underlyingType
this.arraySize = arraySize
this.storageSlots = null
if (arraySize === 'dynamic') {
this.storageSlots = 1
} else {
if (underlyingType.storageBytes < 32) {
var itemPerSlot = Math.floor(32 / underlyingType.storageBytes)
this.storageSlots = Math.ceil(arraySize / itemPerSlot)
class ArrayType {
constructor (underlyingType, arraySize) {
this.typeName = 'array'
this.storageBytes = 32
this.underlyingType = underlyingType
this.arraySize = arraySize
this.storageSlots = null
if (arraySize === 'dynamic') {
this.storageSlots = 1
} else {
this.storageSlots = arraySize * underlyingType.storageSlots
if (underlyingType.storageBytes < 32) {
var itemPerSlot = Math.floor(32 / underlyingType.storageBytes)
this.storageSlots = Math.ceil(arraySize / itemPerSlot)
} else {
this.storageSlots = arraySize * underlyingType.storageSlots
}
}
}
}
ArrayType.prototype.decodeFromStorage = function (location, storageContent) {
var ret = []
var size = null
var slotValue = util.extractHexValue(location, storageContent, this.storageBytes)
var currentLocation = {
offset: 0,
slot: location.slot
}
if (this.arraySize === 'dynamic') {
size = util.toBN('0x' + slotValue)
currentLocation.slot = util.sha3(location.slot)
} else {
size = new BN(this.arraySize)
}
var k = util.toBN(0)
for (; k.lt(size) && k.ltn(300); k.iaddn(1)) {
ret.push(this.underlyingType.decodeFromStorage(currentLocation, storageContent))
if (this.underlyingType.storageSlots === 1 && location.offset + this.underlyingType.storageBytes <= 32) {
currentLocation.offset += this.underlyingType.storageBytes
if (currentLocation.offset + this.underlyingType.storageBytes > 32) {
decodeFromStorage (location, storageContent) {
var ret = []
var size = null
var slotValue = util.extractHexValue(location, storageContent, this.storageBytes)
var currentLocation = {
offset: 0,
slot: location.slot
}
if (this.arraySize === 'dynamic') {
size = util.toBN('0x' + slotValue)
currentLocation.slot = util.sha3(location.slot)
} else {
size = new BN(this.arraySize)
}
var k = util.toBN(0)
for (; k.lt(size) && k.ltn(300); k.iaddn(1)) {
ret.push(this.underlyingType.decodeFromStorage(currentLocation, storageContent))
if (this.underlyingType.storageSlots === 1 && location.offset + this.underlyingType.storageBytes <= 32) {
currentLocation.offset += this.underlyingType.storageBytes
if (currentLocation.offset + this.underlyingType.storageBytes > 32) {
currentLocation.offset = 0
currentLocation.slot = '0x' + util.add(currentLocation.slot, 1).toString(16)
}
} else {
currentLocation.slot = '0x' + util.add(currentLocation.slot, this.underlyingType.storageSlots).toString(16)
currentLocation.offset = 0
currentLocation.slot = '0x' + util.add(currentLocation.slot, 1).toString(16)
}
} else {
currentLocation.slot = '0x' + util.add(currentLocation.slot, this.underlyingType.storageSlots).toString(16)
currentLocation.offset = 0
}
return {
value: ret,
length: '0x' + size.toString(16)
}
}
return {
value: ret,
length: '0x' + size.toString(16)
}
}
ArrayType.prototype.decodeLocals = function (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return []
} else { // TODO manage decoding locals from storage
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
decodeLocals (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return []
} else { // TODO manage decoding locals from storage
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
}
}
}
ArrayType.prototype.decodeFromMemory = function (offset, memory) {
var ret = []
var length = extractLength(this, offset, memory)
if (this.arraySize === 'dynamic') {
offset = offset + 64
}
for (var k = 0; k < length; k++) {
var contentOffset = offset
if (this.underlyingType.typeName === 'bytes' || this.underlyingType.typeName === 'string' || this.underlyingType.typeName === 'array' || this.underlyingType.typeName === 'struct') {
contentOffset = memory.substr(offset, 64)
contentOffset = 2 * parseInt(contentOffset, 16)
decodeFromMemory (offset, memory) {
var ret = []
var length = extractLength(this, offset, memory)
if (this.arraySize === 'dynamic') {
offset = offset + 64
}
for (var k = 0; k < length; k++) {
var contentOffset = offset
if (this.underlyingType.typeName === 'bytes' || this.underlyingType.typeName === 'string' || this.underlyingType.typeName === 'array' || this.underlyingType.typeName === 'struct') {
contentOffset = memory.substr(offset, 64)
contentOffset = 2 * parseInt(contentOffset, 16)
}
ret.push(this.underlyingType.decodeFromMemory(contentOffset, memory))
offset += 64
}
ret.push(this.underlyingType.decodeFromMemory(contentOffset, memory))
offset += 64
return ret
}
return ret
}
function extractLength (type, offset, memory) {
......
'use strict'
var util = require('./util')
var ValueType = require('./ValueType')
function Bool () {
this.storageSlots = 1
this.storageBytes = 1
this.typeName = 'bool'
class Bool extends ValueType {
constructor () {
super(1, 1, 'bool')
}
}
Bool.prototype.decodeFromStorage = function (location, storageContent) {
......
'use strict'
var util = require('./util')
var BN = require('ethereumjs-util').BN
var ValueType = require('./ValueType')
function DynamicByteArray () {
this.storageSlots = 1
this.storageBytes = 32
this.typeName = 'bytes'
}
DynamicByteArray.prototype.decodeFromStorage = function (location, storageContent) {
var value = util.extractHexValue(location, storageContent, this.storageBytes)
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 = util.readFromStorage(dataPos, storageContent)
while (length.gt(ret.length) && ret.length < 32000) {
currentSlot = currentSlot.replace('0x', '')
ret += currentSlot
dataPos = dataPos.add(new BN(1))
currentSlot = util.readFromStorage(dataPos, storageContent)
}
return {
value: '0x' + ret.replace(/(00)+$/, ''),
length: '0x' + length.toString(16)
}
} else {
var size = parseInt(value.substr(value.length - 2, 2), 16) / 2
return {
value: '0x' + value.substr(0, size * 2),
length: '0x' + size.toString(16)
}
class DynamicByteArray extends ValueType {
constructor () {
super(1, 32, 'bytes')
}
}
DynamicByteArray.prototype.decodeLocals = function (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return {
value: '0x',
length: '0x0'
decodeFromStorage (location, storageContent) {
var value = util.extractHexValue(location, storageContent, this.storageBytes)
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 = util.readFromStorage(dataPos, storageContent)
while (length.gt(ret.length) && ret.length < 32000) {
currentSlot = currentSlot.replace('0x', '')
ret += currentSlot
dataPos = dataPos.add(new BN(1))
currentSlot = util.readFromStorage(dataPos, storageContent)
}
return {
value: '0x' + ret.replace(/(00)+$/, ''),
length: '0x' + length.toString(16)
}
} else {
var size = parseInt(value.substr(value.length - 2, 2), 16) / 2
return {
value: '0x' + value.substr(0, size * 2),
length: '0x' + size.toString(16)
}
}
} else {
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
}
}
DynamicByteArray.prototype.decodeFromMemory = function (offset, memory) {
var length = memory.substr(offset, 64)
length = 2 * parseInt(length, 16)
return {
length: '0x' + length.toString(16),
value: '0x' + memory.substr(offset + 64, length)
decodeLocals (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)
}
}
}
DynamicByteArray.prototype.decodeLocals = function (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
decodeFromMemory (offset, memory) {
var length = memory.substr(offset, 64)
length = 2 * parseInt(length, 16)
return {
value: '0x',
length: '0x0'
length: '0x' + length.toString(16),
value: '0x' + memory.substr(offset + 64, length)
}
} else {
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
}
}
DynamicByteArray.prototype.decodeFromMemory = function (offset, memory) {
var length = memory.substr(offset, 64)
length = 2 * parseInt(length, 16)
return {
length: '0x' + length.toString(16),
value: '0x' + memory.substr(offset + 64, length)
}
}
......
'use strict'
var util = require('./util')
var ValueType = require('./ValueType')
function Enum (enumDef) {
this.enumDef = enumDef
this.typeName = 'enum'
this.storageSlots = 1
var length = enumDef.children.length
this.storageBytes = 0
while (length > 1) {
length = length / 256
this.storageBytes++
class Enum extends ValueType {
constructor (enumDef) {
var storageBytes = 0
var length = enumDef.children.length
while (length > 1) {
length = length / 256
storageBytes++
}
super(1, storageBytes, 'enum')
this.enumDef = enumDef
}
}
......
'use strict'
var util = require('./util')
var ValueType = require('./ValueType')
function FixedByteArray (storageBytes) {
this.storageSlots = 1
this.storageBytes = storageBytes
this.typeName = 'bytesX'
}
class FixedByteArray extends ValueType {
constructor (storageBytes) {
super(1, storageBytes, 'bytesX')
}
FixedByteArray.prototype.decodeFromStorage = function (location, storageContent) {
var value = util.extractHexValue(location, storageContent, this.storageBytes)
return '0x' + value.toUpperCase()
}
decodeFromStorage (location, storageContent) {
var value = util.extractHexValue(location, storageContent, this.storageBytes)
return '0x' + value.toUpperCase()
}
FixedByteArray.prototype.decodeLocals = function (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return '0x'
} else {
var value = stack[stack.length - 1 - stackDepth]
return '0x' + value.substr(2, 2 * this.storageBytes).toUpperCase()
decodeLocals (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return '0x'
} else {
var value = stack[stack.length - 1 - stackDepth]
return '0x' + value.substr(2, 2 * this.storageBytes).toUpperCase()
}
}
}
FixedByteArray.prototype.decodeFromMemory = function (offset, memory) {
var value = memory.substr(offset, 64)
return util.extractHexByteSlice(value, this.storageBytes, 0).toUpperCase()
decodeFromMemory (offset, memory) {
var value = memory.substr(offset, 64)
return util.extractHexByteSlice(value, this.storageBytes, 0).toUpperCase()
}
}
module.exports = FixedByteArray
'use strict'
var util = require('./util')
var ValueType = require('./ValueType')
function Int (storageBytes) {
this.storageSlots = 1
this.storageBytes = storageBytes
this.typeName = 'int'
class Int extends ValueType {
constructor (storageBytes) {
super(1, storageBytes, 'int')
}
}
Int.prototype.decodeFromStorage = function (location, storageContent) {
......
'use strict'
function Mapping () {
this.storageSlots = 1
this.storageBytes = 32
this.typeName = 'mapping'
}
class Mapping {
constructor () {
this.storageSlots = 1
this.storageBytes = 32
this.typeName = 'mapping'
}
Mapping.prototype.decodeFromStorage = function (location, storageContent) {
return '<not implemented>'
decodeFromStorage (location, storageContent) {
return '<not implemented>'
}
}
module.exports = Mapping
'use strict'
var DynamicBytes = require('./DynamicByteArray')
function StringType () {
this.storageSlots = 1
this.storageBytes = 32
this.typeName = 'string'
this.dynamicBytes = new DynamicBytes()
}
StringType.prototype.decodeFromStorage = function (location, storageContent) {
var decoded = this.dynamicBytes.decodeFromStorage(location, storageContent)
return format(decoded)
}
class StringType extends DynamicBytes {
constructor () {
super()
this.typeName = 'string'
}
StringType.prototype.decodeLocals = function (stackDepth, stack, memory) {
var decoded = this.dynamicBytes.decodeLocals(stackDepth, stack, memory)
return format(decoded)
}
decodeFromStorage (location, storageContent) {
var decoded = super.decodeFromStorage(location, storageContent)
return format(decoded)
}
StringType.prototype.decodeFromMemory = function (offset, memory) {
var decoded = this.dynamicBytes.decodeFromMemory(offset, memory)
return format(decoded)
}
decodeLocals (stackDepth, stack, memory) {
var decoded = super.decodeLocals(stackDepth, stack, memory)
return format(decoded)
}
StringType.prototype.decodeFromMemory = function (offset, memory) {
var decoded = this.dynamicBytes.decodeFromMemory(offset, memory)
return format(decoded)
decodeFromMemory (offset, memory) {
var decoded = super.decodeFromMemory(offset, memory)
return format(decoded)
}
}
function format (decoded) {
......
'use strict'
var util = require('./util')
function Struct (memberDetails) {
this.storageSlots = memberDetails.storageSlots
this.storageBytes = 32
this.members = memberDetails.members
this.typeName = 'struct'
}
Struct.prototype.decodeFromStorage = function (location, storageContent) {
var ret = {}
this.members.map(function (item, i) {
var globalLocation = {
offset: location.offset + item.location.offset,
slot: util.add(location.slot, item.location.slot)
}
ret[item.name] = item.type.decodeFromStorage(globalLocation, storageContent)
})
return ret
}
class Struct {
constructor (memberDetails) {
this.storageSlots = memberDetails.storageSlots
this.storageBytes = 32
this.members = memberDetails.members
this.typeName = 'struct'
}
Struct.prototype.decodeLocals = function (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return {}
} else { // TODO manage decoding locals from storage
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
decodeFromStorage (location, storageContent) {
var ret = {}
this.members.map(function (item, i) {
var globalLocation = {
offset: location.offset + item.location.offset,
slot: util.add(location.slot, item.location.slot)
}
ret[item.name] = item.type.decodeFromStorage(globalLocation, storageContent)
})
return ret
}
}
Struct.prototype.decodeFromMemory = function (offset, memory) {
var ret = {}
this.members.map(function (item, i) {
var contentOffset = offset
if (item.type.typeName === 'bytes' || item.type.typeName === 'string' || item.type.typeName === 'array' || item.type.typeName === 'struct') {
contentOffset = memory.substr(offset, 64)
contentOffset = 2 * parseInt(contentOffset, 16)
decodeLocals (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return {}
} else { // TODO manage decoding locals from storage
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
}
var member = item.type.decodeFromMemory(contentOffset, memory)
ret[item.name] = member
offset += 64
})
return ret
}
Struct.prototype.decodeLocals = function (stackDepth, stack, memory) {
if (stack.length - 1 < stackDepth) {
return {}
} else { // TODO manage decoding locals from storage
var offset = stack[stack.length - 1 - stackDepth]
offset = 2 * parseInt(offset, 16)
return this.decodeFromMemory(offset, memory)
}
}
Struct.prototype.decodeFromMemory = function (offset, memory) {
var ret = {}
this.members.map(function (item, i) {
var contentOffset = offset
if (item.type.typeName === 'bytes' || item.type.typeName === 'string' || item.type.typeName === 'array' || item.type.typeName === 'struct') {
contentOffset = memory.substr(offset, 64)
contentOffset = 2 * parseInt(contentOffset, 16)
}
var member = item.type.decodeFromMemory(contentOffset, memory)
ret[item.name] = member
offset += 64
})
return ret
decodeFromMemory (offset, memory) {
var ret = {}
this.members.map(function (item, i) {
var contentOffset = offset
if (item.type.typeName === 'bytes' || item.type.typeName === 'string' || item.type.typeName === 'array' || item.type.typeName === 'struct') {
contentOffset = memory.substr(offset, 64)
contentOffset = 2 * parseInt(contentOffset, 16)
}
var member = item.type.decodeFromMemory(contentOffset, memory)
ret[item.name] = member
offset += 64
})
return ret
}
}
module.exports = Struct
'use strict'
var util = require('./util')
var ValueType = require('./ValueType')
function Uint (storageBytes) {
this.storageSlots = 1
this.storageBytes = storageBytes
this.typeName = 'uint'
class Uint extends ValueType {
constructor (storageBytes) {
super(1, storageBytes, 'uint')
}
}
Uint.prototype.decodeFromStorage = function (location, storageContent) {
......
'use strict'
class ValueType {
constructor (storageSlots, storageBytes, typeName) {
this.storageSlots = storageSlots
this.storageBytes = storageBytes
this.typeName = typeName
}
}
module.exports = ValueType
......@@ -132,7 +132,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId) {
tree.scopes[scopeId].locals[variableDeclaration.attributes.name] = {
name: variableDeclaration.attributes.name,
type: decodeInfo.parseType(variableDeclaration.attributes.type, states, contractName),
stackDepth: stack.stackDepth
stackDepth: stack.length
}
}
})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment