eth_getLogs - Query Event Logs
Query and filter event logs from smart contracts on Neuroweb Mainnet. Essential for tracking events, monitoring contracts, and building event-driven applications.
Returns an array of all logs matching a given filter object. Essential for querying historical events and monitoring smart contract activity.
When to Use This Method
eth_getLogs is crucial for:
- Event Monitoring - Track smart contract events and state changes
- Historical Queries - Search past events within a block range
- DeFi Analytics - Monitor trades, liquidity events, and protocol activity
- Indexing - Build databases of on-chain events
Implementation Examples
Advanced Usage
Multiple Address Filtering
{
"jsonrpc": "2.0",
"method": "eth_getLogs",
"params": [{
"fromBlock": "0x1",
"toBlock": "latest",
"address": [
"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"0x4200000000000000000000000000000000000006"
],
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
]
}],
"id": 1
}Topic Filtering with OR Logic
{
"jsonrpc": "2.0",
"method": "eth_getLogs",
"params": [{
"fromBlock": "0x1",
"toBlock": "latest",
"topics": [
[
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"
]
]
}],
"id": 1
}Notes
- Neuroweb supports historical log queries back to genesis block
- Query limits: Maximum 10,000 results per request
- Block range limits: Maximum 2,000 blocks per query for optimal performance
- Topic arrays: Support up to 4 topics with OR logic within each position
- Performance tip: Use specific address filters to improve query speed
- Event signatures: First topic is always the keccak256 hash of the event signature
Common Use Cases
1. Token Balance History
// Track historical token balance changes
async function getBalanceHistory(tokenAddress, userAddress, fromBlock) {
const monitor = new EventMonitor(provider);
// Get all transfers involving the user
const logs = await monitor.getFilteredTransfers(
tokenAddress,
userAddress,
'both',
fromBlock,
'latest'
);
// Calculate balance changes
const balanceChanges = [];
let currentBalance = 0n;
for (const log of logs) {
const iface = new Interface([
'event Transfer(address indexed from, address indexed to, uint256 value)'
]);
const decoded = iface.parseLog({
topics: log.topics,
data: log.data
});
const change = decoded.args.from.toLowerCase() === userAddress.toLowerCase() ?
-decoded.args.value : decoded.args.value;
currentBalance += change;
balanceChanges.push({
blockNumber: log.blockNumber,
transactionHash: log.transactionHash,
change: change.toString(),
balance: currentBalance.toString(),
type: change < 0 ? 'outgoing' : 'incoming'
});
}
return balanceChanges;
}2. DEX Trade Monitoring
// Monitor DEX trading activity
async function monitorDEXTrades(dexAddress, fromBlock) {
const swapTopic = id('Swap(address,address,int256,int256,uint160,uint128,int24)');
const logs = await provider.getLogs({
fromBlock: toBeHex(fromBlock),
toBlock: 'latest',
address: dexAddress,
topics: [swapTopic]
});
const trades = logs.map(log => {
// Decode Uniswap V3 swap event
const iface = new Interface([
'event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick)'
]);
const decoded = iface.parseLog({
topics: log.topics,
data: log.data
});
return {
sender: decoded.args.sender,
recipient: decoded.args.recipient,
amount0: decoded.args.amount0.toString(),
amount1: decoded.args.amount1.toString(),
price: Number(decoded.args.sqrtPriceX96) ** 2 / (2 ** 192),
blockNumber: log.blockNumber,
transactionHash: log.transactionHash
};
});
return trades;
}3. Contract Event Indexer
// Build an event index for a contract
class EventIndexer {
constructor(provider, contractAddress, abi) {
this.provider = provider;
this.contractAddress = contractAddress;
this.iface = new Interface(abi);
this.eventIndex = new Map();
}
async indexEvents(fromBlock, toBlock) {
// Get all events for the contract
const logs = await this.provider.getLogs({
fromBlock: toBeHex(fromBlock),
toBlock: toBlock === 'latest' ? 'latest' : toBeHex(toBlock),
address: this.contractAddress
});
for (const log of logs) {
try {
const parsed = this.iface.parseLog({
topics: log.topics,
data: log.data
});
if (!this.eventIndex.has(parsed.name)) {
this.eventIndex.set(parsed.name, []);
}
this.eventIndex.get(parsed.name).push({
args: Object.fromEntries(
Object.entries(parsed.args).filter(([key]) => isNaN(key))
),
blockNumber: log.blockNumber,
transactionHash: log.transactionHash,
logIndex: log.logIndex
});
} catch {
// Unknown event
}
}
return this.getStatistics();
}
getStatistics() {
const stats = {};
for (const [eventName, events] of this.eventIndex) {
stats[eventName] = {
count: events.length,
firstBlock: Math.min(...events.map(e => e.blockNumber)),
lastBlock: Math.max(...events.map(e => e.blockNumber))
};
}
return stats;
}
}