5

when executing a transaction in truffle tests, the return value is the transaction receipt and one can check for the presence of a particular event in the logs.

this is not possible when the transaction is a contract creation as the returned value is not the transaction receipt but the contract instance.

how can I get to the transaction receipt after instantiating a new contract?

return UserDirectory.new(root.address, {from: newUser})
  .then(d => {
    /*I would like to get the list of events here*/
    dir = d
    return dir.brg()
  })

3 Answers 3

3

The truffle-assertions package can easily help with this. Once the package is installed you can run the following:

// Import the package to your file
const truffleAssert = require('truffle-assertions');

// Deploy the contract
let testContract = await TestContract.new()

// Get the hash of the deployment transaction
let txHash = testContract.transactionHash

// Get the transaction result using truffleAssert
let result = await truffleAssert.createTransactionResult(testContract, txHash)

// Now look at the events using truffleAssert
truffleAssert.eventEmitted(result, 'TestEvent');

You'll find more information about the package here https://github.com/rkalis/truffle-assertions

And you can install it as follows: npm install truffle-assertions

2

this is not possible when the transaction is a contract creation as the returned value is not the transaction receipt but the contract instance.

One of the benefits of Truffle is that it hides away a lot of the complexity from the user, but don't let that fool you; whilst creating a contract is a special transaction (in that it has no to address), it is still a transaction and has a corresponding Transaction ID/Hash. We can verify this by using Etherscan to find a contract creation transaction.

If you want to get hold of this, then you are going to have to get your hands a little dirty and do some of the heavy lifting that Truffle hides away from you: if you look at the web3 documentation then you can find how to deploy a contract.

As per the documentation, you can see that after some work setting up the necessary code, a transaction hash for the transaction of creating a contract can be retrieved.


...
var myContractInstance = MyContract.new(param1, param2, {data: myContractCode, gas: 300000, from: mySenderAddress});
// The hash of the transaction, which created the contract
myContractInstance.transactionHash 

I'm not entirely sure how this relates to the title question

how to check if an event was added to the log in a contract contructor

I will add, that the events API allows you to look for events in past blocks - as per the documentation you can specify the block to start looking from:


...
// watch for an event with {some: 'args'}
var myEvent = myContractInstance.MyEvent({some: 'args'}, {fromBlock: 0, toBlock: 'latest'});

You may, therefore, be able to achieve this by

  • 1: Finding out the current block number
  • 2: Deploying the contract with Truffle and waiting for it to be mined - as you are already doing
  • 3: Call the event code specifying a block number in from equal to the block number in step 1.
0

Consider using OpenZeppelin Test Helper expectEvent.inConstruction.

Contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

contract Test {
    address public owner;

    event ContractCreated();

    constructor() {
        owner = msg.sender;

        emit ContractCreated();
    }
}

truffle-test:

const { expectEvent } = require('@openzeppelin/test-helpers');

const TestContract = artifacts.require('Test');

contract('Test', function (accounts) {
    const [owner] = accounts;
    const txParams = { from: owner };

    beforeEach(async function () {
        this.testContract = await TestContract.new(txParams);
    });

    describe('construction', function () {
        it('initial state', async function () {
            expect(await this.testContract.owner()).to.equal(owner);

            await expectEvent.inConstruction(this.testContract, 'ContractCreated');
        });
    });
});

package.json

{
..
  "devDependencies": {
    "@openzeppelin/test-helpers": "^0.5.10"
  }
..
}
1
  • hi vladmir thanks for this. It seems to work only for a single event though. If multiple events are emitted the receipt would always be the one for the first event it seems
    – G.G.
    Commented Jan 22, 2022 at 10:06

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.