'use strict' var bigNumberify = require('./bignumber').bigNumberify var convert = require('./convert') var getAddress = require('./address').getAddress var utf8 = require('./utf8') var hashKeccak256 = require('./keccak256') var hashSha256 = require('./sha2').sha256 var regexBytes = new RegExp('^bytes([0-9]+)$') var regexNumber = new RegExp('^(u?int)([0-9]*)$') var regexArray = new RegExp('^(.*)\\[([0-9]*)\\]$') var Zeros = '0000000000000000000000000000000000000000000000000000000000000000' function _pack (type, value, isArray) { switch (type) { case 'address': if (isArray) { return convert.padZeros(value, 32) } return convert.arrayify(value) case 'string': return utf8.toUtf8Bytes(value) case 'bytes': return convert.arrayify(value) case 'bool': value = value ? '0x01' : '0x00' if (isArray) { return convert.padZeros(value, 32) } return convert.arrayify(value) } var match = type.match(regexNumber) if (match) { var signed = match[1] === 'int' var size = parseInt(match[2] || '256') if (size % 8 != 0 || size === 0 || size > 256) { throw new Error('invalid number type - ' + type) } if (isArray) { size = 256 } value = bigNumberify(value).toTwos(size) return convert.padZeros(value, size / 8) } match = type.match(regexBytes) if (match) { var size = match[1] if (size != parseInt(size) || size === 0 || size > 32) { throw new Error('invalid number type - ' + type) } size = parseInt(size) if (convert.arrayify(value).byteLength !== size) { throw new Error('invalid value for ' + type) } if (isArray) { return (value + Zeros).substring(0, 66) } return value } match = type.match(regexArray) if (match) { var valueType = match[1] var count = parseInt(match[2] || value.length) if (count != value.length) { throw new Error('invalid value for ' + type) } var result = [] value.forEach(function (value) { value = _pack(valueType, value, true) result.push(value) }) return convert.concat(result) } throw new Error('unknown type - ' + type) } function pack (types, values) { if (types.length != values.length) { throw new Error('type/value count mismatch') } var tight = [] types.forEach(function (type, index) { tight.push(_pack(type, values[index])) }) return convert.hexlify(convert.concat(tight)) } function keccak256 (types, values) { return hashKeccak256(pack(types, values)) } function sha256 (types, values) { return hashSha256(pack(types, values)) } module.exports = { pack: pack, keccak256: keccak256, sha256: sha256 }