web3j – How to Get Event Args When Parsing Logs?

eventsweb3j

I'm trying to get an event args in web3j version 4.0.1.
I use the simple syntax which is explained in the docs. I'm getting the log object but there is no args property or such thing in it.
Here is my code:

EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST,
    DefaultBlockParameterName.LATEST, <contract-address>);
web3j.ethLogFlowable(filter).subscribe(log -> {
    System.out.println(log);
});

I expected to find args in the log it is not there. There is a data index and its value is some unreadable hex string.
I must mention that I'm able to see the log arguments in remix and even in truffle test transaction receipt. But no success in web3j.

Best Answer

For the following event:

event MyEvent(address indexed _arg1, bytes32 indexed _arg2, uint8 _arg3); 

You can extract the event arguments from the log like this

// Event definition
public static final Event MY_EVENT = new Event("MyEvent", Arrays.<TypeReference<?>>asList(new TypeReference<Address>(true) {}, new TypeReference<Bytes32>(true) {}, new TypeReference<Uint8>(false) {}));

// Event definition hash
private static final String MY_EVENT_HASH = EventEncoder.encode(MY_EVENT);

// Filter
EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, <contract-address>);

// Pull all the events for this contract
web3j.ethLogFlowable(filter).subscribe(log -> {
    String eventHash = log.getTopics().get(0); // Index 0 is the event definition hash

    if(eventHash.equals(MY_EVENT_HASH)) { // Only MyEvent. You can also use filter.addSingleTopic(MY_EVENT_HASH) 
        // address indexed _arg1
        Address arg1 = (Address) FunctionReturnDecoder.decodeIndexedValue(log.getTopics().get(1), new TypeReference<Address>() {});
        // bytes32 indexed _arg2
        Bytes32 arg2 = (Bytes32) FunctionReturnDecoder.decodeIndexedValue(log.getTopics().get(2), new TypeReference<Bytes32>() {});
        // uint8 _arg3
        Uint8 arg3 = (Uint8) FunctionReturnDecoder.decodeIndexedValue(log.getTopics().get(3), new TypeReference<Uint8>() {});
    }

});
Related Topic