1

I want to learn about specific events in a contract (or specific methods of said contract) being called as soon as technically possible.

I currently do:

        // Listen for "pending" transactions (transactions that have not been mined yet. I run my own node.)
        ethers_provider.on("pending", async (transaction_id) => {

            // Display transaction.
            console.log(`Transaction ${transaction_id}`);
        
            // Get transaction information.
            let transaction : any = await ethers_provider.getTransaction(transaction_id);

            // If we care about this transaction.
            if(transaction && transaction.to == CONTRACT_ADDRESS_WE_CARE_ABOUT){

                // Display transaction.
                console.log(transaction);

                // Get the receipt from the transaction's "wait" method.
                let receipt : any = await transaction.wait();

                // For each log, look for the log we are interrested in.
                for(let log of receipt.logs){

                    // Do something with the log.
                    console.log(log);

                }
            }
        });

The problem is that while console.log(transaction) is executed "early", the next console.log(log) is executed "late" (about 5 seconds later on average).

"5 seconds later" is equivalent to using .subscribe("logs") instead: it is the "least early" method to be warned about these events.

This is because the transaction.wait() method actually waits for the transaction to be "mined"/part of a mined block, before returning.

This is a problem for my use, I'd like to know about the content of the events/method calls before the block is mined, as soon as the transaction is created / it appears in the mempool.

It is currently my understanding that this is impossible. Am I correct? If so, why exactly? (I'm still learning smart contracts) And if not, how do I access this information "early"?

I guess a different way to ask this question is: I can see the transaction "hash"/id as soon as the transaction is added to the "mempool", when the "pending" event is triggered, BUT I can only see the transaction ID, and not the transaction details/contents/data/events. Is this content (or at least part of this content) present in the mempool ?? Would information about which methods are called (even if they have not been executed yet) be present in the mempool? And if so how do I access it?

The contract methods I want to monitor for is the following:

    function goDown(uint256 time) {
        require(time == currentTime, "Time is too early/late");

        // Do stuff.

        emit goDownEvent(msg.sender, time, );
    }

    function goUp(uint256 time) {
        require(time == currentTime, "Time is too early/late");

        // Do stuff.

        emit goUpEvent(msg.sender, time, );
    }

When a transaction is created, I want to know if it's a "goDown" method/event or a "goUp" method/event (nothing else calls these events).

As you can see, I could be looking to learn about when an event is "triggered" OR I could be looking to learn when a method is "called". "Learning" about either, as soon as technically possible, would work for my needs.

Is there any way to learn about these?

I know how to do it once I have the "receipt" object, but I don't know how to do it before I have this object.

Is there any possible way (even with downsides in terms of reliability or any other downsides) to do this? Any tip or trick?

I run my own geth node if this matters here.

Thank you so much to anyone with answers on this matter.

1
  • 2
    I don't think it will be as easy, but it is possible. You can simulate transactions before they are mined, for example github.com/Tenderly In the mempool you have the whole transaction including its calldata. As a simple case, if the calldata started with goDown then you know goDown is called. Your script should have access to calldata, it is transaction.data and helpful to know the ABI.
    – eth
    Commented Nov 1, 2022 at 5:19

1 Answer 1

0

Im not completely sure if this is the right answer but transaction.wait() would wait until the transaction was mined then send you the reciept. Whatever you are trying to do, you need to do it without wait()

Not the answer you're looking for? Browse other questions tagged or ask your own question.