OK, let's say you have a smart contract deployed on the address
CONTRACT_ADDRESS which can trigger different type of events
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);
When an event is triggered from a smart contract during a transaction, this event is added in an event log (part of the blockchain global state). The event log can be queried using one or several filters (smart contract address, block number range, topics).
indexed means that the event will be added to a special data structure called
topics in the event logs. Consequently, it is possible to query the event log on those event parameters.
An event definition accept up to three indexed parameters.
An event is internally structured like this:
- address: the address of the contract (intrinsically provided by Ethereum);
- topics: keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")") (canonical_type_of is a function that simply returns the canonical type of a given argument, e.g. for uint indexed foo, it would return uint256). If the event is declared as anonymous the topics is not generated;
- topics[n]: EVENT_INDEXED_ARGS[n - 1] (EVENT_INDEXED_ARGS is the series of EVENT_ARGS that are indexed);
- data: abi_serialise(EVENT_NON_INDEXED_ARGS) (EVENT_NON_INDEXED_ARGS is the series of EVENT_ARGS that are not indexed, abi_serialise is the ABI serialisation function used for returning a series of typed values from a function, as described above).
Let's go back to the Java part, the following code demonstrates how to filter only the events of type
player2=MY_ADDRESS from the smart contract
CONTRACT_ADDRESS within the block range [
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)
eventFilter.addOptionalTopics(null, null, MY_ADDRESS); // filter: event parameters (gameId: no filter, player1: no filter, player2: filter)