diff --git a/lib/solidity/coder.js b/lib/solidity/coder.js index 8e31d05..f0c62d5 100644 --- a/lib/solidity/coder.js +++ b/lib/solidity/coder.js @@ -233,8 +233,6 @@ SolidityCoder.prototype.encodeParams = function (types, params) { return solidityType.encode(params[index], types[index]); }); - //console.log(encodeds); - var totalOffset = solidityTypes.reduce(function (acc, solidityType, index) { return acc + solidityType.staticPartLength(types[index]); }, 0); @@ -250,7 +248,6 @@ SolidityCoder.prototype.encodeParams = function (types, params) { return acc + encodeds[index]; }, ""); - //console.log(result); result = solidityTypes.reduce(function (acc, solidityType, index) { if (solidityType.isDynamicArray(types[index])) { var offset = acc.length / 2; @@ -259,8 +256,6 @@ SolidityCoder.prototype.encodeParams = function (types, params) { return acc; }, result); - //console.log(result); - return result; }; @@ -271,15 +266,18 @@ SolidityCoder.prototype.encodeWithOffset = function (type, solidityType, encoded var nestedStaticPartLength = solidityType.staticPartLength(nestedName); var result = encoded[0]; + var previousLength = 2; // in int if (solidityType.isDynamicArray(nestedName)) { - for (var i = 0; i < encoded.length; i++) { - result += f.formatInputInt(offset + i * nestedStaticPartLength + encoded.length * 32).encode(); + for (var i = 1; i < encoded.length; i++) { + previousLength += +(encoded[i - 1] || {})[0] || 0; + result += f.formatInputInt(offset + i * nestedStaticPartLength + previousLength * 32).encode(); } } // first element is length, skip it for (var i = 0; i < encoded.length - 1; i++) { - result += this.encodeWithOffset(nestedName, solidityType, encoded[i + 1], offset + i * nestedStaticPartLength); + var additionalOffset = result / 2; + result += this.encodeWithOffset(nestedName, solidityType, encoded[i + 1], offset + additionalOffset); } return result; @@ -293,7 +291,7 @@ SolidityCoder.prototype.encodeWithOffset = function (type, solidityType, encoded if (solidityType.isDynamicArray(nestedName)) { for (var i = 0; i < encoded.length; i++) { // calculate length of previous item - previousLength += (encoded[i - 1] || {})[0] || 0; + previousLength += +(encoded[i - 1] || {})[0] || 0; result += f.formatInputInt(offset + i * nestedStaticPartLength + previousLength * 32).encode(); } } diff --git a/test/coder.encodeParam.js b/test/coder.encodeParam.js index f83ae1e..78da89a 100644 --- a/test/coder.encodeParam.js +++ b/test/coder.encodeParam.js @@ -26,20 +26,42 @@ describe('lib/solidity/coder', function () { ['0x407d73d8a49eeb85d32cf465507dd71d507100c3', '0x407d73d8a49eeb85d32cf465507dd71d507100c4']], expected: '0000000000000000000000000000000000000000000000000000000000000040' + '00000000000000000000000000000000000000000000000000000000000000a0' + - '0000000000000000000000000000000000000000000000000000000000000002' + /* 40 */ - '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1' + /* 60 */ + '0000000000000000000000000000000000000000000000000000000000000002' + + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1' + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c2' + - '0000000000000000000000000000000000000000000000000000000000000002' + /* a0 */ + '0000000000000000000000000000000000000000000000000000000000000002' + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c3' + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c4' }); test({ type: 'address[][2]', value: [['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x407d73d8a49eeb85d32cf465507dd71d507100c2'], ['0x407d73d8a49eeb85d32cf465507dd71d507100c3', '0x407d73d8a49eeb85d32cf465507dd71d507100c4']], expected: '0000000000000000000000000000000000000000000000000000000000000020' + - '0000000000000000000000000000000000000000000000000000000000000002' + /* 20 */ + '0000000000000000000000000000000000000000000000000000000000000002' + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1' + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c2' + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c3' + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c4' }); + test({ type: 'address[][]', value: [['0x407d73d8a49eeb85d32cf465507dd71d507100c1'], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c3']], + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000002' + /* 20 */ + '0000000000000000000000000000000000000000000000000000000000000080' + + '00000000000000000000000000000000000000000000000000000000000000c0' + + '0000000000000000000000000000000000000000000000000000000000000001' + /* 80 */ + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1' + /* a0 */ + '0000000000000000000000000000000000000000000000000000000000000001' + /* c0 */ + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c3' }); + test({ type: 'address[][]', value: [['0x407d73d8a49eeb85d32cf465507dd71d507100c1', '0x407d73d8a49eeb85d32cf465507dd71d507100c2'], + ['0x407d73d8a49eeb85d32cf465507dd71d507100c3', '0x407d73d8a49eeb85d32cf465507dd71d507100c4']], + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000002' + /* 20 */ + '0000000000000000000000000000000000000000000000000000000000000080' + + '00000000000000000000000000000000000000000000000000000000000000e0' + + '0000000000000000000000000000000000000000000000000000000000000002' + /* 80 */ + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1' + /* a0 */ + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c2' + + '0000000000000000000000000000000000000000000000000000000000000002' + /* e0 */ + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c3' + + '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c4' }); //test({ type: 'int', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); //test({ type: 'int', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); //test({ type: 'int', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'});