1

in my Smart Contract I have a function such that it fires an event at the end of its code.

    function sendTran(arguments) public {
    *code*  
    emit Event(argument 1,argument 3,argument 3,argument 4);       
}

In nodejs I have an API like this

router.post('/send', function (req, res) {
  contractInstance.methods.sendTran(arguments).send({
    *stuff*  
}).on('transactionHash', function(hash){
  console.log(hash);
}).on('error', console.error);
});

How can I modify the API so that I can see in res.send the event emitted by the function sendTran?

Thank you very much!

  • How about res.send = hash? – goodvibration May 17 '18 at 13:36
  • 1
    @goodvibration Your response makes no sense. That would overwrite the res.send function, and what does the transaction hash have to do with the event OP is trying to access? – smarx May 17 '18 at 13:39
4

The logs are included in the transaction receipt but you can retrieve the transaction receipt only once it's mined. Depending on many factors (network congestion, gas price), a transaction can take a few seconds or a few hours to be mined.

That's why I wouldn't recommend to use synchronous HTTP call to do that. A good API is supposed to have a timeout and in your case you can't be absolutely sure that your transaction will be mined on time.

However, if you still want to do this, you can pull the transaction receipt every second until you get it:

waitForReceipt(hash, 1000).then(function (transactionReceipt) {
    console.log(transactionReceipt)
});


function waitForReceipt(hash, millisecondsInterval) {
    var retryCount = 0;
    var retryCountLimit = 100;

    var promise = new Promise((resolve, reject) => {
        var timer = setInterval(function () {

            web3.eth.getTransactionReceipt(hash, function(err, rec) {
                if(err) {
                    console.log(err)
                    clearInterval(interval);
                    reject(err)
                }

                if(rec != null) {
                    clearInterval(timer);
                    resolve(rec);
                    return;
                }

                retryCount++;
                if (retryCount >= retryCountLimit) {
                    clearInterval(timer);
                    reject("retry count exceeded");
                }
            });

        }, millisecondsInterval);
    });

    return promise;
}

I would recommend rather to use WebSocket to handle the asynchronous nature of the blockchain between a client and a server.

  • With this method, can I see the arguments of the emitted event? For example, if I have emit Event (msg.sender, amount, text); in the Smart Contract, I would like to log, after the use of the API, the three arguments of the event "Event"... – Bruce Wayne May 17 '18 at 15:51
  • The transaction receipt includes a field called "logs" [logs: Array - Array of log objects, which this transaction generated.] which are the events triggered by this transaction. Each log can be parsed, you will get the event name and each argument. – Greg Jeanmart May 17 '18 at 18:30

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.