1

Given following solidity code:

pragma solidity ^0.5.1;

contract Foo {

    event FooInc(uint256 _a);
    uint256 a;

    constructor() public {
        a = 42;
    }

    function inc() public returns(bool) {
        a += 1;
        emit FooInc(a);
        return true;
    }
}

and following test javascript code:

let Foo = artifacts.require('Foo');

contract("foocontract", async accounts => {
    it("testing inc", async (done) => {
        let foo = await Foo.deployed();
        foo.allEvents().on('data', function(e) {
            console.log('allevents', e);
            done();
        });
        foo.inc().then(r => {
            console.log('done', r);         
            foo.getPastEvents('allEvents', undefined, (e, l) => {
                console.log("pastevents", e, l);
                done();
            });

        });
    });
});

The receipt from the foo.inc() promise gets logged. Neither of the event listener accessors for the contract events fire, although the receipt object shows the event was triggered.

$ truffle test
Using network 'test'.


Compiling your contracts...
===========================
> Compiling ./contracts/Foo.sol
> Compiling ./contracts/Migrations.sol
> Artifacts written to /tmp/test-2020127-266345-9s8aje.7jzss
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang



  Contract: foocontract
done {
  tx: '0x158109501fa0cecffa6c7887d05c255cb5e76002c25881f5e684ab199a75cdff',
  receipt: {
    transactionHash: '0x158109501fa0cecffa6c7887d05c255cb5e76002c25881f5e684ab199a75cdff',
    transactionIndex: 0,
    blockHash: '0x55e2fce5a0257fad6d851ba35e03885509f98a6641e3e92a146e2fbaad9e3a18',
    blockNumber: 5,
    from: '0x627306090abab3a6e1400e9345bc60c78a8bef57',
    to: '0x345ca3e014aaf5dca488057592ee47305d9b3e10',
    gasUsed: 28961,
    cumulativeGasUsed: 28961,
    contractAddress: null,
    logs: [ [Object] ],
    status: true,
    logsBloom: '0x00000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000010000000000000',
    rawLogs: [ [Object] ]
  },
  logs: [
    {
      logIndex: 0,
      transactionIndex: 0,
      transactionHash: '0x158109501fa0cecffa6c7887d05c255cb5e76002c25881f5e684ab199a75cdff',
      blockHash: '0x55e2fce5a0257fad6d851ba35e03885509f98a6641e3e92a146e2fbaad9e3a18',
      blockNumber: 5,
      address: '0x345cA3e014Aaf5dcA488057592ee47305D9B3e10',
      type: 'mined',
      id: 'log_8dfd46f8',
      event: 'FooInc',
      args: [Result]
    }
  ]
}

I am using [email protected] and the docs for it suggest that it should merely be a matter of listening for javascript events data and error. What am I missing here?

2 Answers 2

2

This works for me on Truffle v4.1.16:

const Foo = artifacts.require('Foo');

contract("foocontract", async accounts => {
    it("testing inc", async (done) => {
        const foo = await Foo.deployed();
        const receipt = await foo.inc();
        printLogs("receipt", receipt.logs);
        foo.allEvents().get(function(error, logs) {
            assert.equal(error, null);
            printLogs("listened", logs);
        });
    });
});

function printLogs(title, logs) {
    for (let i = 0; i < logs.length; i++) {
        console.log();
        console.log(`${title} event #${i + 1}:`);
        console.log(JSON.stringify(logs[i], null, 4));
    }
}

You may want to try something similar on your version of Truffle.

Keep in mind that Truffle v4.x relies on web3.js v0.x, while Truffle v5.x relies on web3.js v1.x.

So there might be a few differences in how events are listened to.

5
  • foo.allEvents() gives me an EventEmitter but it does not have get() :/
    – lash
    Feb 27, 2020 at 15:48
  • @lash: Like I said, "You may want to try something similar on your version of Truffle. I don't have Truffle 5.x installed, so check the docs to see how to use that EventEmitter (or even print this object in order to see what methods it exposes). Feb 27, 2020 at 15:53
  • yeah, I appreciate the hint. Just wanted to document here for others looking to provide help that get() fails. Incidentally, so does addEventListener(). on() compiles, but produces nothing, like explained above. ... I'm assuming EventEmitter is this: nodejs.org/docs/v13.7.0/api/…
    – lash
    Feb 27, 2020 at 16:05
  • @lash: It's actually here - web3.js docs, which I personally find to be easier than Truffle docs (and I'm pretty sure that your link to NodeJS docs is irrelevant in this context). Have a look around there, you may find several functions that will answer your requirements (for example, getPastEvents if you scroll down a bit). Feb 27, 2020 at 16:34
  • that would be a very cheeky overload by web3 if the EventEmitter class would totally change its interface. According to the docs the web3 version should still support .on. Meanwhile I followed up on your hint for getPastEvents() which did not yield any better results, and I've updated the question with code using that aswell.
    – lash
    Feb 27, 2020 at 17:41
2

With truffle 5, solc 0.7

const CrowdFundingWithDeadline = artifacts.require("TestCrowdFundingWithDeadline");

contract('CrowdFundingWithDeadline' , async accounts => {
    let contract;
    let account = accounts[0];
    let beneficiary = accounts[1];
    const ONE_ETH = 1000000000000000000;
    const Ongoing_State = 0;
    const Faild_State = 1;
    const Succeeded_State = 2;
    const Paidout_State = 3;

    beforeEach(async function () {
        contract = await CrowdFundingWithDeadline.new(
            'funding',
            1,
            10,
            beneficiary,
            {
                from: account,
                gas: 2000000
            }
        );
    });
    
    it('event is emitted', async function () {
        await contract.setCurrentTime(601);
        let res = await contract.finishCrowdFunding();
        let eventName = res.logs[0].event;
        let eventRes = res.logs[0].args;
        expect(Number.parseInt(eventRes.totalCollected)).to.equal(0);
        expect(eventRes.succeeded).to.equal(false);
    });
});

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.