7

I'm a three months old programmer. So if what I'm saying is ambiguous, please let me know and help me being a better programmer.

Now I'm coding a test code as using hardhat and ether.js.

My solidity contract is about orderbook token exchange. When people make an order, the contract emit specific event named "Make".


event Make(
    bytes32 indexed orderId, 
    address indexed maker,
    address makerToken, 
    address takerToken,
    uint256 amountSell,
    uint256 amountBuy
);

orderId is made by hashing some data.

And I want to check if event is emitted correctly. While coding test codes, I've spent quite a long time to know how to get emitted events.

finally I can get events using code below. but what I really want is

  1. get 1st arg of event and put it a var. (in case, bytes32 hash) looks like, const hash = await events.args[0];

  2. compare 2nd arg of event and compare it with value. (in case, address maker) looks like, expect(await events.args[1]).to.equal(add1.address);

actually it's not a two question. just one.

here's my test code.

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("EX contract", function () {
    let EX, ex, token, Token, add0, add1, add2, add3;

    before(async function () {
      EX = await ethers.getContractFactory("EX");
      Token = await ethers.getContractFactory("Token");
      ex = await EX.deploy(1000);
      token = await Token.deploy();
      [add0, add1, add2, add3] = await ethers.getSigners();
    });
  
    beforeEach(async function () {
      await token.mint(add1.address, 200000);
    });

    describe("Make / Take order", function () {
        await ex.connect(add1).makeOrder(token.address, 100, {value : 100});
        await ex.connect(add1).makeOrder(token.address, 100, {value : 200});
        
        let eventFilter = ex.filters.Make();
        let events = await ex.queryFilter(eventFilter, "latest");

        console.log(events);            //"events" contains too many information.
    });
});

Help me please, mates!

2 Answers 2

3

I suggest to try OpenZeppelin test helpers. They have a check expectEvent that reads events from the transaction's receipt.

In your case it should look like

it("Make / Take order", async function () {
  const receipt = await ex.connect(add1).makeOrder(token.address, 100, {value : 100});

  expectEvent(receipt, 'Make', {
    orderId: '<EXPECTED_ORDER_ID>',
    maker: '<EXPECTED_MAKER>',
  });
});
5
  • Thanks mate! Actually I already know about OpenZeppelin test helpers. it can resolve the second thing I want but it doesn't resolve the first thing. I think I can do that with ".on" function. but I can't find a solution.
    – S.L.Ater
    Commented Apr 3, 2021 at 9:58
  • @S.L.Ater The events generated by a transaction are included in the transaction's receipt.
    – Ismael
    Commented Apr 3, 2021 at 16:34
  • Okay. Then, if I want to get orderId and put it to const id, how can I write a script?
    – S.L.Ater
    Commented Apr 3, 2021 at 17:50
  • @S.L.Ater If you look at the receipt it has a log field that contains all events generated by the transaction.
    – Ismael
    Commented Apr 3, 2021 at 18:31
  • I really appreciate it, Ismael! I solved the problem. :)
    – S.L.Ater
    Commented Apr 7, 2021 at 16:43
5

Thanks Ismael!

I solved it as two different way. one from my code and one from your help.

from my code

    await ex.makeOrder(token.address, 100, {value : 200});

    const eventFilter = ex.filters.Make();
    const events = await ex.queryFilter(eventFilter, "latest");
    const hash = events[0].args[0];

and from your help

    const tx = await ex.makeOrder(token.address, 100, {value : 200});
    const res = await tx.wait();
    const hash = res.events[0].args[0];

I really appreciate 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.