web3j過濾器提供以太坊網絡發生的某些事件的通知,對java和安卓程式員來說很有用。在Ethereum以太坊中支援三類過濾器:
- 塊濾波器(Block filters)
- 未決交易過濾器(Pending transaction filters)
- 主題過濾器(Topic filters)
塊過濾器和未決交易過濾器提供了在網絡上建立新交易或塊的通知。
主題過濾器更靈活。允許根據提供的特定标準建立過濾器。
不幸的是,除非你使用
WebSocket
連接配接到Geth,否則通過JSON-RPC API來處理過濾器是一個繁瑣的過程,這裡需要輪詢以太坊用戶端,以便了解HTTP和IPC所請求的實時同步特征,是否有任何新的更新到你的過濾器。此外,塊和交易過濾器隻提供交易或區塊鍊hash值,是以需要進一步的請求來獲得hash對應的實際交易或塊。
web3j的
過濾器解決了這些問題,是以你有一個完全異步的基于事件的API來處理過濾器。它使用
RXJava的可觀測性
Observables,它提供了與事件協同工作的一緻API,這有助于通過功能組合将JSON-RPC調用連結在一起。
注:
Infura
不支援過濾器。
塊和交易過濾器
接收所有新塊把它們添加到區塊鍊(false參數指定我們隻需要塊就ok,而不需要嵌入交易):
Subscription subscription = web3j.blockObservable(false).subscribe(block -> {
...
});
接收所有新交易,把它們添加到塊鍊:
Subscription subscription = web3j.transactionObservable().subscribe(tx -> {
...
});
接收所有待送出交易并送出到網絡(即在它們被分組在一起之前):
Subscription subscription = web3j.pendingTransactionObservable().subscribe(tx -> {
...
});
不再需要的時候取消訂閱
unsubscribe
:
subscription.unsubscribe();
另外還提供了其他回調,它們簡單地提供了塊或交易hash,這些細節涉及
Web3JRX接口。
再現過濾器
webjs還提供用于再現塊和交易曆史的過濾器。
從區塊鍊再現一系列塊:
Subscription subscription = web3j.replayBlocksObservable(
<startBlockNumber>, <endBlockNumber>, <fullTxObjects>)
.subscribe(block -> {
...
});
再現包含在一個塊範圍内的單個交易:
Subscription subscription = web3j.replayTransactionsObservable(
<startBlockNumber>, <endBlockNumber>)
.subscribe(tx -> {
...
});
也可以獲得Web3J再現最新的塊,并在你看過後提供通知(通過送出
Observable
):
Subscription subscription = web3j.catchUpToLatestBlockObservable(
<startBlockNumber>, <fullTxObjects>, <onCompleteObservable>)
.subscribe(block -> {
...
});
或者,也可以在你再現最新的塊後,通知新建立的後續塊:
Subscription subscription = web3j.catchUpToLatestAndSubscribeToNewBlocksObservable(
<startBlockNumber>, <fullTxObjects>)
.subscribe(block -> {
...
});
如上所述,并包含在塊内的交易:
Subscription subscription = web3j.catchUpToLatestAndSubscribeToNewTransactionsObservable(
<startBlockNumber>)
.subscribe(tx -> {
...
});
所有上述過濾器都是通過
接口導出的。
主題過濾器和EVM事件
主題過濾器捕獲在網絡中發生的以太坊虛拟機(EVM)事件的細節。這些事件是由智能合約建立的,并存儲在與智能合約相關聯的交易日志中。
solidity文檔提供了EVM事件的良好概述。
使用
EthFilter類型指定希望應用于過濾器的主題。這可以包括希望應用過濾器的智能合約的位址。你還可以提供特定的主題進行篩選。其中單個主題表示智能合約上的索引參數:
EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST,
DefaultBlockParameterName.LATEST, <contract-address>)
[.addSingleTopic(...) | .addOptionalTopics(..., ...) | ...];
然後可以使用類似于上面的塊和交易過濾器的文法建立該過濾器:
web3j.ethLogObservable(filter).subscribe(log -> {
...
});
過濾器主題隻能引用索引的Solidity事件參數。不可能對非索引事件參數進行篩選。此外,對于可變長度數組類型(如字元串和位元組)的任何索引事件參數,它們的值的
Keccak-256
hash 存儲在EVM日志上。不可能使用它們的全部值來存儲或篩選。
如果建立一個沒有與之相關聯的主題的過濾器執行個體,則在網絡中發生的所有EVM事件都将由過濾器捕獲。
操作組合标注
除了
send()
和
sendAsync
之外,所有JSON-RPC方法在web3j中都實作了支援observable()方法來建立可觀察的異步執行請求。這使得将JSON-RPC調用組合成新的函數是非常容易和直接的。
例如,
blockObservable本身由許多單獨的JSON-RPC調用組成:
public Observable<EthBlock> blockObservable(
boolean fullTransactionObjects, long pollingInterval) {
return this.ethBlockHashObservable(pollingInterval)
.flatMap(blockHash ->
web3j.ethGetBlockByHash(blockHash, fullTransactionObjects).observable());
}
在這裡,我們首先建立一個可觀察的,它提供每個新建立的塊的塊哈希的通知。然後,我們使用
flatMap
調用
ethGetBlockByHash
,以獲得完整的塊細節,這是傳遞給可觀察者的訂閱伺服器的細節。
進一步的例子
請參閱
ObservableIT,進一步舉例說明。
對于使用手動篩選器API的示範,可以檢視
EventFilterIT。
原文出處:
web3j教程:過濾器(Filters)和事件(Events)