0

I am currently trying to test a smart contract using the truffle suit ( with 'truffle test'). My contract is of a simple ERC20 token which includes the standard Transfer event:

event Transfer(address indexed from, address indexed to, uint256 value);

Below is my code which attempts to subscribe to all "Transfer" events only coming from account[0] to account[1]. Even though the 2 parameters are declared as "indexed", the filter does not seem to work and I get all Transfer events no matter the sender/receiver. I tried modifying the code in various ways but nothing seems to work so far

const EnergyToken = artifacts.require("EnergyToken");
const assert = require('assert');
const truffleAssert = require('truffle-assertions');
const { performance } = require('perf_hooks');

contract("Energy Heavy Load Test", async accounts => {
    const numberOfTransactions = 10;
    let startTime = 0;
    let finishTime = 0;
    let subscription;
    let contract;
    let i = 0;

    console.log(web3.version);

    // Function for rounding numbers
    function round(value, precision) {
        var multiplier = Math.pow(10, precision || 0);
        return Math.round(value * multiplier) / multiplier; 
    }

    // executed before each test
    before(async () => {
        contract = await EnergyToken.at("0x5BbD383bD43aC3896B86207eFe88cf0628ad06F0");
    });

    // Test mining time of 2500 transaction calls on the EnergyToken smart contract's transfer() method 
    it("send " + numberOfTransactions + " transactions of 1 EnergyToken from account 0 to account 1", (done) => {
        // contract.Transfer(function(error, event) { 
        //     i++;
        //     console.log(event)
        //     if(i == 1)
        //         startTime = performance.now();

        //     if (i == numberOfTransactions) {
        //         finishTime = performance.now();
        //         console.log("Transactions confirmed!" + " It took " + round((finishTime - startTime)/1000,2) + " seconds to confirm " + numberOfTransactions + " transactions");
        // .       done();
        //     }
        // });

        // contract.getPastEvents('Transfer', {
        //     filter: { from: accounts[0], to: accounts[1] },
        //     fromBlock: 0,
        //     toBlock: 'latest'
        // }, function(error, result) {
        //     if(error) {
        //         console.log(error, 'error');
        //     } else {
        //         console.log(result, 'result');
        //     }
        // });

        for (let j = 0; j < numberOfTransactions; j++) {
            contract.transfer(accounts[0], 1, { from:accounts[1] });
        }
        console.log("Finished sending " + numberOfTransactions + " transactions from account 1!!" + accounts[1] + " to "  + accounts[0]);
    });

    it("Calculate average gas used by the transfer() function", async () => {
        let result = await contract.transfer(accounts[1], 1);  
        let hash = await result.tx;
        let tx = await web3.eth.getTransactionReceipt(hash);
        let gasUsed = await tx.gasUsed;
        console.log(" Gas used for a 'Transfer' transaction: " + gasUsed);
    });

    it("Calculate average gas used by the approve() function", async () => {       
        let result = await contract.approve(accounts[1], 1000);  
        let hash = await result.tx;
        let tx = await web3.eth.getTransactionReceipt(hash);
        let gasUsed = await tx.gasUsed;
        console.log(" Gas used for an 'Approve' transaction: " + gasUsed);
    }); 

    it("Calculate average gas used by the transferFrom() function", async () => {
        await contract.approve(accounts[1], 100, { from: accounts[0] });  
        let result = await contract.transferFrom(accounts[0], accounts[1], 100, { from: accounts[1] });  
        let hash = await result.tx;
        let tx = await web3.eth.getTransactionReceipt(hash);
        let gasUsed = await tx.gasUsed;
        console.log(" Gas used for an 'Approve' transaction: " + gasUsed);
    });
});

Note: My version of web3 is 1.2.6

  • If your "web3 is 1.2.6" as you say it is, then you should by the least use contract.events.Transfer instead of contract.Transfer. The fact that your code runs and even fetches events, leads me to the logical conclusion that your web3 version is 0.x. In order to verify this, please run console.log(web3.version) in your program. And after verifying this, please refer to the official documentation of that specific version. Side note: if you're on Truffle 4.x, then the web3 used inside your Truffle tests IS 0.x. – goodvibration Feb 3 at 20:09
  • @goodvibration Thanks for the quick reply. My truffle version is Truffle v5.1.9 and I ran the code to check the web3 version - it is 1.2.1. I read the documentation earlier and indeed it says I should use contract.events.Transfer but contract.events returns undefined for some reason. That's why tried changing the code a bit and using contract.Transfer I managed to at least get some events back. No luck in trying to filter them so far though. – Aleksi Daskalov Feb 3 at 21:19
0

I suggest you should check your web3 version again by running in the terminal npm view web3 version in the root of your project. And then again you can check the version in the javascript by doing console.log(web3.version);. If it's really 1.x.x then you should be able to filter the events like this:

contract.getPastEvents('Transfer', {
    filter: {'from': accounts[0], 'to': accounts[1]},
    fromBlock: 0,
    toBlock: 'latest'
}, function(error, result) {
    if(error) {
        console.log(error, 'error');
    } else {
        console.log(result, 'result');
    }
});

It's also not normal behavior contract.events to return null for web3 1.x.x. Here are the docs how web3 1.x.x is dealing with events. If the problem still appears post your smart contract code here so we can test.

| improve this answer | |
  • Thanks for the reply. When I run npm view web3, the version is 1.2.6. However, using console.log(web3.version) in my truffle test code it says 1.2.1 (could be something related to truffle). As for contract.events, I am not sure why it returns undefined. When I run EnergyToken.events it returns the list of events. However, when I assign the contract instance to a variable with : let contract = await EnergyToken.at("0x5BbD383bD43aC3896B86207eFe88cf0628ad06F0"); then contract.events is undefined. According to the documentation, this should work in both versions since they are 1.x.x – Aleksi Daskalov Feb 4 at 15:45
  • Please attach your whole javascript or at least the logic where you define the instance. Also you work locally or on some of the testnets? – Miroslav Nedelchev Feb 4 at 15:53
  • I added my whole test code. The event filtering that I am trying to implement should go into the first it() clause. And yes I am running a private network of nodes using geth and truffle for contract deployment/testing. – Aleksi Daskalov Feb 4 at 16:08
  • This is my truffle test JS file => pastebin.com/xAC44PpX. Please check it carefully and adapt it to your logic. Unfortunately the code you shared above looks broken. I tested my example just right now with web3 1.2.6 and it all went smoothly. – Miroslav Nedelchev Feb 4 at 19:51

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.