1

I've got the following event declaration in my Solidity contract:

    event RemoteOrderCreated(bytes32 indexed id, uint32 indexed nonce, address indexed sender, bytes input);

And I capture the event like so:

contract.on('eventName', async (...args) => {
  // here I have all the event args
})

For this sample transaction (sepolia block explorer link) the args looks like this:

[
  '0x1ae0b4b1df473f1aea6c8970adf5347aa0eaf656ba1c6888e4876c889488ef18',
  4502989,
  '0xCbeeBE266ab8d734a8ccd90097bF87809893977B',
  '0x030303030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e8d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a'
]

Value at index 0 is the id from the event, at index 1 is the nonce, at index 2 is the sender and at index 3 is the input prop.

This is the part of the ABI relating to the event declaration:

{
  "_format": "hh-sol-artifact-1",
  "contractName": "MyContract",
  "sourceName": "contracts/MyContract.sol",
  "abi": [
    {
      "inputs": [
        // inputs
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    // HERE is the event declaraion:
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "id",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "uint32",
          "name": "nonce",
          "type": "uint32"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "bytes",
          "name": "input",
          "type": "bytes"
        }
      ],
      "name": "RemoteOrderCreated",
      "type": "event"
    },
    // the rest of the ABI
 ]
}

I need to decode the input, but I'm not being successful. I tried with ethers.utils.defaultAbiCoder.decode() in different combinations of: providing the contract ABI, or just specific parts of it (relating to the event itself), and the input value that I want to decode.

I also tried with simple bytes decoding, but to no avail.

Is there a standard way of decoding bytes values from events/transactions?

3
  • 1
    You just need to provide the correct data structure for your bytes input part. Right now a complete guess is there are: Some identifier: 0x03030303 Some zero value. Some possibly uint256 value: 1000 in dec. Some other identifier or some data: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d. Some other uint256 value: 10 in dec. You need to tell ethers what these are. If you can share the source code, I can have a look.
    – Ake
    Commented Oct 17, 2023 at 4:34
  • 1
    Hey @Ake, I've just updated the post, adding the ABI relating to the event declaration. Is that what you asked for? If not, can you be more specific about what you mean by "source code" - which part exactly? Commented Oct 17, 2023 at 11:53
  • 2
    Hi! To decode the input, you need to know what the smart contract function that emits the event looks like. Do you have the code of the function? from there you can see what the input looks like. Commented Oct 17, 2023 at 18:57

1 Answer 1

1

Okay, thru a bunch of research I found out that when it's not a specific type of bytes type, eg. bytes4 or bytes32 etc..., but just bytes, then you need to figure out what is the structure of the encoded bytes string.

In my case, it's the following:

(bytes4, uint32, bytes32, uint256, address, uint256, uint256)

I got that from the Solidity contract where the input is being encoded before emitted with the event.

So, the JS solution is as follows:

decodedInput = ethers.utils.defaultAbiCoder.decode(
  ['bytes4', 'uint32', 'bytes32', 'uint256', 'address', 'uint256', 'uint256'],
  input
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.