When building decentralized applications (dApps) on Ethereum, real-time monitoring of blockchain activity is essential. This is where filters and events come into play—powerful tools that allow developers to react dynamically to on-chain changes. With web3j, a lightweight Java library for integrating with Ethereum clients, handling these events becomes not only possible but efficient and scalable.
web3j simplifies the complexity of Ethereum’s JSON-RPC interface by offering fully asynchronous event handling through RxJava Observables. Whether you're tracking new blocks, pending transactions, or smart contract events, web3j abstracts away the manual polling typically required—delivering clean, reactive streams of blockchain data.
Understanding Ethereum Filters
Ethereum supports three primary types of filters:
- Block Filters
- Pending Transaction Filters
- Topic Filters
These filters notify applications when specific blockchain events occur. However, using filters over standard HTTP RPC endpoints can be inefficient due to the need for constant polling. Without WebSocket support (such as via Geth), this process becomes cumbersome and slow.
👉 Discover how real-time blockchain monitoring boosts dApp performance
Thankfully, web3j automates this workflow, managing filter lifecycle and leveraging RxJava to provide seamless asynchronous event streams—eliminating the need for manual polling and complex state tracking.
Block and Transaction Observables
With web3j, listening to blockchain updates is intuitive and code-efficient.
To receive notifications for every new block added to the chain (without full transaction details):
Subscription subscription = web3j.blockObservable(false)
.subscribe(block -> {
System.out.println("New block mined: " + block.getBlock().getNumber());
});To observe all new transactions included in confirmed blocks:
Subscription subscription = web3j.transactionObservable()
.subscribe(tx -> {
System.out.println("Transaction confirmed: " + tx.getHash());
});And to monitor transactions as soon as they’re broadcast to the network—before confirmation:
Subscription subscription = web3j.pendingTransactionObservable()
.subscribe(tx -> {
System.out.println("Pending transaction: " + tx.getHash());
});Always unsubscribe when no longer needed:
subscription.unsubscribe();
This ensures resource efficiency and prevents memory leaks in long-running applications.
Replaying Historical Blockchain Data
Beyond real-time tracking, many use cases require analyzing past blockchain activity—such as syncing user balances or auditing contract interactions.
web3j provides powerful replay observables for this purpose.
Replay all blocks within a specified range:
Subscription subscription = web3j.replayBlocksObservable(
DefaultBlockParameter.valueOf(1000),
DefaultBlockParameter.valueOf(2000),
false
).subscribe(block -> {
// Handle each block
});Replay individual transactions from a block range:
Subscription subscription = web3j.replayTransactionsObservable(
DefaultBlockParameter.valueOf(1000),
DefaultBlockParameter.valueOf(2000)
).subscribe(tx -> {
// Process each transaction
});For applications needing both historical sync and live updates:
Catch up to the latest block and stop:
web3j.catchUpToLatestBlockObservable(...).subscribe(block -> { ... });Or continue listening for new blocks afterward:
web3j.catchUpToLatestAndSubscribeToNewBlocksObservable(...).subscribe(block -> { ... });
Similarly, for transactions:
web3j.catchUpToLatestAndSubscribeToNewTransactionsObservable(
DefaultBlockParameter.valueOf(1000)
).subscribe(tx -> {
// Full history + ongoing stream
});All of these are accessible via the Web3jRx interface, enabling flexible integration across services.
Working with Topic Filters and EVM Events
Smart contracts emit EVM events—log entries stored in transaction receipts—that serve as a communication channel between on-chain logic and off-chain applications.
These events are defined in Solidity using the event keyword and are indexed for efficient filtering.
web3j allows you to create precise filters using the EthFilter class:
EthFilter filter = new EthFilter(
DefaultBlockParameterName.EARLIEST,
DefaultBlockParameterName.LATEST,
"0xYourContractAddress"
)
.addSingleTopic("0xYourEventSignature");Then subscribe to matching logs:
web3j.ethLogObservable(filter).subscribe(log -> {
System.out.println("Event detected: " + log.getData());
});Key Limitations to Remember
- Only indexed event parameters can be filtered.
- Non-indexed parameters cannot be searched or filtered directly.
- For indexed parameters of dynamic types (
string,bytes, etc.), Ethereum stores the Keccak256 hash of the value—not the raw value—making exact filtering challenging.
If you create a filter without specifying any topics, it will capture all EVM events across the network—an expensive and noisy operation best avoided in production.
👉 Learn how event-driven architecture enhances blockchain application responsiveness
Functional Composition with RxJava Observables
One of web3j’s most powerful features is its use of functional reactive programming (FRP) via RxJava. Every JSON-RPC method that supports streaming has an .observable() variant, enabling elegant composition of asynchronous operations.
For example, the blockObservable is built by combining two RPC calls:
public Observable<Block> blockObservable(boolean fullTxObjects, long pollingInterval) {
return ethBlockHashObservable(pollingInterval)
.flatMap(blockHash ->
web3j.ethGetBlockByHash(blockHash, fullTxObjects).observable());
}Here’s what happens:
- First,
ethBlockHashObservableemits new block hashes at regular intervals. - Then,
flatMaptriggersethGetBlockByHashto fetch full block data. - The result is a continuous stream of complete block objects—fully asynchronous and non-blocking.
This pattern enables sophisticated workflows like:
- Filtering transactions by sender or recipient
- Detecting specific contract interactions
- Building real-time analytics dashboards
Core Keywords for SEO Optimization
To align with search intent and improve visibility, here are the key terms naturally integrated throughout this article:
- web3j filters
- Ethereum events
- blockchain observables
- smart contract events
- RxJava Ethereum
- EVM event monitoring
- real-time blockchain data
- transaction filtering
These keywords reflect high-intent queries from developers building Java-based blockchain solutions.
Frequently Asked Questions (FAQ)
What are Ethereum event filters used for?
Ethereum event filters allow applications to monitor specific on-chain activities—like new blocks, transactions, or smart contract events—without constantly querying the entire blockchain. They enable efficient, real-time responses to changes in network state.
Why doesn't Infura support regular filters?
Infura disables traditional filter methods over HTTP due to scalability and security concerns. Instead, it recommends using WebSockets or alternative polling strategies. For full filter functionality with web3j, connect to a Geth node via WebSocket.
How do I stop memory leaks when using observables?
Always call subscription.unsubscribe() when you no longer need event updates. Failing to do so may keep references alive, leading to memory accumulation—especially in long-running services or batch processors.
Can I filter non-indexed Solidity event parameters?
No. Only indexed parameters in Solidity events can be filtered using topic-based queries. Non-indexed parameters are stored in the log data but cannot be used as filter criteria through standard Ethereum RPC calls.
Is web3j suitable for production dApps?
Yes. web3j is widely used in enterprise environments for integrating Java systems with Ethereum. Its robust error handling, asynchronous design, and support for TLS, IPC, and WebSocket connections make it ideal for production-grade applications.
How does RxJava improve blockchain development?
RxJava introduces reactive programming patterns that simplify handling asynchronous data streams—like blocks or transactions. Operators like map, filter, and merge allow developers to compose complex logic cleanly, improving code maintainability and scalability.
Final Thoughts
web3j transforms Ethereum interaction from a series of disjointed RPC calls into a cohesive, event-driven experience. By harnessing RxJava observables, it delivers powerful capabilities—from real-time transaction monitoring to historical data replay—with minimal boilerplate.
Whether you're building a wallet backend, audit tool, or DeFi analytics engine, mastering filters and events in web3j is a critical step toward creating responsive, scalable blockchain applications.
👉 Start building reactive blockchain apps with modern tools today
Remember: always manage subscriptions responsibly, design filters precisely, and leverage functional composition to unlock the full potential of Ethereum’s event system.