Solidity
如何將 EthFilter 應用於特定地址?
在 web3.js 中,我們可以應用如下事件過濾器:
this.event = this.Contract.events.MyEvent({ filter: { address: "0xAccountAddress" }, })
在 Web3J 中,它被翻譯成
EthFilter eventFilter = new EthFilter( DefaultBlockParameterName.LATEST, DefaultBlockParameterName.LATEST, mContract.getContractAddress() ); eventFilter.addSingleTopic(EventEncoder.encode(Contract.MY_EVENT));
但是,如何
filter
在上面 web3.js 範例中的事件中傳遞特定地址?
好的,假設您在地址
CONTRACT_ADDRESS
上部署了一個智能合約,可以觸發不同類型的事件事件定義:
event GameStarted(bytes32 indexed gameId, address indexed player1, address indexed player2); event PlayerMoved(bytes32 indexed gameId, address indexed player); event GameEnded(bytes32 indexed gameId, address indexed player1, address indexed player2);
在交易期間從智能合約觸發事件時,該事件將添加到事件日誌(區塊鏈全域狀態的一部分)中。可以使用一個或多個過濾器(智能合約地址、塊號範圍、主題)查詢事件日誌。
關鍵字
indexed
意味著事件將被添加到topics
事件日誌中呼叫的特殊資料結構中。因此,可以根據這些事件參數查詢事件日誌。一個事件定義最多接受三個索引參數。
事件的內部結構如下:
- address:合約的地址(本質上由乙太坊提供);
- 話題$$ 0 $$: keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")") (canonical_type_of 是一個簡單地返回給定參數的規範類型的函式,例如對於 uint 索引 foo,它會返回 uint256)。如果事件被聲明為匿名,則主題$$ 0 $$沒有生成;
- 話題$$ n $$: EVENT_INDEXED_ARGS$$ n - 1 $$(EVENT_INDEXED_ARGS 是被索引的一系列 EVENT_ARGS);
- data : abi_serialise(EVENT_NON_INDEXED_ARGS) (EVENT_NON_INDEXED_ARGS 是一系列未編入索引的 EVENT_ARGS,abi_serialise 是用於從函式返回一系列類型值的 ABI 序列化函式,如上所述)。
讓我們回到 Java 部分,下面的程式碼展示瞭如何從區塊範圍 [ , ]內的智能合約中僅過濾類型為
GameStarted
where的事件:player2=MY_ADDRESS``CONTRACT_ADDRESS``BLOCK_n``BLOCK_m
EthFilter eventFilter = new EthFilter( BLOCK_n, // filter: from block BLOCK_m, // filter: to block CONTRACT_ADDRESS // filter: smart contract address ); eventFilter.addSingleTopic(EventEncoder.encode(Contract.GameStarted)); // filter: event type (topic[0]) eventFilter.addOptionalTopics(null, null, MY_ADDRESS); // filter: event parameters (gameId: no filter, player1: no filter, player2: filter)