esaulpaugh / headlong

High-performance Contract ABI and RLP for Ethereum
Apache License 2.0
79 stars 20 forks source link

Issues decoding event with multiple indexed arguments and one non indexed argument. #51

Closed mtgnoah closed 1 year ago

mtgnoah commented 1 year ago

Here is the abi and it happens for Transfer and Approval events: uniswappairabi

    val blockNumber = 14918135
    val transactionHash = "0x72bf1f4c584163e06f951a92fda5e790cb6a0c87cf549866a6043699d8cc5053"

    val data = Array[Byte]()
    var topics = Array("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", "0x000000000000000000000000bdd95abe8a7694ccd77143376b0fbea183e6a740","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000002646")

    val eventName = "Approval"
    val event = AbiEvent(eventABI).toHeadlongEvent
    val topics = topicsHex.map(decodeHex)
    Some(event.decodeArgs(topics, data))

If I change the value parameter in the abi to be indexed then it worked perfectly fine but if not then it throws an exception: expected topics.length == 3 but found length 4 which I think is related to how that function only counts indexedParams and not nonIndexedParams. Is their a better fix than just changing the abi for each event I want to decode and hoping it gives consistent data?

esaulpaugh commented 1 year ago

This works for me:

Event eee = Event.fromJson("{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}");
final byte[] data = new byte[0];
final byte[][] topics = new byte[][] {
            Strings.decode("8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"),
            Strings.decode("000000000000000000000000bdd95abe8a7694ccd77143376b0fbea183e6a740"),
            Strings.decode("0000000000000000000000000000000000000000000000000000000000000000"),
            Strings.decode("0000000000000000000000000000000000000000000000000000000000002646")
};
Tuple z = eee.decodeArgs(topics, data);

System.out.println(z);

If you need to ignore the 0x, you can use FastHex.decode(str, 2, str.length() - 2)

I got the JSON from etherscan. https://etherscan.io/address/0x3b2c32363f8a61de868708dc6d0054246b5c98dd#code

https://api.etherscan.io/api?module=contract&action=getabi&address=0x3b2c32363f8a61de868708dc6d0054246b5c98dd

mtgnoah commented 1 year ago

Ok thanks. I'll just manually change the abis I have to reflect that and it should work