diff --git a/src/solidity/types/Address.js b/src/solidity/types/Address.js index 3d94eb0922..c58e97ce62 100644 --- a/src/solidity/types/Address.js +++ b/src/solidity/types/Address.js @@ -1,4 +1,5 @@ 'use strict' +var util = require('./util') function Address () { this.storageSlots = 1 @@ -7,7 +8,7 @@ function Address () { } Address.prototype.decodeFromStorage = function (location, storageContent) { - return '' + return util.extractValue(location, storageContent, this.storageBytes) } module.exports = Address diff --git a/src/solidity/types/Bool.js b/src/solidity/types/Bool.js index 8752dc1d79..dae404b4dc 100644 --- a/src/solidity/types/Bool.js +++ b/src/solidity/types/Bool.js @@ -1,4 +1,5 @@ 'use strict' +var util = require('./util') function Bool () { this.storageSlots = 1 @@ -7,7 +8,8 @@ function Bool () { } Bool.prototype.decodeFromStorage = function (location, storageContent) { - return '' + var value = util.extractValue(location, storageContent, this.storageBytes) + return value !== '0x00' } module.exports = Bool diff --git a/src/solidity/types/DynamicByteArray.js b/src/solidity/types/DynamicByteArray.js index cbf1b618f8..89a2682f52 100644 --- a/src/solidity/types/DynamicByteArray.js +++ b/src/solidity/types/DynamicByteArray.js @@ -1,4 +1,6 @@ 'use strict' +var util = require('./util') +var BN = require('ethereumjs-util').BN function DynamicByteArray () { this.storageSlots = 1 @@ -7,7 +9,27 @@ function DynamicByteArray () { } DynamicByteArray.prototype.decodeFromStorage = function (location, storageContent) { - return '' + var value = util.extractValue(location, storageContent, this.storageBytes) + var key = util.dynamicTypePointer(location) + if (storageContent[key] && storageContent[key] !== '0x') { + var ret = '' + var length = parseInt(value) - 1 + var slots = Math.ceil(length / 64) + var currentSlot = storageContent[key] + key = new BN(key.replace('0x', ''), 16) + for (var k = 0; k < slots; k++) { + if (!currentSlot) { + break + } + ret += currentSlot.replace('0x', '') + key = key.add(new BN(1)) + currentSlot = storageContent['0x' + key.toString(16)] + } + return ret.substr(0, length) + } else { + var size = value.substr(value.length - 2, 2) + return value.substr(0, parseInt(size, 16) + 2) + } } module.exports = DynamicByteArray diff --git a/src/solidity/types/Enum.js b/src/solidity/types/Enum.js index 6c38aec83c..6aab9502f4 100644 --- a/src/solidity/types/Enum.js +++ b/src/solidity/types/Enum.js @@ -1,4 +1,5 @@ 'use strict' +var util = require('./util') function Enum (enumDef) { this.enumDef = enumDef @@ -13,7 +14,9 @@ function Enum (enumDef) { } Enum.prototype.decodeFromStorage = function (location, storageContent) { - return '' + var value = util.extractValue(location, storageContent, this.storageBytes) + value = parseInt(value) + return this.enumDef.children[value].attributes.name } module.exports = Enum diff --git a/src/solidity/types/FixedByteArray.js b/src/solidity/types/FixedByteArray.js index 6dcbb5456b..309c4384d8 100644 --- a/src/solidity/types/FixedByteArray.js +++ b/src/solidity/types/FixedByteArray.js @@ -1,4 +1,6 @@ 'use strict' +var util = require('./util') +var utileth = require('ethereumjs-util') function FixedByteArray (storageBytes) { this.storageSlots = 1 @@ -7,7 +9,8 @@ function FixedByteArray (storageBytes) { } FixedByteArray.prototype.decodeFromStorage = function (location, storageContent) { - return '' + var value = util.extractValue(location, storageContent, this.storageBytes) + return '0x' + utileth.unpad(value.replace('0x', '')).toUpperCase() } module.exports = FixedByteArray diff --git a/src/solidity/types/StringType.js b/src/solidity/types/StringType.js index 7431eed3a2..829291291a 100644 --- a/src/solidity/types/StringType.js +++ b/src/solidity/types/StringType.js @@ -1,13 +1,23 @@ '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) { - return '' + var value = this.dynamicBytes.decodeFromStorage(location, storageContent) + value = value.replace('0x', '') + var ret = '' + for (var k = 0; k < value.length; k += 2) { + var raw = value.substr(k, 2) + var str = String.fromCharCode(parseInt(raw, 16)) + ret += str + } + return ret } module.exports = StringType diff --git a/src/solidity/types/Uint.js b/src/solidity/types/Uint.js index 4993258d2d..eef4d5f302 100644 --- a/src/solidity/types/Uint.js +++ b/src/solidity/types/Uint.js @@ -1,12 +1,10 @@ 'use strict' -var IntType = require('./Int') var util = require('./util') function Uint (storageBytes) { this.storageSlots = 1 this.storageBytes = storageBytes this.typeName = 'uint' - this.decodeInt = new IntType(storageBytes) } Uint.prototype.decodeFromStorage = function (location, storageContent) { diff --git a/test/solidity/contracts/byteStorage.js b/test/solidity/contracts/byteStorage.js new file mode 100644 index 0000000000..104ad3f9b8 --- /dev/null +++ b/test/solidity/contracts/byteStorage.js @@ -0,0 +1,135 @@ +'use strict' + +module.exports = { + contract: ` + contract byteStorage { + enum enum1 { + a, + b, + c, + d + } + bool b1; + address a1; + bool b2; + bytes dynb1; + byte stab; + bytes1 stab1; + bytes2 stab2; + bytes3 stab3; + bytes4 stab4; + bytes5 stab5; + bytes6 stab6; + bytes7 stab7; + bytes8 stab8; + bytes9 stab9; + bytes10 stab10; + bytes11 stab11; + bytes12 stab12; + bytes13 stab13; + bytes14 stab14; + bytes15 stab15; + bytes16 stab16; + bytes17 stab17; + bytes18 stab18; + bytes19 stab19; + bytes20 stab20; + bytes21 stab21; + bytes22 stab22; + bytes23 stab23; + bytes24 stab24; + bytes25 stab25; + bytes26 stab26; + bytes27 stab27; + bytes28 stab28; + bytes29 stab29; + bytes30 stab30; + bytes31 stab31; + bytes32 stab32; + enum1 enumDec; + string str1; + string str2; + + function byteStorage () { + b1 = false; + a1 = 0xfe350f199f244ac9a79038d254400b632a633225; + b2 = true; + dynb1 = 'dynamicbytes'; + stab = 0x1; + stab1 = 0x12; + stab2 = 0x1579; + stab3 = 0x359356; + stab4 = 0x2375; + stab5 = 0x2357645; + stab6 = 0x324435; + stab7 = 0x324324; + stab8 = 0x324554645765; + stab9 = 0x3434543; + stab10 = 0x4543543654657; + stab11 = 0x54354654; + stab12 = 0x3; + stab13 = 0x3243242345435; + stab14 = 0x32454354354353; + stab15 = 0x32454434435; + stab16 = 0x3245435444; + stab17 = 0x32454343243243245; + stab18 = 0x324534325435435; + stab19 = 0x324543435435435; + stab20 = 0x32454543543AB35; + stab21 = 0x32454432423435; + stab22 = 0x324543AEF5; + stab23 = 0x3245435FFF; + stab24 = 0x3245435F; + stab25 = 0x3245435F; + stab26 = 0x3245435F; + stab27 = 0x3245FFFFFFF; + stab28 = 0x3241235; + stab29 = 0x325213213; + stab30 = 0x3245435232423; + stab31 = 0x3245435123; + stab32 = 0x324324423432543543AB; + enumDec = enum1.d; + str1 = 'short'; + 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'; + } + + } +`, + storage: { + '0x0000000000000000000000000000000000000000000000000000000000000000': '0x0000000000000000000001fe350f199f244ac9a79038d254400b632a63322500', + '0x0000000000000000000000000000000000000000000000000000000000000001': '0x64796e616d696362797465730000000000000000000000000000000000000018', + '0x0000000000000000000000000000000000000000000000000000000000000002': '0x0000000000000032432400000032443500023576450000237535935615791201', + '0x0000000000000000000000000000000000000000000000000000000000000003': '0x0000000000000000045435436546570000000000034345430000324554645765', + '0x0000000000000000000000000000000000000000000000000000000000000004': '0x0000000000000000000000000000000000000000030000000000000054354654', + '0x0000000000000000000000000000000000000000000000000000000000000005': '0x0000000000000000000000003245435435435300000000000003243242345435', + '0x0000000000000000000000000000000000000000000000000000000000000006': '0x0000000000000000000000003245435444000000000000000000032454434435', + '0x0000000000000000000000000000000000000000000000000000000000000007': '0x0000000000000000000000000000000000000000000000032454343243243245', + '0x0000000000000000000000000000000000000000000000000000000000000008': '0x0000000000000000000000000000000000000000000000000324534325435435', + '0x0000000000000000000000000000000000000000000000000000000000000009': '0x0000000000000000000000000000000000000000000000000324543435435435', + '0x000000000000000000000000000000000000000000000000000000000000000a': '0x000000000000000000000000000000000000000000000000032454543543ab35', + '0x000000000000000000000000000000000000000000000000000000000000000b': '0x0000000000000000000000000000000000000000000000000032454432423435', + '0x000000000000000000000000000000000000000000000000000000000000000c': '0x000000000000000000000000000000000000000000000000000000324543aef5', + '0x000000000000000000000000000000000000000000000000000000000000000d': '0x0000000000000000000000000000000000000000000000000000003245435fff', + '0x000000000000000000000000000000000000000000000000000000000000000e': '0x000000000000000000000000000000000000000000000000000000003245435f', + '0x000000000000000000000000000000000000000000000000000000000000000f': '0x000000000000000000000000000000000000000000000000000000003245435f', + '0x0000000000000000000000000000000000000000000000000000000000000010': '0x000000000000000000000000000000000000000000000000000000003245435f', + '0x0000000000000000000000000000000000000000000000000000000000000011': '0x000000000000000000000000000000000000000000000000000003245fffffff', + '0x0000000000000000000000000000000000000000000000000000000000000012': '0x0000000000000000000000000000000000000000000000000000000003241235', + '0x0000000000000000000000000000000000000000000000000000000000000013': '0x0000000000000000000000000000000000000000000000000000000325213213', + '0x0000000000000000000000000000000000000000000000000000000000000014': '0x0000000000000000000000000000000000000000000000000003245435232423', + '0x0000000000000000000000000000000000000000000000000000000000000015': '0x0000000000000000000000000000000000000000000000000000003245435123', + '0x0000000000000000000000000000000000000000000000000000000000000016': '0x00000000000000000000000000000000000000000000324324423432543543ab', + '0x0000000000000000000000000000000000000000000000000000000000000017': '0x0000000000000000000000000000000000000000000000000000000000000003', + '0x0000000000000000000000000000000000000000000000000000000000000018': '0x73686f727400000000000000000000000000000000000000000000000000000a', + '0x0000000000000000000000000000000000000000000000000000000000000019': '0x000000000000000000000000000000000000000000000000000000000000023d', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695': '0x6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9696': '0x6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e67', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9697': '0x5f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9698': '0x6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9699': '0x6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e67', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c969a': '0x5f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c969b': '0x6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c969c': '0x6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e67', + '0x944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c969d': '0x5f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e675f5f6c6f6e670000' + } +} diff --git a/test/solidity/storageDecoder.js b/test/solidity/storageDecoder.js index b0292fbf76..70cc8708d5 100644 --- a/test/solidity/storageDecoder.js +++ b/test/solidity/storageDecoder.js @@ -6,6 +6,8 @@ var stateDecoder = require('../../src/index').solidity.stateDecoder tape('solidity', function (t) { t.test('storage decoder', function (st) { testIntStorage(st) + testByteStorage(st) + st.end() }) }) @@ -50,6 +52,52 @@ function testIntStorage (st) { st.end() } +function testByteStorage (st) { + var byteStorage = require('./contracts/byteStorage') + var output = compiler.compile(byteStorage.contract, 0) + var decoded = stateDecoder.solidityState(byteStorage.storage, output.sources, 'byteStorage') + st.equal(decoded['b1'], false) + st.equal(decoded['a1'], '0xfe350f199f244ac9a79038d254400b632a633225') + st.equal(decoded['b2'], true) + st.equal(decoded['dynb1'], '0x64796e616d69636279746573') + st.equal(decoded['stab'], '0x1') + st.equal(decoded['stab1'], '0x12') + st.equal(decoded['stab2'], '0x1579') + st.equal(decoded['stab3'], '0x359356') + st.equal(decoded['stab4'], '0x2375') + st.equal(decoded['stab5'], '0x2357645') + st.equal(decoded['stab6'], '0x324435') + st.equal(decoded['stab7'], '0x324324') + st.equal(decoded['stab8'], '0x324554645765') + st.equal(decoded['stab9'], '0x3434543') + st.equal(decoded['stab10'], '0x4543543654657') + st.equal(decoded['stab11'], '0x54354654') + st.equal(decoded['stab12'], '0x3') + st.equal(decoded['stab13'], '0x3243242345435') + st.equal(decoded['stab14'], '0x32454354354353') + st.equal(decoded['stab15'], '0x32454434435') + st.equal(decoded['stab16'], '0x3245435444') + st.equal(decoded['stab17'], '0x32454343243243245') + st.equal(decoded['stab18'], '0x324534325435435') + st.equal(decoded['stab19'], '0x324543435435435') + st.equal(decoded['stab20'], '0x32454543543AB35') + st.equal(decoded['stab21'], '0x32454432423435') + st.equal(decoded['stab22'], '0x324543AEF5') + st.equal(decoded['stab23'], '0x3245435FFF') + st.equal(decoded['stab24'], '0x3245435F') + st.equal(decoded['stab25'], '0x3245435F') + st.equal(decoded['stab26'], '0x3245435F') + st.equal(decoded['stab27'], '0x3245FFFFFFF') + st.equal(decoded['stab28'], '0x3241235') + st.equal(decoded['stab29'], '0x325213213') + st.equal(decoded['stab30'], '0x3245435232423') + st.equal(decoded['stab31'], '0x3245435123') + st.equal(decoded['stab32'], '0x324324423432543543AB') + st.equal(decoded['enumDec'], 'd') + 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') +} + function shrinkStorage (storage) { var shrinkedStorage = {} var regex = /0x(00)*(..)/