It seems that there is an issue with handling of contract events and I am not sure if it is at the EVM level or just web3js.

I have 2 contracts "SomeCoin" and "SomeConcert". Both contracts emit "Transfer" event when there is a transfer of item from one address to another. For "SomeCoin" the object of transfer is a coin/token, for "SomeConcert" the object of transfer is concert tickets (that is priced in "SomeCoins").

When I called "SomeConcert" method to purchase tickets, the logic will transfer some "SomeCoins" from my address to the "SomeConcert" address. All is well and good except for the event handling. I saw 2 events emitted "Buy" event emitted from "SomeConcert" contract and "Transfer" event from "SomeCoin" contract. If I renamed the "Transfer" event in "SomeCoin" contract to "TransferCoin" then I will only see the "Buy" event.

So, apparently either web3 or the underlying layer confuses the events emitted by inner layer contract with the outer layer contract. At least this is the conclusion I have come to.

Is this a web3js bug? Is there anything I missed out in the event handling that might have prevented the confusion. The code I have for event handling is rather standard

... return someConcertInstance.buyTickets(3, {from: customer1}); }).then(function(receipt) { assert.equal(receipt.logs.length, 1, "should have received 1 events for buy-ticket)"); assert.equal(receipt.logs[0].args._numberOfTickets, 3, "Number of tix bought must be 3");

The test case failed on the first assert and I found out 2 events are emitted (transfer and buy).

  • It's expected that the transaction receipt contains two log entries, because two events were logged in that transaction. It's unexpected that you see only one log entry if you rename one of the events... perhaps it's a mismatch between the contract code and the ABI you're using? – smarx Apr 5 '18 at 13:45
  • I checked and indeed that's the behaviour. – Thomas Apr 5 '18 at 13:58
  • I'm not sure what you're confirming. Did you find a mismatch between the contract code and the ABI? – smarx Apr 5 '18 at 14:19
  • The ABI and contract are consistent. I used Truffle v4.1.5 and I cleared out everything in the "build" folder, restarted my testrpc, did a "Truffle compile --all" and "Truffle migrate --reset" though Truffle test is supposed to do cleanroom deployment. But the result remains - I will see the inner contract events if I have the same event signature at the outer contract. It seems to me there is some logic on how events are bubbled up the chain and probably they used the event name to filter. I wonder if this has to do with web3 or something more fundamental. – Thomas Apr 5 '18 at 14:29
  • As I said, I believe you should see all logs that were generated by your transaction. The fact that one of the events seems to disappear based on the name of the event strikes me as a bug in web3.js... my best theory is that web3.js doesn't actually give you all the logs but rather just the ones matching a signature in the ABI. This may be by design, but I don't like that design. :-) – smarx Apr 5 '18 at 14:31

Sorted out in the comments above, moving to an answer for future readers.

The code in the question is using truffle. When sending a transaction in truffle, the result you get back has a logs field, which is assembled via this code: https://github.com/trufflesuite/truffle-contract/blob/develop/contract.js#L44.

That code discards logs with topics that don't match a known event signature in the ABI of the contract you're calling. I consider that behavior to be a design bug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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