1. Event Listening Basics
In smart contracts, events are represented using the Event method within the contract's wrapper package. These events extract indexed and non-indexed parameters from transaction receipts.
Key Mechanism:
Event listening relies on Ethereum logs. When a smart contract triggers an event:
- The event is recorded in the blockchain logs.
- External applications subscribed to the event detect it and retrieve relevant log data.
2. Observer Pattern vs. Pub-Sub Pattern
Observer Pattern
A design pattern for achieving loose coupling where observers directly subscribe to target events.
Example Workflow:
- Observable (Subject): Emits events.
- Observer: Listens and reacts to events.
- Subscription: Established via
subscribe().
// Observable (Subject)
Observable<String> observable = Observable.create(emitter -> {
emitter.onNext("Event 1");
emitter.onNext("Event 2");
emitter.onComplete();
});
// Observer
Observer<String> observer = new Observer<>() {
@Override public void onNext(String value) {
System.out.println("Received: " + value);
}
@Override public void onComplete() { /* Logic */ }
};
observable.subscribe(observer); // Link subscriptionPub-Sub Pattern
A generalized observer pattern with decoupled publishers/subscribers (e.g., Redis Pub-Sub). No direct dependency between components.
3. Implementing Observer Pattern with Web3j
Web3j’s reactive functions enable observers to notify subscribers via events. Ethereum supports three filter types:
- Block Filters: Notify new blocks.
- Pending Transaction Filters: Track unconfirmed transactions.
- Topic Filters: Custom criteria-based event listening.
Topic Filter Demo
EthFilter filter = new EthFilter(
DefaultBlockParameterName.EARLIEST,
DefaultBlockParameterName.LATEST,
"CONTRACT_ADDRESS"
);
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
web3j.ethLogObservable(filter).subscribe(log -> {
System.out.println("Log: " + log);
});Block/Transaction Filters
// New blocks
Subscription blockSub = web3j.blockObservable(false).subscribe(block -> { /* ... */ });
// New transactions
Subscription txSub = web3j.transactionObservable().subscribe(tx -> { /* ... */ });
// Unsubscribe when done
blockSub.unsubscribe();Replay Filters
// Replay historical blocks
web3j.replayBlocksObservable(startBlock, endBlock, true)
.subscribe(block -> { /* ... */ });
// Catch up to latest blocks
web3j.catchUpToLatestAndSubscribeToNewBlocksObservable(startBlock, true)
.subscribe(block -> { /* ... */ });FAQ Section
Q1: Why use Web3j for event listening?
👉 Web3j simplifies Ethereum integration by providing reactive APIs for real-time event handling.
Q2: How do topic filters differ from block filters?
Topic filters allow custom event criteria (e.g., specific contract methods), while block filters monitor all new blocks.
Q3: Can I listen to past events?
Yes! Use replayBlocksObservable() to process historical data.
Q4: What’s the advantage of Pub-Sub over Observer?
Pub-Sub decouples publishers/subscribers, enabling scalable distributed systems.
Q5: How to optimize gas costs for event-heavy contracts?
Minimize indexed parameters and avoid excessive logging in high-frequency transactions.
Key Takeaways
- Use topic filters for targeted event listening.
- Leverage Web3j’s reactive streams for efficient monitoring.
- Choose patterns (Observer/Pub-Sub) based on coupling needs.
👉 Explore advanced Web3j features for enterprise-grade blockchain solutions.