1

I am calling a contract function which emits an event in a transaction. This transaction should include the event and is typically visible via:

const receipt = await contractInstance.someFunction()
let logs = receipt.logs

This normally contains a list of the emitted event names in the transaction. However in my call the tests output:

[]
    1) Test someFunction()

    Events emitted during test:
    ---------------------------

    Stored()

    ---------------------------

  1 failing

  1) Contract: Test.js
       Test someFunction():
     AssertionError: Stored event not emitted: expected false to be truthy
      at Context.it (test/test.js:145:12)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:7)

with testing block that fails:

const receipt = await instance.someFunction();
let event = validationReceipt.logs.some(l => { return l.event == "Stored" });
console.log(validationReceipt.logs);
assert.ok(event, "Stored event not emitted");

First line performs the function call which emits the event Stored. Second line retrieves the instance by event name from the logs. Third line simply logs the contained events. Fourth line asserts that the event exists in the logs.

As shown in the test output, the logs were empty [], but the event was emitted.

Why is the event being shown to have been emitted but also not present in the logs of the transaction that emitted it?

3

Turns out transaction receipt logs only include events emitted in the context of the direct contract function being called. If the called function makes another call to a separate external contract that emits an event, those won't be included even if there are emitted.

To make use of those emitted events from other contracts:

const sha3 = require('js-sha3').keccak_256
...

const tx = await instance.someFunction(();
let event = tx.receipt.logs.some(l => { return l.topics[0] == '0x' + sha3("Stored()") });
assert.ok(event, "Stored event not emitted");

where someFunction is a function that calls a function of another contract different to instance.

This grabs the logs from the receipt object. The logs should contain topics, the first of which is a hashed event signature. Thus we can use what we expect our event signature to be, hash it and test for existence in the logs. This works because all events are included in receipt logs but are not returned in the transaction logs provided by truffle/ganache.

This post helped.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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