The eth_getFilterLogs
method returns an array of all logs matching the filter with the given ID. Unlike eth_getFilterChanges
, which only returns new logs since the last poll, this method returns all logs that match the original filter criteria, regardless of whether they've been returned before, making it perfect for initializing application state or backfilling missed events.
This method takes a filter ID and returns all logs that match the filter criteria, providing a comprehensive view of historical events.
The filter ID returned by eth_newFilter
Array of all log objects matching the filter criteria
{
"jsonrpc": "2.0",
"id": 1,
"result": [
{
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0",
"0x00000000000000000000000023a6b9c321aba35d18ca26e66824e917778d9d2b"
],
"data": "0x0000000000000000000000000000000000000000000000003635c9adc5dea00000",
"blockNumber": "0x10892bc",
"transactionHash": "0x56b28388cadcf4da8cbd30aa3c3f126e0513550e6fab6fc20992f3e1435846c8",
"transactionIndex": "0x3",
"blockHash": "0x6b092af2e8fbe2ceba2034ef4f334f3274a1cce5ffe955fa1895565d9278dac7",
"logIndex": "0x7",
"removed": false
},
{
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000b5d85cbf7cb3ee0d56b3bb207d5fc4b82f43f511",
"0x00000000000000000000000023a6b9c321aba35d18ca26e66824e917778d9d2b"
],
"data": "0x00000000000000000000000000000000000000000000000000000000007a1200",
"blockNumber": "0x10892be",
"transactionHash": "0xbb3a336e3f823ec18197f1e13ee875700f08f03e2cab75f0d0b118dabb44cba0",
"transactionIndex": "0x6",
"blockHash": "0x429e967f9b3b86ee1349669ebb49c5c4a7690287a6d215cc8d7e07d891823d33",
"logIndex": "0x5",
"removed": false
}
]
}
Each log object contains the following comprehensive data:
true
if the log was removed due to a chain reorganizationTo properly use event data, you need to decode it according to the event's ABI:
// Example: Decoding an ERC-20 Transfer event
function decodeTransferEvent(log) {
// ERC-20 Transfer: event Transfer(address indexed from, address indexed to, uint256 value)
// From and To are indexed parameters (in topics)
const from = '0x' + log.topics[1].slice(26); // Remove padding
const to = '0x' + log.topics[2].slice(26); // Remove padding
// Value is a non-indexed parameter (in data)
const value = BigInt(log.data);
return { from, to, value };
}
// Usage
const transferEvents = logs
.filter(log => log.topics[0] === '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef')
.map(decodeTransferEvent);
Both eth_getFilterLogs
and eth_getLogs
return logs matching criteria, but they have important differences:
Filter-based vs. Direct Query:
eth_getFilterLogs
requires creating a filter first with eth_newFilter
eth_getLogs
takes filter criteria directly in the requestFilter Reusability:
eth_getFilterLogs
, you can reuse the same filter ID for multiple callseth_getLogs
, you must specify the criteria every timeResource Management:
eth_getFilterLogs
relies on server-side filter state, which may expireeth_getLogs
is stateless and doesn't rely on server-side filter stateTypical Use Cases:
eth_getFilterLogs
is useful in combination with eth_getFilterChanges
for ongoing monitoringeth_getLogs
is often simpler for one-time historical queriesHere are some typical filter patterns used with this method:
// 1. ERC-20 token transfers for a specific address
async function getTokenTransfersForAddress(tokenAddress, userAddress) {
const transferEventSignature = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
const userAddressPadded = userAddress.replace('0x', '0x000000000000000000000000');
// Create filter for incoming or outgoing transfers
const filterId = await provider.send('eth_newFilter', [{
address: tokenAddress,
topics: [
transferEventSignature,
[userAddressPadded, null], // From (outgoing) - OR condition
[userAddressPadded, null] // To (incoming) - OR condition
],
fromBlock: '0x1000000', // Starting block number (adjust as needed)
toBlock: 'latest'
}]);
// Get all matching logs
return provider.send('eth_getFilterLogs', [filterId]);
}
// 2. Smart contract events for a specific function
async function getSwapEvents(poolAddress) {
const swapEventSignature = '0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822';
const filterId = await provider.send('eth_newFilter', [{
address: poolAddress,
topics: [swapEventSignature],
fromBlock: '0x1000000',
toBlock: 'latest'
}]);
return provider.send('eth_getFilterLogs', [filterId]);
}