Updated dist files.

This commit is contained in:
Richard Moore 2017-11-21 21:28:58 -05:00
parent 0d106d01af
commit 3ed66f5c16
No known key found for this signature in database
GPG Key ID: 525F70A6FCABC295
7 changed files with 427 additions and 237 deletions

View File

@ -19,6 +19,15 @@ var allowedTransactionKeys = {
data: true, from: true, gasLimit: true, gasPrice:true, to: true, value: true data: true, from: true, gasLimit: true, gasPrice:true, to: true, value: true
} }
function copyObject(object) {
var result = {};
for (var key in object) {
result[key] = object[key];
}
return result;
}
function Contract(addressOrName, contractInterface, signerOrProvider) { function Contract(addressOrName, contractInterface, signerOrProvider) {
if (!(this instanceof Contract)) { throw new Error('missing new'); } if (!(this instanceof Contract)) { throw new Error('missing new'); }
@ -58,6 +67,7 @@ function Contract(addressOrName, contractInterface, signerOrProvider) {
if (typeof(transaction) !== 'object') { if (typeof(transaction) !== 'object') {
throw new Error('invalid transaction overrides'); throw new Error('invalid transaction overrides');
} }
transaction = copyObject(transaction);
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit") // Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
for (var key in transaction) { for (var key in transaction) {
@ -151,7 +161,7 @@ function Contract(addressOrName, contractInterface, signerOrProvider) {
if (transaction.nonce) { if (transaction.nonce) {
noncePromise = Promise.resolve(transaction.nonce) noncePromise = Promise.resolve(transaction.nonce)
} else if (signer.getTransactionCount) { } else if (signer.getTransactionCount) {
noncePromise = signer.getTransactionCount; noncePromise = signer.getTransactionCount();
if (!(noncePromise instanceof Promise)) { if (!(noncePromise instanceof Promise)) {
noncePromise = Promise.resolve(noncePromise); noncePromise = Promise.resolve(noncePromise);
} }
@ -333,6 +343,7 @@ function defineFrozen(object, name, value) {
}); });
} }
// getKeys([{a: 1, b: 2}, {a: 3, b: 4}], 'a') => [1, 3] // getKeys([{a: 1, b: 2}, {a: 3, b: 4}], 'a') => [1, 3]
function getKeys(params, key, allowEmpty) { function getKeys(params, key, allowEmpty) {
if (!Array.isArray(params)) { throwError('invalid params', {params: params}); } if (!Array.isArray(params)) { throwError('invalid params', {params: params}); }
@ -352,6 +363,32 @@ function getKeys(params, key, allowEmpty) {
return result; return result;
} }
function parseParams(params) {
var names = [];
var types = [];
params.forEach(function(param) {
if (param.components != null) {
if (param.type.substring(0, 5) !== 'tuple') {
throw new Error('internal error; report on GitHub');
}
var suffix = '';
var arrayBracket = param.type.indexOf('[');
if (arrayBracket >= 0) { suffix = param.type.substring(arrayBracket); }
var result = parseParams(param.components);
names.push({ name: (param.name || null), names: result.names });
types.push('tuple(' + result.types.join(',') + ')' + suffix)
} else {
names.push(param.name || null);
types.push(param.type);
}
});
return {
names: names,
types: types
}
}
var coderNull = { var coderNull = {
name: 'null', name: 'null',
type: '', type: '',
@ -368,9 +405,10 @@ var coderNull = {
dynamic: false dynamic: false
}; };
function coderNumber(size, signed) { function coderNumber(size, signed, localName) {
var name = ((signed ? 'int': 'uint') + size); var name = ((signed ? 'int': 'uint') + size);
return { return {
localName: localName,
name: name, name: name,
type: name, type: name,
encode: function(value) { encode: function(value) {
@ -401,7 +439,9 @@ function coderNumber(size, signed) {
} }
var uint256Coder = coderNumber(32, false); var uint256Coder = coderNumber(32, false);
var coderBoolean = { var coderBoolean = function(localName) {
return {
localName: localName,
name: 'boolean', name: 'boolean',
type: 'boolean', type: 'boolean',
encode: function(value) { encode: function(value) {
@ -414,11 +454,13 @@ var coderBoolean = {
value: !result.value.isZero() value: !result.value.isZero()
} }
} }
}
} }
function coderFixedBytes(length) { function coderFixedBytes(length, localName) {
var name = ('bytes' + length); var name = ('bytes' + length);
return { return {
localName: localName,
name: name, name: name,
type: name, type: name,
encode: function(value) { encode: function(value) {
@ -440,7 +482,9 @@ function coderFixedBytes(length) {
}; };
} }
var coderAddress = { var coderAddress = function(localName) {
return {
localName: localName,
name: 'address', name: 'address',
type: 'address', type: 'address',
encode: function(value) { encode: function(value) {
@ -456,6 +500,7 @@ var coderAddress = {
value: utils.getAddress(utils.hexlify(data.slice(offset + 12, offset + 32))) value: utils.getAddress(utils.hexlify(data.slice(offset + 12, offset + 32)))
} }
} }
}
} }
function _encodeDynamicBytes(value) { function _encodeDynamicBytes(value) {
@ -482,7 +527,9 @@ function _decodeDynamicBytes(data, offset) {
} }
} }
var coderDynamicBytes = { var coderDynamicBytes = function(localName) {
return {
localName: localName,
name: 'bytes', name: 'bytes',
type: 'bytes', type: 'bytes',
encode: function(value) { encode: function(value) {
@ -494,9 +541,12 @@ var coderDynamicBytes = {
return result; return result;
}, },
dynamic: true dynamic: true
}; };
}
var coderString = { var coderString = function(localName) {
return {
localName: localName,
name: 'string', name: 'string',
type: 'string', type: 'string',
encode: function(value) { encode: function(value) {
@ -508,7 +558,8 @@ var coderString = {
return result; return result;
}, },
dynamic: true dynamic: true
}; };
}
function alignSize(size) { function alignSize(size) {
return parseInt(32 * Math.ceil(size / 32)); return parseInt(32 * Math.ceil(size / 32));
@ -553,12 +604,10 @@ function pack(coders, values) {
return data; return data;
} }
function unpack(coders, data, offset) { function unpack(coders, data, offset) {
var baseOffset = offset; var baseOffset = offset;
var consumed = 0; var consumed = 0;
var value = []; var value = [];
coders.forEach(function(coder) { coders.forEach(function(coder) {
if (coder.dynamic) { if (coder.dynamic) {
var dynamicOffset = uint256Coder.decode(data, offset); var dynamicOffset = uint256Coder.decode(data, offset);
@ -577,6 +626,20 @@ function unpack(coders, data, offset) {
consumed += result.consumed; consumed += result.consumed;
}); });
coders.forEach(function(coder, index) {
var name = coder.localName;
if (!name) { return; }
if (typeof(name) === 'object') { name = name.name; }
if (!name) { return; }
if (name === 'length') { name = '_length'; }
if (value[name] != null) { return; }
value[name] = value[index];
});
return { return {
value: value, value: value,
consumed: consumed consumed: consumed
@ -585,11 +648,12 @@ function unpack(coders, data, offset) {
return result; return result;
} }
function coderArray(coder, length) { function coderArray(coder, length, localName) {
var type = (coder.type + '[' + (length >= 0 ? length: '') + ']'); var type = (coder.type + '[' + (length >= 0 ? length: '') + ']');
return { return {
coder: coder, coder: coder,
localName: localName,
length: length, length: length,
name: 'array', name: 'array',
type: type, type: type,
@ -638,7 +702,7 @@ function coderArray(coder, length) {
} }
function coderTuple(coders) { function coderTuple(coders, localName) {
var dynamic = false; var dynamic = false;
var types = []; var types = [];
coders.forEach(function(coder) { coders.forEach(function(coder) {
@ -650,14 +714,21 @@ function coderTuple(coders) {
return { return {
coders: coders, coders: coders,
localName: localName,
name: 'tuple', name: 'tuple',
type: type, type: type,
encode: function(value) { encode: function(value) {
if (Array.isArray(value)) {
if (coders.length !== coders.length) { if (coders.length !== value.length) {
throwError('types/values mismatch', { type: type, values: values }); throwError('types/values mismatch', { type: type, values: values });
} }
// @TODO: If receiving an object, and we have names, create the array
} else {
throwError('invalid value', { type: types, values: values });
}
return pack(coders, value); return pack(coders, value);
}, },
decode: function(data, offset) { decode: function(data, offset) {
@ -708,10 +779,9 @@ var paramTypeSimple = {
bytes: coderDynamicBytes, bytes: coderDynamicBytes,
}; };
function getParamCoder(type) { function getParamCoder(type, localName) {
var coder = paramTypeSimple[type]; var coder = paramTypeSimple[type];
if (coder) { return coder; } if (coder) { return coder(localName); }
var match = type.match(paramTypeNumber); var match = type.match(paramTypeNumber);
if (match) { if (match) {
@ -719,7 +789,7 @@ function getParamCoder(type) {
if (size === 0 || size > 256 || (size % 8) !== 0) { if (size === 0 || size > 256 || (size % 8) !== 0) {
throwError('invalid type', { type: type }); throwError('invalid type', { type: type });
} }
return coderNumber(size / 8, (match[1] === 'int')); return coderNumber(size / 8, (match[1] === 'int'), localName);
} }
var match = type.match(paramTypeBytes); var match = type.match(paramTypeBytes);
@ -728,21 +798,26 @@ function getParamCoder(type) {
if (size === 0 || size > 32) { if (size === 0 || size > 32) {
throwError('invalid type ' + type); throwError('invalid type ' + type);
} }
return coderFixedBytes(size); return coderFixedBytes(size, localName);
} }
var match = type.match(paramTypeArray); var match = type.match(paramTypeArray);
if (match) { if (match) {
var size = parseInt(match[2] || -1); var size = parseInt(match[2] || -1);
return coderArray(getParamCoder(match[1]), size); return coderArray(getParamCoder(match[1], localName), size, localName);
} }
if (type.substring(0, 6) === 'tuple(' && type.substring(type.length - 1) === ')') { if (type.substring(0, 6) === 'tuple(' && type.substring(type.length - 1) === ')') {
var coders = []; var coders = [];
splitNesting(type.substring(6, type.length - 1)).forEach(function(type) { var names = [];
coders.push(getParamCoder(type)); if (localName && typeof(localName) === 'object') {
if (Array.isArray(localName.names)) { names = localName.names; }
if (typeof(localName.name) === 'string') { localName = localName.name; }
}
splitNesting(type.substring(6, type.length - 1)).forEach(function(type, index) {
coders.push(getParamCoder(type, names[index]));
}); });
return coderTuple(coders); return coderTuple(coders, localName);
} }
if (type === '') { if (type === '') {
@ -772,6 +847,11 @@ utils.defineProperty(TransactionDescription.prototype, 'type', 'transaction');
function EventDescription() { } function EventDescription() { }
utils.defineProperty(EventDescription.prototype, 'type', 'event'); utils.defineProperty(EventDescription.prototype, 'type', 'event');
function Indexed(value) {
utils.defineProperty(this, 'indexed', true);
utils.defineProperty(this, 'hash', value);
}
function Interface(abi) { function Interface(abi) {
if (!(this instanceof Interface)) { throw new Error('missing new'); } if (!(this instanceof Interface)) { throw new Error('missing new'); }
@ -796,6 +876,7 @@ function Interface(abi) {
switch (method.type) { switch (method.type) {
case 'constructor': case 'constructor':
var func = (function() { var func = (function() {
// @TODO: Move to parseParams
var inputTypes = getKeys(method.inputs, 'type'); var inputTypes = getKeys(method.inputs, 'type');
var func = function(bytecode) { var func = function(bytecode) {
if (!utils.isHexString(bytecode)) { if (!utils.isHexString(bytecode)) {
@ -816,6 +897,7 @@ function Interface(abi) {
return populateDescription(new DeployDescription(), result); return populateDescription(new DeployDescription(), result);
} }
// @TODO: Move to parseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name')); defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
return func; return func;
@ -827,13 +909,16 @@ function Interface(abi) {
case 'function': case 'function':
var func = (function() { var func = (function() {
var inputTypes = getKeys(method.inputs, 'type'); var inputParams = parseParams(method.inputs);
var outputParams = parseParams(method.outputs);
var inputTypes = inputParams.types;
if (method.constant) { if (method.constant) {
var outputTypes = getKeys(method.outputs, 'type'); var outputTypes = outputParams.types;
var outputNames = getKeys(method.outputs, 'name', true); var outputNames = outputParams.names;
} }
var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')'; var signature = method.name + '(' + inputParams.types.join(',') + ')';
var sighash = utils.keccak256(utils.toUtf8Bytes(signature)).substring(0, 10); var sighash = utils.keccak256(utils.toUtf8Bytes(signature)).substring(0, 10);
var func = function() { var func = function() {
var result = { var result = {
@ -865,6 +950,7 @@ function Interface(abi) {
return populateDescription(new TransactionDescription(), result); return populateDescription(new TransactionDescription(), result);
} }
// @TODO: Move the paraseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name')); defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
defineFrozen(func, 'outputs', getKeys(method.outputs, 'name')); defineFrozen(func, 'outputs', getKeys(method.outputs, 'name'));
utils.defineProperty(func, 'signature', signature); utils.defineProperty(func, 'signature', signature);
@ -883,8 +969,10 @@ function Interface(abi) {
case 'event': case 'event':
var func = (function() { var func = (function() {
// @TODO: Move to parseParams
var inputTypes = getKeys(method.inputs, 'type'); var inputTypes = getKeys(method.inputs, 'type');
var func = function() { var func = function() {
// @TODO: Move to parseParams
var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')'; var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')';
var result = { var result = {
inputs: method.inputs, inputs: method.inputs,
@ -894,27 +982,41 @@ function Interface(abi) {
}; };
result.parse = function(topics, data) { result.parse = function(topics, data) {
if (data == null) {
data = topics;
topics = null;
}
// Strip the signature off of non-anonymous topics // Strip the signature off of non-anonymous topics
if (!method.anonymous) { topics = topics.slice(1); } if (topics != null && !method.anonymous) { topics = topics.slice(1); }
var inputNamesIndexed = [], inputNamesNonIndexed = []; var inputNamesIndexed = [], inputNamesNonIndexed = [];
var inputTypesIndexed = [], inputTypesNonIndexed = []; var inputTypesIndexed = [], inputTypesNonIndexed = [];
var inputDynamic = [];
method.inputs.forEach(function(input) { method.inputs.forEach(function(input) {
if (input.indexed) { if (input.indexed) {
inputNamesIndexed.push(input.name); if (input.type === 'string' || input.type === 'bytes' || input.type.indexOf('[') >= 0) {
inputTypesIndexed.push('bytes32');
inputDynamic.push(true);
} else {
inputTypesIndexed.push(input.type); inputTypesIndexed.push(input.type);
inputDynamic.push(false);
}
inputNamesIndexed.push(input.name);
} else { } else {
inputNamesNonIndexed.push(input.name); inputNamesNonIndexed.push(input.name);
inputTypesNonIndexed.push(input.type); inputTypesNonIndexed.push(input.type);
inputDynamic.push(false);
} }
}); });
if (topics != null) {
var resultIndexed = Interface.decodeParams( var resultIndexed = Interface.decodeParams(
inputNamesIndexed, inputNamesIndexed,
inputTypesIndexed, inputTypesIndexed,
utils.concat(topics) utils.concat(topics)
); );
}
var resultNonIndexed = Interface.decodeParams( var resultNonIndexed = Interface.decodeParams(
inputNamesNonIndexed, inputNamesNonIndexed,
@ -926,7 +1028,19 @@ function Interface(abi) {
var nonIndexedIndex = 0, indexedIndex = 0; var nonIndexedIndex = 0, indexedIndex = 0;
method.inputs.forEach(function(input, i) { method.inputs.forEach(function(input, i) {
if (input.indexed) { if (input.indexed) {
if (topics == null) {
result[i] = new Indexed(null);
} else if (inputDynamic[i]) {
result[i] = new Indexed(resultIndexed[indexedIndex++]);
/*{
indexed: true,
hash: resultIndexed[indexedIndex++]
};
*/
} else {
result[i] = resultIndexed[indexedIndex++]; result[i] = resultIndexed[indexedIndex++];
}
} else { } else {
result[i] = resultNonIndexed[nonIndexedIndex++]; result[i] = resultNonIndexed[nonIndexedIndex++];
} }
@ -940,6 +1054,7 @@ function Interface(abi) {
return populateDescription(new EventDescription(), result); return populateDescription(new EventDescription(), result);
} }
// @TODO: Move to parseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name')); defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
return func; return func;
@ -992,39 +1107,18 @@ utils.defineProperty(Interface, 'decodeParams', function(names, types, data) {
if (arguments.length < 3) { if (arguments.length < 3) {
data = types; data = types;
types = names; types = names;
names = []; names = null;
} }
data = utils.arrayify(data); data = utils.arrayify(data);
var coders = []; var coders = [];
types.forEach(function(type) { types.forEach(function(type, index) {
coders.push(getParamCoder(type)); coders.push(getParamCoder(type, (names ? names[index]: undefined)));
}); });
var result = coderTuple(coders).decode(data, 0);
// @TODO: Move this into coderTuple
var values = new Result(); var values = new Result();
coders.forEach(function(coder, index) { return coderTuple(coders).decode(data, 0).value;
values[index] = result.value[index];
if (names && names[index]) {
var name = names[index];
if (name === 'length') {
console.log('WARNING: result length renamed to _length');
name = '_length';
}
if (values[name] == null) {
values[name] = values[index];
} else {
console.log('WARNING: duplicate value - ' + name);
}
}
})
values.length = types.length;
return values;
}); });
module.exports = Interface; module.exports = Interface;

File diff suppressed because one or more lines are too long

View File

@ -5390,6 +5390,7 @@ var utils = (function() {
isHexString: convert.isHexString, isHexString: convert.isHexString,
concat: convert.concat, concat: convert.concat,
stripZeros: convert.stripZeros,
namehash: require('ethers-utils/namehash'), namehash: require('ethers-utils/namehash'),
@ -5559,7 +5560,7 @@ function checkTransaction(transaction) {
// Some clients (TestRPC) do strange things like return 0x0 for the // Some clients (TestRPC) do strange things like return 0x0 for the
// 0 address; correct this to be a real address // 0 address; correct this to be a real address
if (transaction.to && utils.bigNumberify(transaction.to).isZero) { if (transaction.to && utils.bigNumberify(transaction.to).isZero()) {
transaction.to = '0x0000000000000000000000000000000000000000'; transaction.to = '0x0000000000000000000000000000000000000000';
} }
@ -5578,15 +5579,15 @@ function checkTransaction(transaction) {
// Very loose providers (e.g. TestRPC) don't provide a signature or raw // Very loose providers (e.g. TestRPC) don't provide a signature or raw
if (transaction.v && transaction.r && transaction.s) { if (transaction.v && transaction.r && transaction.s) {
var raw = [ var raw = [
utils.hexlify(transaction.nonce), utils.stripZeros(utils.hexlify(transaction.nonce)),
utils.hexlify(transaction.gasPrice), utils.stripZeros(utils.hexlify(transaction.gasPrice)),
utils.hexlify(transaction.gasLimit), utils.stripZeros(utils.hexlify(transaction.gasLimit)),
(transaction.to || "0x"), (transaction.to || "0x"),
utils.hexlify(transaction.value || '0x'), utils.stripZeros(utils.hexlify(transaction.value || '0x')),
utils.hexlify(transaction.data || '0x'), utils.hexlify(transaction.data || '0x'),
utils.hexlify(transaction.v || '0x'), utils.stripZeros(utils.hexlify(transaction.v || '0x')),
utils.hexlify(transaction.r), utils.stripZeros(utils.hexlify(transaction.r)),
utils.hexlify(transaction.s), utils.stripZeros(utils.hexlify(transaction.s)),
]; ];
transaction.raw = utils.RLP.encode(raw); transaction.raw = utils.RLP.encode(raw);

File diff suppressed because one or more lines are too long

221
dist/ethers.js vendored
View File

@ -6626,6 +6626,15 @@ var allowedTransactionKeys = {
data: true, from: true, gasLimit: true, gasPrice:true, to: true, value: true data: true, from: true, gasLimit: true, gasPrice:true, to: true, value: true
} }
function copyObject(object) {
var result = {};
for (var key in object) {
result[key] = object[key];
}
return result;
}
function Contract(addressOrName, contractInterface, signerOrProvider) { function Contract(addressOrName, contractInterface, signerOrProvider) {
if (!(this instanceof Contract)) { throw new Error('missing new'); } if (!(this instanceof Contract)) { throw new Error('missing new'); }
@ -6665,6 +6674,7 @@ function Contract(addressOrName, contractInterface, signerOrProvider) {
if (typeof(transaction) !== 'object') { if (typeof(transaction) !== 'object') {
throw new Error('invalid transaction overrides'); throw new Error('invalid transaction overrides');
} }
transaction = copyObject(transaction);
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit") // Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
for (var key in transaction) { for (var key in transaction) {
@ -6758,7 +6768,7 @@ function Contract(addressOrName, contractInterface, signerOrProvider) {
if (transaction.nonce) { if (transaction.nonce) {
noncePromise = Promise.resolve(transaction.nonce) noncePromise = Promise.resolve(transaction.nonce)
} else if (signer.getTransactionCount) { } else if (signer.getTransactionCount) {
noncePromise = signer.getTransactionCount; noncePromise = signer.getTransactionCount();
if (!(noncePromise instanceof Promise)) { if (!(noncePromise instanceof Promise)) {
noncePromise = Promise.resolve(noncePromise); noncePromise = Promise.resolve(noncePromise);
} }
@ -6940,6 +6950,7 @@ function defineFrozen(object, name, value) {
}); });
} }
// getKeys([{a: 1, b: 2}, {a: 3, b: 4}], 'a') => [1, 3] // getKeys([{a: 1, b: 2}, {a: 3, b: 4}], 'a') => [1, 3]
function getKeys(params, key, allowEmpty) { function getKeys(params, key, allowEmpty) {
if (!Array.isArray(params)) { throwError('invalid params', {params: params}); } if (!Array.isArray(params)) { throwError('invalid params', {params: params}); }
@ -6959,6 +6970,32 @@ function getKeys(params, key, allowEmpty) {
return result; return result;
} }
function parseParams(params) {
var names = [];
var types = [];
params.forEach(function(param) {
if (param.components != null) {
if (param.type.substring(0, 5) !== 'tuple') {
throw new Error('internal error; report on GitHub');
}
var suffix = '';
var arrayBracket = param.type.indexOf('[');
if (arrayBracket >= 0) { suffix = param.type.substring(arrayBracket); }
var result = parseParams(param.components);
names.push({ name: (param.name || null), names: result.names });
types.push('tuple(' + result.types.join(',') + ')' + suffix)
} else {
names.push(param.name || null);
types.push(param.type);
}
});
return {
names: names,
types: types
}
}
var coderNull = { var coderNull = {
name: 'null', name: 'null',
type: '', type: '',
@ -6975,9 +7012,10 @@ var coderNull = {
dynamic: false dynamic: false
}; };
function coderNumber(size, signed) { function coderNumber(size, signed, localName) {
var name = ((signed ? 'int': 'uint') + size); var name = ((signed ? 'int': 'uint') + size);
return { return {
localName: localName,
name: name, name: name,
type: name, type: name,
encode: function(value) { encode: function(value) {
@ -7008,7 +7046,9 @@ function coderNumber(size, signed) {
} }
var uint256Coder = coderNumber(32, false); var uint256Coder = coderNumber(32, false);
var coderBoolean = { var coderBoolean = function(localName) {
return {
localName: localName,
name: 'boolean', name: 'boolean',
type: 'boolean', type: 'boolean',
encode: function(value) { encode: function(value) {
@ -7021,11 +7061,13 @@ var coderBoolean = {
value: !result.value.isZero() value: !result.value.isZero()
} }
} }
}
} }
function coderFixedBytes(length) { function coderFixedBytes(length, localName) {
var name = ('bytes' + length); var name = ('bytes' + length);
return { return {
localName: localName,
name: name, name: name,
type: name, type: name,
encode: function(value) { encode: function(value) {
@ -7047,7 +7089,9 @@ function coderFixedBytes(length) {
}; };
} }
var coderAddress = { var coderAddress = function(localName) {
return {
localName: localName,
name: 'address', name: 'address',
type: 'address', type: 'address',
encode: function(value) { encode: function(value) {
@ -7063,6 +7107,7 @@ var coderAddress = {
value: utils.getAddress(utils.hexlify(data.slice(offset + 12, offset + 32))) value: utils.getAddress(utils.hexlify(data.slice(offset + 12, offset + 32)))
} }
} }
}
} }
function _encodeDynamicBytes(value) { function _encodeDynamicBytes(value) {
@ -7089,7 +7134,9 @@ function _decodeDynamicBytes(data, offset) {
} }
} }
var coderDynamicBytes = { var coderDynamicBytes = function(localName) {
return {
localName: localName,
name: 'bytes', name: 'bytes',
type: 'bytes', type: 'bytes',
encode: function(value) { encode: function(value) {
@ -7101,9 +7148,12 @@ var coderDynamicBytes = {
return result; return result;
}, },
dynamic: true dynamic: true
}; };
}
var coderString = { var coderString = function(localName) {
return {
localName: localName,
name: 'string', name: 'string',
type: 'string', type: 'string',
encode: function(value) { encode: function(value) {
@ -7115,7 +7165,8 @@ var coderString = {
return result; return result;
}, },
dynamic: true dynamic: true
}; };
}
function alignSize(size) { function alignSize(size) {
return parseInt(32 * Math.ceil(size / 32)); return parseInt(32 * Math.ceil(size / 32));
@ -7160,12 +7211,10 @@ function pack(coders, values) {
return data; return data;
} }
function unpack(coders, data, offset) { function unpack(coders, data, offset) {
var baseOffset = offset; var baseOffset = offset;
var consumed = 0; var consumed = 0;
var value = []; var value = [];
coders.forEach(function(coder) { coders.forEach(function(coder) {
if (coder.dynamic) { if (coder.dynamic) {
var dynamicOffset = uint256Coder.decode(data, offset); var dynamicOffset = uint256Coder.decode(data, offset);
@ -7184,6 +7233,20 @@ function unpack(coders, data, offset) {
consumed += result.consumed; consumed += result.consumed;
}); });
coders.forEach(function(coder, index) {
var name = coder.localName;
if (!name) { return; }
if (typeof(name) === 'object') { name = name.name; }
if (!name) { return; }
if (name === 'length') { name = '_length'; }
if (value[name] != null) { return; }
value[name] = value[index];
});
return { return {
value: value, value: value,
consumed: consumed consumed: consumed
@ -7192,11 +7255,12 @@ function unpack(coders, data, offset) {
return result; return result;
} }
function coderArray(coder, length) { function coderArray(coder, length, localName) {
var type = (coder.type + '[' + (length >= 0 ? length: '') + ']'); var type = (coder.type + '[' + (length >= 0 ? length: '') + ']');
return { return {
coder: coder, coder: coder,
localName: localName,
length: length, length: length,
name: 'array', name: 'array',
type: type, type: type,
@ -7245,7 +7309,7 @@ function coderArray(coder, length) {
} }
function coderTuple(coders) { function coderTuple(coders, localName) {
var dynamic = false; var dynamic = false;
var types = []; var types = [];
coders.forEach(function(coder) { coders.forEach(function(coder) {
@ -7257,14 +7321,21 @@ function coderTuple(coders) {
return { return {
coders: coders, coders: coders,
localName: localName,
name: 'tuple', name: 'tuple',
type: type, type: type,
encode: function(value) { encode: function(value) {
if (Array.isArray(value)) {
if (coders.length !== coders.length) { if (coders.length !== value.length) {
throwError('types/values mismatch', { type: type, values: values }); throwError('types/values mismatch', { type: type, values: values });
} }
// @TODO: If receiving an object, and we have names, create the array
} else {
throwError('invalid value', { type: types, values: values });
}
return pack(coders, value); return pack(coders, value);
}, },
decode: function(data, offset) { decode: function(data, offset) {
@ -7315,10 +7386,9 @@ var paramTypeSimple = {
bytes: coderDynamicBytes, bytes: coderDynamicBytes,
}; };
function getParamCoder(type) { function getParamCoder(type, localName) {
var coder = paramTypeSimple[type]; var coder = paramTypeSimple[type];
if (coder) { return coder; } if (coder) { return coder(localName); }
var match = type.match(paramTypeNumber); var match = type.match(paramTypeNumber);
if (match) { if (match) {
@ -7326,7 +7396,7 @@ function getParamCoder(type) {
if (size === 0 || size > 256 || (size % 8) !== 0) { if (size === 0 || size > 256 || (size % 8) !== 0) {
throwError('invalid type', { type: type }); throwError('invalid type', { type: type });
} }
return coderNumber(size / 8, (match[1] === 'int')); return coderNumber(size / 8, (match[1] === 'int'), localName);
} }
var match = type.match(paramTypeBytes); var match = type.match(paramTypeBytes);
@ -7335,21 +7405,26 @@ function getParamCoder(type) {
if (size === 0 || size > 32) { if (size === 0 || size > 32) {
throwError('invalid type ' + type); throwError('invalid type ' + type);
} }
return coderFixedBytes(size); return coderFixedBytes(size, localName);
} }
var match = type.match(paramTypeArray); var match = type.match(paramTypeArray);
if (match) { if (match) {
var size = parseInt(match[2] || -1); var size = parseInt(match[2] || -1);
return coderArray(getParamCoder(match[1]), size); return coderArray(getParamCoder(match[1], localName), size, localName);
} }
if (type.substring(0, 6) === 'tuple(' && type.substring(type.length - 1) === ')') { if (type.substring(0, 6) === 'tuple(' && type.substring(type.length - 1) === ')') {
var coders = []; var coders = [];
splitNesting(type.substring(6, type.length - 1)).forEach(function(type) { var names = [];
coders.push(getParamCoder(type)); if (localName && typeof(localName) === 'object') {
if (Array.isArray(localName.names)) { names = localName.names; }
if (typeof(localName.name) === 'string') { localName = localName.name; }
}
splitNesting(type.substring(6, type.length - 1)).forEach(function(type, index) {
coders.push(getParamCoder(type, names[index]));
}); });
return coderTuple(coders); return coderTuple(coders, localName);
} }
if (type === '') { if (type === '') {
@ -7379,6 +7454,11 @@ utils.defineProperty(TransactionDescription.prototype, 'type', 'transaction');
function EventDescription() { } function EventDescription() { }
utils.defineProperty(EventDescription.prototype, 'type', 'event'); utils.defineProperty(EventDescription.prototype, 'type', 'event');
function Indexed(value) {
utils.defineProperty(this, 'indexed', true);
utils.defineProperty(this, 'hash', value);
}
function Interface(abi) { function Interface(abi) {
if (!(this instanceof Interface)) { throw new Error('missing new'); } if (!(this instanceof Interface)) { throw new Error('missing new'); }
@ -7403,6 +7483,7 @@ function Interface(abi) {
switch (method.type) { switch (method.type) {
case 'constructor': case 'constructor':
var func = (function() { var func = (function() {
// @TODO: Move to parseParams
var inputTypes = getKeys(method.inputs, 'type'); var inputTypes = getKeys(method.inputs, 'type');
var func = function(bytecode) { var func = function(bytecode) {
if (!utils.isHexString(bytecode)) { if (!utils.isHexString(bytecode)) {
@ -7423,6 +7504,7 @@ function Interface(abi) {
return populateDescription(new DeployDescription(), result); return populateDescription(new DeployDescription(), result);
} }
// @TODO: Move to parseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name')); defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
return func; return func;
@ -7434,13 +7516,16 @@ function Interface(abi) {
case 'function': case 'function':
var func = (function() { var func = (function() {
var inputTypes = getKeys(method.inputs, 'type'); var inputParams = parseParams(method.inputs);
var outputParams = parseParams(method.outputs);
var inputTypes = inputParams.types;
if (method.constant) { if (method.constant) {
var outputTypes = getKeys(method.outputs, 'type'); var outputTypes = outputParams.types;
var outputNames = getKeys(method.outputs, 'name', true); var outputNames = outputParams.names;
} }
var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')'; var signature = method.name + '(' + inputParams.types.join(',') + ')';
var sighash = utils.keccak256(utils.toUtf8Bytes(signature)).substring(0, 10); var sighash = utils.keccak256(utils.toUtf8Bytes(signature)).substring(0, 10);
var func = function() { var func = function() {
var result = { var result = {
@ -7472,6 +7557,7 @@ function Interface(abi) {
return populateDescription(new TransactionDescription(), result); return populateDescription(new TransactionDescription(), result);
} }
// @TODO: Move the paraseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name')); defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
defineFrozen(func, 'outputs', getKeys(method.outputs, 'name')); defineFrozen(func, 'outputs', getKeys(method.outputs, 'name'));
utils.defineProperty(func, 'signature', signature); utils.defineProperty(func, 'signature', signature);
@ -7490,8 +7576,10 @@ function Interface(abi) {
case 'event': case 'event':
var func = (function() { var func = (function() {
// @TODO: Move to parseParams
var inputTypes = getKeys(method.inputs, 'type'); var inputTypes = getKeys(method.inputs, 'type');
var func = function() { var func = function() {
// @TODO: Move to parseParams
var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')'; var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')';
var result = { var result = {
inputs: method.inputs, inputs: method.inputs,
@ -7501,27 +7589,41 @@ function Interface(abi) {
}; };
result.parse = function(topics, data) { result.parse = function(topics, data) {
if (data == null) {
data = topics;
topics = null;
}
// Strip the signature off of non-anonymous topics // Strip the signature off of non-anonymous topics
if (!method.anonymous) { topics = topics.slice(1); } if (topics != null && !method.anonymous) { topics = topics.slice(1); }
var inputNamesIndexed = [], inputNamesNonIndexed = []; var inputNamesIndexed = [], inputNamesNonIndexed = [];
var inputTypesIndexed = [], inputTypesNonIndexed = []; var inputTypesIndexed = [], inputTypesNonIndexed = [];
var inputDynamic = [];
method.inputs.forEach(function(input) { method.inputs.forEach(function(input) {
if (input.indexed) { if (input.indexed) {
inputNamesIndexed.push(input.name); if (input.type === 'string' || input.type === 'bytes' || input.type.indexOf('[') >= 0) {
inputTypesIndexed.push('bytes32');
inputDynamic.push(true);
} else {
inputTypesIndexed.push(input.type); inputTypesIndexed.push(input.type);
inputDynamic.push(false);
}
inputNamesIndexed.push(input.name);
} else { } else {
inputNamesNonIndexed.push(input.name); inputNamesNonIndexed.push(input.name);
inputTypesNonIndexed.push(input.type); inputTypesNonIndexed.push(input.type);
inputDynamic.push(false);
} }
}); });
if (topics != null) {
var resultIndexed = Interface.decodeParams( var resultIndexed = Interface.decodeParams(
inputNamesIndexed, inputNamesIndexed,
inputTypesIndexed, inputTypesIndexed,
utils.concat(topics) utils.concat(topics)
); );
}
var resultNonIndexed = Interface.decodeParams( var resultNonIndexed = Interface.decodeParams(
inputNamesNonIndexed, inputNamesNonIndexed,
@ -7533,7 +7635,19 @@ function Interface(abi) {
var nonIndexedIndex = 0, indexedIndex = 0; var nonIndexedIndex = 0, indexedIndex = 0;
method.inputs.forEach(function(input, i) { method.inputs.forEach(function(input, i) {
if (input.indexed) { if (input.indexed) {
if (topics == null) {
result[i] = new Indexed(null);
} else if (inputDynamic[i]) {
result[i] = new Indexed(resultIndexed[indexedIndex++]);
/*{
indexed: true,
hash: resultIndexed[indexedIndex++]
};
*/
} else {
result[i] = resultIndexed[indexedIndex++]; result[i] = resultIndexed[indexedIndex++];
}
} else { } else {
result[i] = resultNonIndexed[nonIndexedIndex++]; result[i] = resultNonIndexed[nonIndexedIndex++];
} }
@ -7547,6 +7661,7 @@ function Interface(abi) {
return populateDescription(new EventDescription(), result); return populateDescription(new EventDescription(), result);
} }
// @TODO: Move to parseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name')); defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
return func; return func;
@ -7599,39 +7714,18 @@ utils.defineProperty(Interface, 'decodeParams', function(names, types, data) {
if (arguments.length < 3) { if (arguments.length < 3) {
data = types; data = types;
types = names; types = names;
names = []; names = null;
} }
data = utils.arrayify(data); data = utils.arrayify(data);
var coders = []; var coders = [];
types.forEach(function(type) { types.forEach(function(type, index) {
coders.push(getParamCoder(type)); coders.push(getParamCoder(type, (names ? names[index]: undefined)));
}); });
var result = coderTuple(coders).decode(data, 0);
// @TODO: Move this into coderTuple
var values = new Result(); var values = new Result();
coders.forEach(function(coder, index) { return coderTuple(coders).decode(data, 0).value;
values[index] = result.value[index];
if (names && names[index]) {
var name = names[index];
if (name === 'length') {
console.log('WARNING: result length renamed to _length');
name = '_length';
}
if (values[name] == null) {
values[name] = values[index];
} else {
console.log('WARNING: duplicate value - ' + name);
}
}
})
values.length = types.length;
return values;
}); });
module.exports = Interface; module.exports = Interface;
@ -8279,6 +8373,7 @@ var utils = (function() {
isHexString: convert.isHexString, isHexString: convert.isHexString,
concat: convert.concat, concat: convert.concat,
stripZeros: convert.stripZeros,
namehash: require('ethers-utils/namehash'), namehash: require('ethers-utils/namehash'),
@ -8448,7 +8543,7 @@ function checkTransaction(transaction) {
// Some clients (TestRPC) do strange things like return 0x0 for the // Some clients (TestRPC) do strange things like return 0x0 for the
// 0 address; correct this to be a real address // 0 address; correct this to be a real address
if (transaction.to && utils.bigNumberify(transaction.to).isZero) { if (transaction.to && utils.bigNumberify(transaction.to).isZero()) {
transaction.to = '0x0000000000000000000000000000000000000000'; transaction.to = '0x0000000000000000000000000000000000000000';
} }
@ -8467,15 +8562,15 @@ function checkTransaction(transaction) {
// Very loose providers (e.g. TestRPC) don't provide a signature or raw // Very loose providers (e.g. TestRPC) don't provide a signature or raw
if (transaction.v && transaction.r && transaction.s) { if (transaction.v && transaction.r && transaction.s) {
var raw = [ var raw = [
utils.hexlify(transaction.nonce), utils.stripZeros(utils.hexlify(transaction.nonce)),
utils.hexlify(transaction.gasPrice), utils.stripZeros(utils.hexlify(transaction.gasPrice)),
utils.hexlify(transaction.gasLimit), utils.stripZeros(utils.hexlify(transaction.gasLimit)),
(transaction.to || "0x"), (transaction.to || "0x"),
utils.hexlify(transaction.value || '0x'), utils.stripZeros(utils.hexlify(transaction.value || '0x')),
utils.hexlify(transaction.data || '0x'), utils.hexlify(transaction.data || '0x'),
utils.hexlify(transaction.v || '0x'), utils.stripZeros(utils.hexlify(transaction.v || '0x')),
utils.hexlify(transaction.r), utils.stripZeros(utils.hexlify(transaction.r)),
utils.hexlify(transaction.s), utils.stripZeros(utils.hexlify(transaction.s)),
]; ];
transaction.raw = utils.RLP.encode(raw); transaction.raw = utils.RLP.encode(raw);

6
dist/ethers.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -10,8 +10,8 @@
"version": "grunt dist" "version": "grunt dist"
}, },
"dependencies": { "dependencies": {
"ethers-contracts": "^2.1.5", "ethers-contracts": "^2.1.6",
"ethers-providers": "^2.1.11", "ethers-providers": "^2.1.12",
"ethers-utils": "^2.1.7", "ethers-utils": "^2.1.7",
"ethers-wallet": "^2.1.4" "ethers-wallet": "^2.1.4"
}, },