天天看點

web3j教程:以太坊過濾器(filter)篩選和智能合約事件(event)監聽

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教程 ,主要是針對java和android程式員進行區塊鍊以太坊開發的web3j開發詳解。
  • 以太坊教程 ,主要介紹智能合約與dapp應用開發,适合入門。
  • 以太坊開發 ,主要是介紹使用node.js、mongodb、區塊鍊、ipfs實作去中心化電商DApp實戰,适合進階。
  • php以太坊 ,主要是介紹使用php進行智能合約開發互動,進行賬号建立、交易、轉賬、代币開發以及過濾器和事件等内容。

原文出處:

web3j教程:過濾器(Filters)和事件(Events)