sevm
Version:
A Symbolic Ethereum Virtual Machine (EVM) bytecode decompiler & analyzer library & CLI
58 lines (45 loc) • 2.08 kB
JavaScript
/* eslint-env node */
/* eslint-disable @typescript-eslint/no-var-requires */
const sevm = require('sevm');
sevm.Contract.prototype.patch = async function (/** @type {Partial<import('.').Lookup>} */lookup = {}) {
const keys = Object.keys;
/** @type {(selector: string) => string} */
const hex = selector => '0x' + selector;
const functions = [...keys(this.functions), ...keys(this.reverts)].map(hex).join(',');
const events = keys(this.events).map(hex).join(',');
if (!lookup.function || !lookup.event) {
const url = `https://api.openchain.xyz/signature-database/v1/lookup?function=${functions}&event=${events}`;
const resp = await fetch(url);
if (!resp.ok) {
throw new Error(`Failed to fetch signatures from api.openchain.xyz, url: ${url}`);
}
/** @typedef {{ [hash: string]: {name: string, filtered: boolean}[] | null }} HashesResponse */
const { result } = /** @type {{result: { function: HashesResponse, event: HashesResponse }}} */ (await resp.json());
/**
* @param {HashesResponse} hashes
* @returns {{ [hash: string]: string[] }}
*/
const mapHashes = hashes => Object.fromEntries(
Object.entries(hashes).map(([hash, matches]) => [hash, matches?.map(({ name }) => name) ?? []])
);
lookup.function = mapHashes(result.function);
lookup.event = mapHashes(result.event);
}
for (let [selector, fn] of Object.entries(this.functions)) {
selector = '0x' + selector;
if (selector in lookup.function)
fn.label = lookup.function[selector][0];
}
for (let [topic, event] of Object.entries(this.events)) {
topic = '0x' + topic;
if (topic in lookup.event)
event.sig = lookup.event[topic][0];
}
for (let [selector, decl] of Object.entries(this.reverts)) {
selector = '0x' + selector;
if (selector in lookup.function)
decl.sig = lookup.function[selector][0];
}
return this;
};
module.exports = sevm;