Added formatParamType and formatSignature.

This commit is contained in:
Richard Moore 2018-06-24 20:32:14 -04:00
parent c348c60d5c
commit fcd57f9756
No known key found for this signature in database
GPG Key ID: 525F70A6FCABC295
10 changed files with 68 additions and 142 deletions

View File

@ -21,38 +21,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
var abi_coder_1 = require("../utils/abi-coder"); var abi_coder_1 = require("../utils/abi-coder");
var bignumber_1 = require("../utils/bignumber"); var bignumber_1 = require("../utils/bignumber");
var bytes_1 = require("../utils/bytes"); var bytes_1 = require("../utils/bytes");
var keccak256_1 = require("../utils/keccak256"); var hash_1 = require("../utils/hash");
var utf8_1 = require("../utils/utf8");
var properties_1 = require("../utils/properties"); var properties_1 = require("../utils/properties");
var errors = __importStar(require("../utils/errors")); var errors = __importStar(require("../utils/errors"));
// @TODO: Replace with a new abiCode.formatSignature method
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 Description = /** @class */ (function () { var Description = /** @class */ (function () {
function Description(info) { function Description(info) {
for (var key in info) { for (var key in info) {
@ -68,7 +39,6 @@ var Description = /** @class */ (function () {
return Description; return Description;
}()); }());
exports.Description = Description; exports.Description = Description;
// @TOOD: Make this a description
var Indexed = /** @class */ (function (_super) { var Indexed = /** @class */ (function (_super) {
__extends(Indexed, _super); __extends(Indexed, _super);
function Indexed() { function Indexed() {
@ -236,11 +206,8 @@ function addMethod(method) {
break; break;
} }
case 'function': { case 'function': {
// @TODO: See event var signature = abi_coder_1.formatSignature(method).replace(/tuple/g, '');
var signature = '(' + parseParams(method.inputs).types.join(',') + ')'; var sighash = hash_1.id(signature).substring(0, 10);
signature = signature.replace(/tuple/g, '');
signature = method.name + signature;
var sighash = keccak256_1.keccak256(utf8_1.toUtf8Bytes(signature)).substring(0, 10);
var description = new FunctionDescription({ var description = new FunctionDescription({
inputs: method.inputs, inputs: method.inputs,
outputs: method.outputs, outputs: method.outputs,
@ -260,17 +227,12 @@ function addMethod(method) {
break; break;
} }
case 'event': { case 'event': {
// @TODO: method.params instead? As well? Different fomrat? var signature = abi_coder_1.formatSignature(method).replace(/tuple/g, '');
//let inputParams = parseParams(method.inputs);
// @TODO: Don't use parseParams (create new function in ABI, formatSignature)
var signature = '(' + parseParams(method.inputs).types.join(',') + ')';
signature = signature.replace(/tuple/g, '');
signature = method.name + signature;
var description = new EventDescription({ var description = new EventDescription({
name: method.name, name: method.name,
signature: signature, signature: signature,
inputs: method.inputs, inputs: method.inputs,
topic: keccak256_1.keccak256(utf8_1.toUtf8Bytes(signature)), topic: hash_1.id(signature),
anonymous: (!!method.anonymous), anonymous: (!!method.anonymous),
type: 'event' type: 'event'
}); });

6
dist/ethers.d.ts vendored
View File

@ -96,7 +96,7 @@ declare module 'ethers/providers/networks' {
declare module 'ethers/utils' { declare module 'ethers/utils' {
import { getAddress, getContractAddress, getIcapAddress } from 'ethers/utils/address'; import { getAddress, getContractAddress, getIcapAddress } from 'ethers/utils/address';
import { AbiCoder, defaultAbiCoder, parseSignature, parseParamType } from 'ethers/utils/abi-coder'; import { AbiCoder, defaultAbiCoder, formatSignature, formatParamType, parseSignature, parseParamType } from 'ethers/utils/abi-coder';
import * as base64 from 'ethers/utils/base64'; import * as base64 from 'ethers/utils/base64';
import { BigNumber, bigNumberify } from 'ethers/utils/bignumber'; import { BigNumber, bigNumberify } from 'ethers/utils/bignumber';
import { arrayify, concat, hexlify, joinSignature, padZeros, splitSignature, stripZeros } from 'ethers/utils/bytes'; import { arrayify, concat, hexlify, joinSignature, padZeros, splitSignature, stripZeros } from 'ethers/utils/bytes';
@ -113,7 +113,7 @@ declare module 'ethers/utils' {
import { parse as parseTransaction } from 'ethers/utils/transaction'; import { parse as parseTransaction } from 'ethers/utils/transaction';
import * as errors from 'ethers/utils/errors'; import * as errors from 'ethers/utils/errors';
const etherSymbol = "\u039E"; const etherSymbol = "\u039E";
export { AbiCoder, defaultAbiCoder, parseSignature, parseParamType, RLP, fetchJson, defineReadOnly, defineFrozen, resolveProperties, shallowCopy, etherSymbol, arrayify, concat, padZeros, stripZeros, base64, bigNumberify, BigNumber, hexlify, toUtf8Bytes, toUtf8String, hashMessage, namehash, id, getAddress, getIcapAddress, getContractAddress, formatEther, parseEther, formatUnits, parseUnits, keccak256, sha256, randomBytes, solidityPack, solidityKeccak256, soliditySha256, splitSignature, joinSignature, parseTransaction, errors }; export { AbiCoder, defaultAbiCoder, formatSignature, formatParamType, parseSignature, parseParamType, RLP, fetchJson, defineReadOnly, defineFrozen, resolveProperties, shallowCopy, etherSymbol, arrayify, concat, padZeros, stripZeros, base64, bigNumberify, BigNumber, hexlify, toUtf8Bytes, toUtf8String, hashMessage, namehash, id, getAddress, getIcapAddress, getContractAddress, formatEther, parseEther, formatUnits, parseUnits, keccak256, sha256, randomBytes, solidityPack, solidityKeccak256, soliditySha256, splitSignature, joinSignature, parseTransaction, errors };
const _default: { const _default: {
AbiCoder: typeof AbiCoder; AbiCoder: typeof AbiCoder;
defaultAbiCoder: AbiCoder; defaultAbiCoder: AbiCoder;
@ -563,6 +563,8 @@ declare module 'ethers/utils/abi-coder' {
stateMutability: string; stateMutability: string;
}; };
export function parseParamType(type: string): ParamType; export function parseParamType(type: string): ParamType;
export function formatParamType(paramType: ParamType): string;
export function formatSignature(fragment: EventFragment | FunctionFragment): string;
export function parseSignature(fragment: string): EventFragment | FunctionFragment; export function parseSignature(fragment: string): EventFragment | FunctionFragment;
export class AbiCoder { export class AbiCoder {
readonly coerceFunc: CoerceFunc; readonly coerceFunc: CoerceFunc;

65
dist/ethers.js vendored
View File

@ -9234,38 +9234,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
var abi_coder_1 = require("../utils/abi-coder"); var abi_coder_1 = require("../utils/abi-coder");
var bignumber_1 = require("../utils/bignumber"); var bignumber_1 = require("../utils/bignumber");
var bytes_1 = require("../utils/bytes"); var bytes_1 = require("../utils/bytes");
var keccak256_1 = require("../utils/keccak256"); var hash_1 = require("../utils/hash");
var utf8_1 = require("../utils/utf8");
var properties_1 = require("../utils/properties"); var properties_1 = require("../utils/properties");
var errors = __importStar(require("../utils/errors")); var errors = __importStar(require("../utils/errors"));
// @TODO: Replace with a new abiCode.formatSignature method
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 Description = /** @class */ (function () { var Description = /** @class */ (function () {
function Description(info) { function Description(info) {
for (var key in info) { for (var key in info) {
@ -9281,7 +9252,6 @@ var Description = /** @class */ (function () {
return Description; return Description;
}()); }());
exports.Description = Description; exports.Description = Description;
// @TOOD: Make this a description
var Indexed = /** @class */ (function (_super) { var Indexed = /** @class */ (function (_super) {
__extends(Indexed, _super); __extends(Indexed, _super);
function Indexed() { function Indexed() {
@ -9449,11 +9419,8 @@ function addMethod(method) {
break; break;
} }
case 'function': { case 'function': {
// @TODO: See event var signature = abi_coder_1.formatSignature(method).replace(/tuple/g, '');
var signature = '(' + parseParams(method.inputs).types.join(',') + ')'; var sighash = hash_1.id(signature).substring(0, 10);
signature = signature.replace(/tuple/g, '');
signature = method.name + signature;
var sighash = keccak256_1.keccak256(utf8_1.toUtf8Bytes(signature)).substring(0, 10);
var description = new FunctionDescription({ var description = new FunctionDescription({
inputs: method.inputs, inputs: method.inputs,
outputs: method.outputs, outputs: method.outputs,
@ -9473,17 +9440,12 @@ function addMethod(method) {
break; break;
} }
case 'event': { case 'event': {
// @TODO: method.params instead? As well? Different fomrat? var signature = abi_coder_1.formatSignature(method).replace(/tuple/g, '');
//let inputParams = parseParams(method.inputs);
// @TODO: Don't use parseParams (create new function in ABI, formatSignature)
var signature = '(' + parseParams(method.inputs).types.join(',') + ')';
signature = signature.replace(/tuple/g, '');
signature = method.name + signature;
var description = new EventDescription({ var description = new EventDescription({
name: method.name, name: method.name,
signature: signature, signature: signature,
inputs: method.inputs, inputs: method.inputs,
topic: keccak256_1.keccak256(utf8_1.toUtf8Bytes(signature)), topic: hash_1.id(signature),
anonymous: (!!method.anonymous), anonymous: (!!method.anonymous),
type: 'event' type: 'event'
}); });
@ -9591,7 +9553,7 @@ var Interface = /** @class */ (function () {
}()); }());
exports.Interface = Interface; exports.Interface = Interface;
},{"../utils/abi-coder":58,"../utils/bignumber":60,"../utils/bytes":61,"../utils/errors":62,"../utils/keccak256":65,"../utils/properties":66,"../utils/utf8":73}],50:[function(require,module,exports){ },{"../utils/abi-coder":58,"../utils/bignumber":60,"../utils/bytes":61,"../utils/errors":62,"../utils/hash":63,"../utils/properties":66}],50:[function(require,module,exports){
"use strict"; "use strict";
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = Object.setPrototypeOf ||
@ -12015,6 +11977,16 @@ function parseParamType(type) {
return parseParam(type, true); return parseParam(type, true);
} }
exports.parseParamType = parseParamType; exports.parseParamType = parseParamType;
// @TODO: Allow a second boolean to expose names
function formatParamType(paramType) {
return getParamCoder(exports.defaultCoerceFunc, paramType).type;
}
exports.formatParamType = formatParamType;
// @TODO: Allow a second boolean to expose names and modifiers
function formatSignature(fragment) {
return fragment.name + '(' + fragment.inputs.map(function (i) { return formatParamType(i); }).join(',') + ')';
}
exports.formatSignature = formatSignature;
function parseSignature(fragment) { function parseSignature(fragment) {
if (typeof (fragment) === 'string') { if (typeof (fragment) === 'string') {
// Make sure the "returns" is surrounded by a space and all whitespace is exactly one space // Make sure the "returns" is surrounded by a space and all whitespace is exactly one space
@ -12582,6 +12554,7 @@ function getParamCoder(coerceFunc, param) {
var match = param.type.match(paramTypeArray); var match = param.type.match(paramTypeArray);
if (match) { if (match) {
var size = parseInt(match[2] || "-1"); var size = parseInt(match[2] || "-1");
param = properties_1.jsonCopy(param);
param.type = match[1]; param.type = match[1];
return new CoderArray(coerceFunc, getParamCoder(coerceFunc, param), size, param.name); return new CoderArray(coerceFunc, getParamCoder(coerceFunc, param), size, param.name);
} }
@ -12622,7 +12595,7 @@ var AbiCoder = /** @class */ (function () {
typeObject = parseParam(type); typeObject = parseParam(type);
} }
else { else {
typeObject = properties_1.jsonCopy(type); typeObject = type;
} }
coders.push(getParamCoder(this.coerceFunc, typeObject)); coders.push(getParamCoder(this.coerceFunc, typeObject));
}, this); }, this);
@ -13338,6 +13311,8 @@ exports.getIcapAddress = address_1.getIcapAddress;
var abi_coder_1 = require("./abi-coder"); var abi_coder_1 = require("./abi-coder");
exports.AbiCoder = abi_coder_1.AbiCoder; exports.AbiCoder = abi_coder_1.AbiCoder;
exports.defaultAbiCoder = abi_coder_1.defaultAbiCoder; exports.defaultAbiCoder = abi_coder_1.defaultAbiCoder;
exports.formatSignature = abi_coder_1.formatSignature;
exports.formatParamType = abi_coder_1.formatParamType;
exports.parseSignature = abi_coder_1.parseSignature; exports.parseSignature = abi_coder_1.parseSignature;
exports.parseParamType = abi_coder_1.parseParamType; exports.parseParamType = abi_coder_1.parseParamType;
var base64 = __importStar(require("./base64")); var base64 = __importStar(require("./base64"));

2
dist/ethers.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,44 +2,14 @@
// See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI // See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
import { defaultAbiCoder, EventFragment, FunctionFragment, ParamType, parseSignature } from '../utils/abi-coder'; import { defaultAbiCoder, EventFragment, formatSignature, FunctionFragment, ParamType, parseSignature } from '../utils/abi-coder';
import { BigNumber, bigNumberify, BigNumberish } from '../utils/bignumber'; import { BigNumber, bigNumberify, BigNumberish } from '../utils/bignumber';
import { arrayify, concat, isHexString } from '../utils/bytes'; import { arrayify, concat, isHexString } from '../utils/bytes';
import { keccak256 } from '../utils/keccak256'; import { id } from '../utils/hash';
import { toUtf8Bytes } from '../utils/utf8';
import { defineReadOnly, defineFrozen } from '../utils/properties'; import { defineReadOnly, defineFrozen } from '../utils/properties';
import * as errors from '../utils/errors'; import * as errors from '../utils/errors';
// @TODO: Replace with a new abiCode.formatSignature method
function parseParams(params: Array<ParamType>): { names: Array<any>, types: Array<string> } {
var names: Array<any> = [];
var types: Array<string> = [];
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
}
}
export class Description { export class Description {
readonly type: string; readonly type: string;
constructor(info: any) { constructor(info: any) {
@ -54,7 +24,6 @@ export class Description {
} }
} }
// @TOOD: Make this a description
export class Indexed extends Description { export class Indexed extends Description {
readonly hash: string; readonly hash: string;
} }
@ -231,12 +200,8 @@ function addMethod(method: any): void {
} }
case 'function': { case 'function': {
// @TODO: See event let signature = formatSignature(method).replace(/tuple/g, '');
let signature = '(' + parseParams(method.inputs).types.join(',') + ')'; let sighash = id(signature).substring(0, 10);
signature = signature.replace(/tuple/g, '');
signature = method.name + signature;
let sighash = keccak256(toUtf8Bytes(signature)).substring(0, 10);
let description = new FunctionDescription({ let description = new FunctionDescription({
inputs: method.inputs, inputs: method.inputs,
@ -263,20 +228,14 @@ function addMethod(method: any): void {
} }
case 'event': { case 'event': {
// @TODO: method.params instead? As well? Different fomrat? let signature = formatSignature(method).replace(/tuple/g, '');
//let inputParams = parseParams(method.inputs);
// @TODO: Don't use parseParams (create new function in ABI, formatSignature)
let signature = '(' + parseParams(method.inputs).types.join(',') + ')';
signature = signature.replace(/tuple/g, '');
signature = method.name + signature;
let description = new EventDescription({ let description = new EventDescription({
name: method.name, name: method.name,
signature: signature, signature: signature,
inputs: method.inputs, inputs: method.inputs,
topic: keccak256(toUtf8Bytes(signature)), topic: id(signature),
anonymous: (!!method.anonymous), anonymous: (!!method.anonymous),
type: 'event' type: 'event'

View File

@ -304,6 +304,16 @@ export function parseParamType(type: string): ParamType {
return parseParam(type, true); return parseParam(type, true);
} }
// @TODO: Allow a second boolean to expose names
export function formatParamType(paramType: ParamType): string {
return getParamCoder(defaultCoerceFunc, paramType).type;
}
// @TODO: Allow a second boolean to expose names and modifiers
export function formatSignature(fragment: EventFragment | FunctionFragment): string {
return fragment.name + '(' + fragment.inputs.map((i) => formatParamType(i)).join(',') + ')';
}
export function parseSignature(fragment: string): EventFragment | FunctionFragment { export function parseSignature(fragment: string): EventFragment | FunctionFragment {
if(typeof(fragment) === 'string') { if(typeof(fragment) === 'string') {
// Make sure the "returns" is surrounded by a space and all whitespace is exactly one space // Make sure the "returns" is surrounded by a space and all whitespace is exactly one space
@ -814,9 +824,11 @@ class CoderTuple extends Coder {
super(coerceFunc, 'tuple', type, localName, dynamic); super(coerceFunc, 'tuple', type, localName, dynamic);
this.coders = coders; this.coders = coders;
} }
encode(value: Array<any>): Uint8Array { encode(value: Array<any>): Uint8Array {
return pack(this.coders, value); return pack(this.coders, value);
} }
decode(data: Uint8Array, offset: number): DecodedResult { decode(data: Uint8Array, offset: number): DecodedResult {
var result = unpack(this.coders, data, offset); var result = unpack(this.coders, data, offset);
result.value = this.coerceFunc(this.type, result.value); result.value = this.coerceFunc(this.type, result.value);
@ -903,6 +915,7 @@ function getParamCoder(coerceFunc: CoerceFunc, param: ParamType): Coder {
var match = param.type.match(paramTypeArray); var match = param.type.match(paramTypeArray);
if (match) { if (match) {
let size = parseInt(match[2] || "-1"); let size = parseInt(match[2] || "-1");
param = jsonCopy(param);
param.type = match[1]; param.type = match[1];
return new CoderArray(coerceFunc, getParamCoder(coerceFunc, param), size, param.name); return new CoderArray(coerceFunc, getParamCoder(coerceFunc, param), size, param.name);
} }
@ -952,7 +965,7 @@ export class AbiCoder {
if (typeof(type) === 'string') { if (typeof(type) === 'string') {
typeObject = parseParam(type); typeObject = parseParam(type);
} else { } else {
typeObject = jsonCopy(type); typeObject = type;
} }
coders.push(getParamCoder(this.coerceFunc, typeObject)); coders.push(getParamCoder(this.coerceFunc, typeObject));

View File

@ -4,7 +4,7 @@
//var unorm = require('unorm'); //var unorm = require('unorm');
import { getAddress, getContractAddress, getIcapAddress } from './address'; import { getAddress, getContractAddress, getIcapAddress } from './address';
import { AbiCoder, defaultAbiCoder, parseSignature, parseParamType } from './abi-coder'; import { AbiCoder, defaultAbiCoder, formatSignature, formatParamType, parseSignature, parseParamType } from './abi-coder';
import * as base64 from './base64'; import * as base64 from './base64';
import { BigNumber, bigNumberify } from './bignumber'; import { BigNumber, bigNumberify } from './bignumber';
import { arrayify, concat, hexlify, joinSignature, padZeros, splitSignature, stripZeros } from './bytes'; import { arrayify, concat, hexlify, joinSignature, padZeros, splitSignature, stripZeros } from './bytes';
@ -31,6 +31,8 @@ const etherSymbol = '\u039e';
export { export {
AbiCoder, AbiCoder,
defaultAbiCoder, defaultAbiCoder,
formatSignature,
formatParamType,
parseSignature, parseSignature,
parseParamType, parseParamType,

View File

@ -248,6 +248,16 @@ function parseParamType(type) {
return parseParam(type, true); return parseParam(type, true);
} }
exports.parseParamType = parseParamType; exports.parseParamType = parseParamType;
// @TODO: Allow a second boolean to expose names
function formatParamType(paramType) {
return getParamCoder(exports.defaultCoerceFunc, paramType).type;
}
exports.formatParamType = formatParamType;
// @TODO: Allow a second boolean to expose names and modifiers
function formatSignature(fragment) {
return fragment.name + '(' + fragment.inputs.map(function (i) { return formatParamType(i); }).join(',') + ')';
}
exports.formatSignature = formatSignature;
function parseSignature(fragment) { function parseSignature(fragment) {
if (typeof (fragment) === 'string') { if (typeof (fragment) === 'string') {
// Make sure the "returns" is surrounded by a space and all whitespace is exactly one space // Make sure the "returns" is surrounded by a space and all whitespace is exactly one space
@ -815,6 +825,7 @@ function getParamCoder(coerceFunc, param) {
var match = param.type.match(paramTypeArray); var match = param.type.match(paramTypeArray);
if (match) { if (match) {
var size = parseInt(match[2] || "-1"); var size = parseInt(match[2] || "-1");
param = properties_1.jsonCopy(param);
param.type = match[1]; param.type = match[1];
return new CoderArray(coerceFunc, getParamCoder(coerceFunc, param), size, param.name); return new CoderArray(coerceFunc, getParamCoder(coerceFunc, param), size, param.name);
} }
@ -855,7 +866,7 @@ var AbiCoder = /** @class */ (function () {
typeObject = parseParam(type); typeObject = parseParam(type);
} }
else { else {
typeObject = properties_1.jsonCopy(type); typeObject = type;
} }
coders.push(getParamCoder(this.coerceFunc, typeObject)); coders.push(getParamCoder(this.coerceFunc, typeObject));
}, this); }, this);

View File

@ -16,6 +16,8 @@ exports.getIcapAddress = address_1.getIcapAddress;
var abi_coder_1 = require("./abi-coder"); var abi_coder_1 = require("./abi-coder");
exports.AbiCoder = abi_coder_1.AbiCoder; exports.AbiCoder = abi_coder_1.AbiCoder;
exports.defaultAbiCoder = abi_coder_1.defaultAbiCoder; exports.defaultAbiCoder = abi_coder_1.defaultAbiCoder;
exports.formatSignature = abi_coder_1.formatSignature;
exports.formatParamType = abi_coder_1.formatParamType;
exports.parseSignature = abi_coder_1.parseSignature; exports.parseSignature = abi_coder_1.parseSignature;
exports.parseParamType = abi_coder_1.parseParamType; exports.parseParamType = abi_coder_1.parseParamType;
var base64 = __importStar(require("./base64")); var base64 = __importStar(require("./base64"));