I want to get all events emitted by a Solidity contract using web3, however the .getPastEvents() method is for a contract.
This returns all events for contractInstance, however, my contract calls other contracts which also emit events.
await contractInstance.getPastEvents("allEvents", {fromBlock: bn, toBlock: bn});
I want to get all the events from a transaction, not from a contract.
Or as an alternative, even all events from a block, which I could then filter down using the transaction hash, to get what I want. Is there a function that returns all events in a block? I've looked but I cannot find one. Must I know every contract in the chain and get the events separately? Perhaps.
I have made a really simple example to illustrate.
The solidity code:
pragma solidity 0.5.8;
contract contractA {
event eventA();
function methodA( address b ) public {
emit eventA();
contractB instanceB = contractB( b );
instanceB.methodB();
}
}
contract contractB {
event eventB();
function methodB() public {
emit eventB();
}
}
I am using Truffle to make it simple. Here is the migration file:
var contractA = artifacts.require("contractA");
var contractB = artifacts.require("contractB");
module.exports = function(deployer) {
deployer.deploy(contractA);
deployer.deploy(contractB);
Here is the truffle javascript code that calls the contractA methodA which emits eventA, and calls contractB methodB which emits eventB:
const contractA = artifacts.require("contractA");
const contractB = artifacts.require("contractB");
contract("contractA", async accounts => {
thisAccount = accounts[0];
it( "Simple test", async () => {
const instanceA = await contractA.deployed();
const instanceB = await contractB.deployed();
const transaction = await instanceA.methodA( instanceB.address, { from: thisAccount } );
const bn = transaction.receipt.blockNumber, txHash = transaction.tx;
const allEventsA = await instanceA.getPastEvents("allEvents", {fromBlock: bn, toBlock: bn});
const allEventsB = await instanceB.getPastEvents("allEvents", {fromBlock: bn, toBlock: bn});
console.log("A");
console.log( allEventsA );
console.log("B");
console.log( allEventsB );
});
});
And here is the output:
$ truffle test test.js
Using network 'development'.
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Contract: contractA
A
[
{
logIndex: 0,
transactionIndex: 0,
transactionHash: '0xe99db12863e5c0a0ae2c9c603d9d29f46a74d45ee9bf9f56d15f6f7bd1888058',
blockHash: '0xfa65496b8cb6ecf5b729892836adf80aa883e6823bbdb2d1b8cdfe61b5c97256',
blockNumber: 1573,
address: '0x97519Ada953F882d61625125D5D68E7932250E9F',
type: 'mined',
id: 'log_d28138a2',
returnValues: Result {},
event: 'eventA',
signature: '0x72f2637d8047e961ba6b558fdf63d428e9734bdf7ee2fb2b114f3b1aa65335c7',
raw: { data: '0x', topics: [Array] },
args: Result { __length__: 0 }
}
]
B
[
{
logIndex: 1,
transactionIndex: 0,
transactionHash: '0xe99db12863e5c0a0ae2c9c603d9d29f46a74d45ee9bf9f56d15f6f7bd1888058',
blockHash: '0xfa65496b8cb6ecf5b729892836adf80aa883e6823bbdb2d1b8cdfe61b5c97256',
blockNumber: 1573,
address: '0x00108B6A5572d95Da87e8b4bbF1A3DcA2a565ff7',
type: 'mined',
id: 'log_da38637d',
returnValues: Result {},
event: 'eventB',
signature: '0x34a286cd617cdbf745989ac7e8dab3f95e8bb2501bcc48d9b6534b73d055a89c',
raw: { data: '0x', topics: [Array] },
args: Result { __length__: 0 }
}
]
✓ Simple test (76ms)
As you can see I have to call for every contract independently. I wondered if perhaps there was a "transaction object" method to get both of these events in one call - as they, after all, are from the same transaction.
You can imagine a situation where events were emitted from many contracts in the same transaction.
Perhaps it just isn't possible, but I thought I would ask anyway.