Skip to content

Instantly share code, notes, and snippets.

@wschwab
Last active August 22, 2023 07:41
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save wschwab/528153cb6f2ea17ef9eee0c180425961 to your computer and use it in GitHub Desktop.
Save wschwab/528153cb6f2ea17ef9eee0c180425961 to your computer and use it in GitHub Desktop.
a handmade Ethereum event filter that you should never really use
const eventFilter = (contractAddress, contractAbi, eventName, _provider) => {
const provider = _provider
// this will return an array with an object for each event
const events = contractAbi.abi.filter(obj => obj.type ? obj.type === "event" : false);
// getting the Transfer event and pulling it out of its array
const event = events.filter(event => event.name === eventName)[0];
// getting the types for the event signature
const types = event.inputs.map(input => input.type)
// knowing which types are indexed will be useful later
let indexedInputs = [];
let unindexedInputs = [];
event.inputs.forEach(input => {
input.indexed ?
indexedInputs.push(input) :
unindexedInputs.push(input)
});
// event signature
const eventSig = `${event.name}(${types.toString()})`;
// getting the topic
const eventTopic = ethers.utils.keccak256(eventSig);
// you could also filter by blocks using fromBlock and toBlock
const logs = provider.getLogs({
address: contractAddress,
topics: [eventTopic]
});
// need to decode the topics and events
const decoder = new ethers.utils.AbiCoder();
const decodedLogs = logs.map(log => {
// remember how we separated indexed and unindexed events?
// it was because we need to sort them differently here
const decodedTopics = indexedInputs.map(input => {
// we use the position of the type in the array as an index for the
// topic, we need to add 1 since the first topic is the event signature
const value = decoder.decode(input.type, log.topics[indexedInputs.indexOf(input) + 1]);
return `${input.name}: ${value}`;
})
const decodedDataRaw = decoder.decode(unindexedInputs, log.data);
const decodedData = unindexedInputs.map((input, i) => {
return `${input.name}: ${decodedDataRaw[i]}`
});
return [...decodedTopics, ...decodedData]
});
return decodedLogs
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment