Skip to main content

eth_getLogs

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

Parameters​

  1. Filter Object
    • fromBlock - (optional) Starting block number or tag
    • toBlock - (optional) Ending block number or tag
    • address - (optional) Contract address or array of addresses
    • topics - (optional) Array of topic filters (event signatures and indexed parameters)
    • blockHash - (optional) Restrict to single block (incompatible with fromBlock/toBlock)
{
"jsonrpc": "2.0",
"method": "eth_getLogs",
"params": [{
"fromBlock": "0x1",
"toBlock": "latest",
"address": "0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
null,
"0x000000000000000000000000a7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270"
]
}],
"id": 1
}

Returns​

Array of log objects with:

  • removed - true if log was removed due to reorg
  • logIndex - Position in the block
  • transactionIndex - Transaction position in block
  • transactionHash - Hash of transaction
  • blockHash - Hash of block
  • blockNumber - Block number
  • address - Contract address
  • data - Non-indexed log parameters
  • topics - Array of indexed log parameters

Implementation Examples​

curl -X POST https://api-bittensor-finney.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getLogs",
"params": [{
"fromBlock": "0x1",
"toBlock": "latest",
"address": "0x1234567890123456789012345678901234567890",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
]
}],
"id": 1
}'

Response Example​

{
"jsonrpc": "2.0",
"id": 1,
"result": [
{
"address": "0x1234567890123456789012345678901234567890",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000a7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270",
"0x0000000000000000000000004e6b5f1abfb9aa3cc5b3d8f4a7b8c2d9e3f0a1b2"
],
"data": "0x000000000000000000000000000000000000000000000000016345785d8a0000",
"blockNumber": "0x123abc",
"blockHash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"transactionHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"transactionIndex": "0x0",
"logIndex": "0x0",
"removed": false
}
]
}

Advanced Usage​

Multiple Address Filtering​

{
"jsonrpc": "2.0",
"method": "eth_getLogs",
"params": [{
"fromBlock": "0x1",
"toBlock": "latest",
"address": [
"0x1234567890123456789012345678901234567890",
"0x0987654321098765432109876543210987654321"
],
"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​

  • Bittensor supports AI-focused smart contract event monitoring
  • 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
  • AI integration: Optimized for tracking AI model and subnet-related events

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;
}
}

Error Handling​

Error TypeDescriptionSolution
Query limit exceededToo many logs in rangeUse pagination or reduce block range
Invalid block rangefromBlock > toBlockValidate block parameters
Node timeoutLarge query timeoutBreak into smaller queries
async function robustGetLogs(filter, maxRetries = 3) {
// Validate filter
if (filter.fromBlock > filter.toBlock && filter.toBlock !== 'latest') {
throw new Error('Invalid block range: fromBlock must be <= toBlock');
}

for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const logs = await provider.getLogs(filter);
return logs;

} catch (error) {
if (error.message.includes('query returned more than')) {
// Too many results, need pagination
const monitor = new EventMonitor(provider);
return await monitor.getPaginatedLogs(filter, 500);
}

if (error.message.includes('timeout') && attempt < maxRetries - 1) {
// Retry with exponential backoff
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, attempt) * 1000)
);
continue;
}

throw error;
}
}
}

Need help? Contact our support team or check the Bittensor documentation.