Skip to content

Commit

Permalink
Solidity pack Array support
Browse files Browse the repository at this point in the history
Solidity pack Array support
  • Loading branch information
vrolland committed Sep 13, 2017
1 parent ee6ded6 commit 5acbaf1
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 1 deletion.
48 changes: 47 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,52 @@ ABI.solidityPack = function (types, values) {

if (type === 'bytes') {
ret.push(value)
} else if (isArray(type)) {
var typeArray = type.split('[')[0];
var length = type.match(/\[(.*)\]/i)[1];

if(typeArray=='address') {
for(var j=0;j<length;j++) {
ret.push(utils.setLengthLeft(value[j], 32))
};
}else if(typeArray=='bool') {
for(var j=0;j<length;j++) {
ret.push(utils.setLengthLeft(value[j] ? 1 : 0, 32))
};
} else if (typeArray.startsWith('bytes') && (parseTypeN(typeArray) >= 1 || parseTypeN(typeArray) <= 32)) {
for(var j=0;j<length;j++) {
ret.push(utils.setLengthRight(value[j], 32))
};
} else if (typeArray.startsWith('uint')) {
var size = parseTypeN(typeArray)
if ((size % 8) || (size < 8) || (size > 256)) {
throw new Error('Invalid uint<N> width: ' + size)
}
for(var j=0;j<length;j++) {
var num = parseNumber(!value[j]?0:value[j]);
if (num.bitLength() > size) {
throw new Error('Supplied uint exceeds width: ' + size + ' vs ' + num.bitLength())
}

ret.push(num.toArrayLike(Buffer, 'be', 32))
}
} else if (type.startsWith('int')) {
var size = parseTypeN(typeArray)
if ((size % 8) || (size < 8) || (size > 256)) {
throw new Error('Invalid int<N> width: ' + size)
}
for(var j=0;j<length;j++) {
var num = parseNumber(!value[j]?0:value[j]);
if (num.bitLength() > size) {
throw new Error('Supplied int exceeds width: ' + size + ' vs ' + num.bitLength())
}

ret.push(num.toTwos(size).toArrayLike(Buffer, 'be', 32))
}

} else {
throw new Error('Unsupported or invalid type array: ' + typeArray)
}
} else if (type === 'string') {
ret.push(new Buffer(value, 'utf8'))
} else if (type === 'bool') {
Expand Down Expand Up @@ -480,7 +526,6 @@ ABI.solidityPack = function (types, values) {
throw new Error('Unsupported or invalid type: ' + type)
}
}

return Buffer.concat(ret)
}

Expand Down Expand Up @@ -555,3 +600,4 @@ ABI.toSerpent = function (types) {
}

module.exports = ABI

55 changes: 55 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,61 @@ describe('solidity tight packing multiple arguments', function () {
})
})

describe('solidity tight packing array of address', function () {
it('should equal', function () {
var a = abi.solidityPack(
[ 'address[3]' ],
[ [new BN('43989fb883ba8111221e89123897538475893837', 16), new BN('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 16)] ]
)
var b = '00000000000000000000000043989fb883ba8111221e89123897538475893837000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000000000000000000000000000000000000000000000000000000000';
assert.equal(a.toString('hex'), b.toString('hex'))
})
})

describe('solidity tight packing array of bool', function () {
it('should equal', function () {
var a = abi.solidityPack(
[ 'bool[3]' ],
[ [true, false, true] ]
)
var b = '000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001';
assert.equal(a.toString('hex'), b.toString('hex'))
})
})

describe('solidity tight packing array of bytes8', function () {
it('should equal', function () {
var a = abi.solidityPack(
[ 'bytes8[3]' ],
[ [new BN('123456', 16), new BN('abcdef', 16)] ]
)
var b = '1234560000000000000000000000000000000000000000000000000000000000abcdef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
assert.equal(a.toString('hex'), b.toString('hex'))
})
})

describe('solidity tight packing array of uint8', function () {
it('should equal', function () {
var a = abi.solidityPack(
[ 'uint8[3]' ],
[ [new BN('123', 10), new BN('ff', 16)] ]
)
var b = '000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000000';
assert.equal(a.toString('hex'), b.toString('hex'))
})
})

describe('solidity tight packing array of int8', function () {
it('should equal', function () {
var a = abi.solidityPack(
[ 'int8[3]' ],
[ [new BN('-123', 10), new BN('ff', 16)] ]
)
var b = '000000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000000';
assert.equal(a.toString('hex'), b.toString('hex'))
})
})

describe('solidity tight packing sha3', function () {
it('should equal', function () {
var a = abi.soliditySHA3(
Expand Down

0 comments on commit 5acbaf1

Please sign in to comment.