3

In Hellos.sol, there is event initContract after constructor is called. Here is the solidity code:

pragma solidity 0.7.0;

contract Hello {
    address owner;
    uint256 value;
    
    event initContract(address _owner);  //<<==msg.sender in event
    constructor() {
        owner = msg.sender;
        emit initContract(owner);
    }
    
    //do something
}

In front end React native dapp with ethers 5.0.x, here is the code to listen to the event initContract after deployment:

      const contract = await factory.deploy();  //<<==deploy Hello.sol
      console.log("contract before mined: xxxxxxxxxxx",contract.address);
      contract.on("initContract", async (to, amount, from) => { //<<== listen to event initContract
        console.log("event initContract fired");
        console.log("to : ", to);  //EOA account to submit tx
        console.log("amount : ", amount); //json object
        console.log("from : ", from); //undefined
        ....
}

Here is the console output:

[Mon Dec 28 2020 10:52:42.771]  LOG      contract before mined: xxxxxxxxxxx 0x2b9534670c080E8B0B323e61524699C6efD589eB  //<<==contract address
...
[Mon Dec 28 2020 10:52:47.120]  LOG      event initContract fired
[Mon Dec 28 2020 10:52:47.123]  LOG      to :  0xF89b29Fb7D2a2Ecf56A4BA57f1680aa9d47BE538  //<<==this is msg.sender
[Mon Dec 28 2020 10:52:47.125]  LOG      amount :  {"address": "0x2b9534670c080E8B0B323e61524699C6efD589eB", "args": ["0xF89b29Fb7D2a2Ecf56A4BA57f1680aa9d47BE538"], "blockHash": "0xef52621b7fe9b8ff9402216c455cc57dc5005b57d1cca9a5368e640d6766bc19", "blockNumber": 255565, "data": "0x000000000000000000000000f89b29fb7d2a2ecf56a4ba57f1680aa9d47be538", "decode": [Function anonymous], "event": "initContract", "eventSignature": "initContract(address)", "getBlock": [Function anonymous], "getTransaction": [Function anonymous], "getTransactionReceipt": [Function anonymous], "logIndex": 0, "removeListener": [Function anonymous], "removed": false, "topics": ["0xcf9d4afa5954e14c65b6abfb613fbb48ee661f50cfb1c9e0b24b914d132dd504"], "transactionHash": "0x7f1a8741dd56544b0183421c2249d9207d1625e01489d0ff0d1efd7d1e2c351c", "transactionIndex": 0}
//<<== what is this? transaction object submitted?
[Mon Dec 28 2020 10:52:47.127]  LOG      from :  undefined  //<<==nothing returned on 3rd arg

What is in the return when listening to an event? Is the return the args in event definition, plus the transaction object submitted?

2 Answers 2

2

In short, as stated in ethers docs here

All event callbacks receive the parameters specified in the ABI as well as one additional Event Object

Here is an example that hopefully will make this clear. Let's say you have a contract with an event that looks like this

event metadata(bytes32 indexed fileHash, string name, string meta );

Then, using ethers.js

contract.on('metadata', (hash, name, metadata, event) => {
    console.log('First parameter :', hash);
    console.log('Second parameter :', name);
    console.log('Third parameter :', metadata);
    console.log('Event : ', event);  //Event object
});

you will get an output similar to the one below when a new event is emitted.

First parameter : 0xf29af4ebe4da02879e6c889417a09fe087a654ffeb3aa350128d0dd1729a9e6e
Second parameter : Logs.jpg 
Third parameter : { "type" : "jpg" , "size" : unknown}

Event : 
{
  blockNumber: 9357083,
  blockHash: '0x0d26e13567a123e9380f6de29b1face1a995dee90c77c5d6f4321bc7ecfbbba8',
  transactionIndex: 8,
  removed: false,
  address: '0x8fa9C961D02b05Bcf05B43061e05f90794155A63',
  data: '0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000084c6f67732e6a706700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247b20227479706522203a20226a706722202c202273697a6522203a20756e6b6e6f776e7d00000000000000000000000000000000000000000000000000000000',
  topics: [
    '0xf2b82d966b4a2fc73b533ba2c1b6d85cc9a6345a7e05c93cf169696ff13149eb',
    '0xf29af4ebe4da02879e6c889417a09fe087a654ffeb3aa350128d0dd1729a9e6e'
  ],
  transactionHash: '0xe0d00c28973bebb2d9208fe2eed4dd6c5a69971f59a7b5263386e9af4491ceb0',
  logIndex: 3,
  removeListener: [Function],
  getBlock: [Function],
  getTransaction: [Function],
  getTransactionReceipt: [Function],
  event: 'metadata',
  eventSignature: 'metadata(bytes32,string,string)',
  decode: [Function],
  args: [
    '0xf29af4ebe4da02879e6c889417a09fe087a654ffeb3aa350128d0dd1729a9e6e',
    'Logs.jpg',
    '{ "type" : "jpg" , "size" : unknown}',
    fileHash: '0xf29af4ebe4da02879e6c889417a09fe087a654ffeb3aa350128d0dd1729a9e6e',
    name: 'Logs.jpg',
    meta: '{ "type" : "jpg" , "size" : unknown}'
  ]
}

You can see some info about each field in the Event object here. In addition, i will tell you what i know about some specific fields

  • Topics : For every indexed parameter, a topic is created and stores the parameter's value. You may have up to 4 topics, but 3 indexed parameters. That's cause by default one of the topics is the hash of event signature(more on that here). Topics enable you to search for specific events by filtering.
  • Data : The rest of the parameters(non-indexed) passed to an event are stored in the data field of the Logs. They can't be used to filter and search for specific events, but are cheaper. Also there isn't any restriction about the size of such parameters(topics are limited to 32bytes).
  • Args : In this field you can find the parameters you passed to the event, both indexed and non-indexed. That's not part of the Log. It is just a way of ethers.js to make your life easier, cause otherwise you would need to decode the data yourself.

As for your example i think you have to make some modifications in the way you listen for new events. You don't need 3 parameters here contract.on("initContract", async (to, amount, from) because your event has only one parameter. That's why you got undefined for the 3rd arguement from.

Better change it to this

    contract.on("initContract", (owner, event) => { 
        console.log("event initContract fired");
        console.log("Owner: ", owner);  //owner will be msg.sender
        console.log("Event object: ", event); //the return Event object
}

If you need additional info feel free to ask.

1

The important part of the event data is topics which is the serialised arguments (In this case _owner). More information about the relationship between topics (logs) and events in this answer.

You can deserialise raw topics to symbolic ABIs. In your case this is (address _owner). There is a function web3.eth.abi.decodeLog for it.

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.