2
0
mirror of synced 2025-02-23 19:48:28 +00:00

Moved bare ABI named functions and events from Interface into Contracts to simplify other consumers of Interface.

This commit is contained in:
Richard Moore 2019-11-19 18:13:58 +09:00
parent 1ec5804bd4
commit da8ca2e8bc
No known key found for this signature in database
GPG Key ID: 665176BE8E9DC651
2 changed files with 103 additions and 16 deletions

View File

@ -111,6 +111,7 @@ export class Interface {
});
// Add any fragments with a unique name by its name (sans signature parameters)
/*
[this.events, this.functions].forEach((bucket) => {
let count = getNameCount(bucket);
Object.keys(bucket).forEach((signature) => {
@ -122,6 +123,7 @@ export class Interface {
bucket[fragment.name] = fragment;
});
});
*/
// If we do not have a constructor use the default "constructor() payable"
if (!this.deploy) {
@ -149,32 +151,67 @@ export class Interface {
getFunction(nameOrSignatureOrSighash: string): FunctionFragment {
if (isHexString(nameOrSignatureOrSighash)) {
return <FunctionFragment>getFragment(nameOrSignatureOrSighash, this.getSighash.bind(this), this.functions);
for (const name in this.functions) {
if (nameOrSignatureOrSighash === this.getSighash(name)) {
return this.functions[name];
}
}
logger.throwArgumentError("no matching function", "sighash", nameOrSignatureOrSighash);
}
// It is a bare name, look up the function (will return null if ambiguous)
if (nameOrSignatureOrSighash.indexOf("(") === -1) {
return (this.functions[nameOrSignatureOrSighash.trim()] || null);
const name = nameOrSignatureOrSighash.trim();
const matching = Object.keys(this.functions).filter((f) => (f.split("("/* fix:) */)[0] === name));
if (matching.length === 0) {
logger.throwArgumentError("no matching function", "name", name);
} else if (matching.length > 1) {
logger.throwArgumentError("multiple matching functions", "name", name);
}
return this.functions[matching[0]];
}
// Normlize the signature and lookup the function
return this.functions[FunctionFragment.fromString(nameOrSignatureOrSighash).format()];
const result = this.functions[FunctionFragment.fromString(nameOrSignatureOrSighash).format()];
if (!result) {
logger.throwArgumentError("no matching function", "signature", nameOrSignatureOrSighash);
}
return result;
}
getEvent(nameOrSignatureOrTopic: string): EventFragment {
if (isHexString(nameOrSignatureOrTopic)) {
return <EventFragment>getFragment(nameOrSignatureOrTopic, this.getEventTopic.bind(this), this.events);
const topichash = nameOrSignatureOrTopic.toLowerCase();
for (const name in this.events) {
if (topichash === this.getEventTopic(name)) {
return this.events[name];
}
}
logger.throwArgumentError("no matching event", "topichash", topichash);
}
// It is a bare name, look up the function (will return null if ambiguous)
if (nameOrSignatureOrTopic.indexOf("(") === -1) {
return this.events[nameOrSignatureOrTopic];
const name = nameOrSignatureOrTopic.trim();
const matching = Object.keys(this.events).filter((f) => (f.split("("/* fix:) */)[0] === name));
if (matching.length === 0) {
logger.throwArgumentError("no matching event", "name", name);
} else if (matching.length > 1) {
logger.throwArgumentError("multiple matching events", "name", name);
}
return this.events[matching[0]];
}
return this.events[EventFragment.fromString(nameOrSignatureOrTopic).format()];
// Normlize the signature and lookup the function
const result = this.events[EventFragment.fromString(nameOrSignatureOrTopic).format()];
if (!result) {
logger.throwArgumentError("no matching event", "signature", nameOrSignatureOrTopic);
}
return result;
}
getSighash(functionFragment: FunctionFragment | string): string {
if (typeof(functionFragment) === "string") {
functionFragment = this.getFunction(functionFragment);
@ -425,7 +462,7 @@ export class Interface {
return !!(value && value._isInterface);
}
}
/*
function getFragment(hash: string, calcFunc: (f: Fragment) => string, items: { [ sig: string ]: Fragment } ) {
for (let signature in items) {
if (signature.indexOf("(") === -1) { continue; }
@ -434,7 +471,8 @@ function getFragment(hash: string, calcFunc: (f: Fragment) => string, items: { [
}
return null;
}
*/
/*
function getNameCount(fragments: { [ signature: string ]: Fragment }): { [ name: string ]: number } {
let unique: { [ name: string ]: number } = { };
@ -447,3 +485,4 @@ function getNameCount(fragments: { [ signature: string ]: Fragment }): { [ name:
return unique;
}
*/

View File

@ -113,6 +113,16 @@ type RunOptions = {
transaction?: boolean;
};
/*
export function _populateTransaction(func: FunctionFragment, args: Array<any>, overrides?: any): Promise<Transaction> {
return null;
}
export function _sendTransaction(func: FunctionFragment, args: Array<any>, overrides?: any): Promise<Transaction> {
return null;
}
*/
function runMethod(contract: Contract, functionName: string, options: RunOptions): RunFunction {
let method = contract.interface.functions[functionName];
return function(...params): Promise<any> {
@ -463,15 +473,29 @@ export class Contract {
defineReadOnly(this, "filters", { });
Object.keys(this.interface.events).forEach((eventName) => {
let event = this.interface.events[eventName];
defineReadOnly(this.filters, eventName, (...args: Array<any>) => {
return {
address: this.address,
topics: this.interface.encodeFilterTopics(event, args)
{
const uniqueFilters: { [ name: string ]: Array<string> } = { };
Object.keys(this.interface.events).forEach((eventSignature) => {
let event = this.interface.events[eventSignature];
defineReadOnly(this.filters, eventSignature, (...args: Array<any>) => {
return {
address: this.address,
topics: this.interface.encodeFilterTopics(event, args)
}
});
if (!uniqueFilters[event.name]) { uniqueFilters[event.name] = [ ]; }
uniqueFilters[event.name].push(eventSignature);
});
Object.keys(uniqueFilters).forEach((name) => {
const filters = uniqueFilters[name];
if (filters.length === 1) {
defineReadOnly(this.filters, name, this.filters[filters[0]]);
} else {
logger.warn(`Duplicate definition of ${ name } (${ filters.join(", ")})`);
}
});
});
}
defineReadOnly(this, "_runningEvents", { });
defineReadOnly(this, "_wrappedEmits", { });
@ -494,7 +518,11 @@ export class Contract {
}
}
const uniqueFunctions: { [ name: string ]: Array<string> } = { };
Object.keys(this.interface.functions).forEach((name) => {
const fragment = this.interface.functions[name];
// @TODO: This should take in fragment
let run = runMethod(this, name, { });
if (this[name] == null) {
@ -516,6 +544,26 @@ export class Contract {
if (this.estimate[name] == null) {
defineReadOnly(this.estimate, name, runMethod(this, name, { estimate: true }));
}
if (!uniqueFunctions[fragment.name]) { uniqueFunctions[fragment.name] = [ ]; }
uniqueFunctions[fragment.name].push(name);
});
Object.keys(uniqueFunctions).forEach((name) => {
const signatures = uniqueFunctions[name];
if (signatures.length > 1) {
logger.warn(`Duplicate definition of ${ name } (${ signatures.join(", ")})`);
return;
}
if (this[name] == null) {
defineReadOnly(this, name, this[signatures[0]]);
}
defineReadOnly(this.functions, name, this.functions[signatures[0]]);
defineReadOnly(this.callStatic, name, this.callStatic[signatures[0]]);
defineReadOnly(this.populateTransaction, name, this.populateTransaction[signatures[0]]);
defineReadOnly(this.estimate, name, this.estimate[signatures[0]]);
});
}