5

I am trying to figure out how to send a transaction to a contract method, retrieve the transaction hash automatically, and then get a receipt callback after the transaction is mined.

I am able to do one or the other but seemingly not both. Any suggestions?

Contract.deployed().then(function(instance) {
    instance.methodName(parameter, {from: this.account, value: price})
        .then(function(receipt) {
          //THIS FIRES AFTER THE TRANSACTION IS MINED, 
          //BUT I CANT GET THE TX HASH ANY SOONER
        });
});


Contract.deployed().then(function(instance) {
    instance.methodName.sendTransaction(parameter, {from: this.account, value: price})
        .then(function(hash) {
            //THIS FIRES BEFORE THE TRANSACTION IS MINED, 
            //BUT I NOW DON'T HAVE A WAY TO GET A MINED RECEIPT
        });
});
3
  • What version of web3.js? And is this actually truffle?
    – user19510
    Commented Jan 19, 2018 at 4:46
  • This is version 0.16.0 of web3.js and yes, this is a truffle project.
    – skajake
    Commented Jan 19, 2018 at 4:52
  • To my knowledge, instance.methodName() and instance.methodName.sendTransaction() should perform identically in web3.js 0.2x.x, but I'm not sure about older versions, and I believe that pre-1.0.0 versions of web3.js don't support promises, so I believe you're dealing with some truffle magic instead. (Sorry, but I'm unfamiliar with truffle.)
    – user19510
    Commented Jan 19, 2018 at 4:53

2 Answers 2

10

I'm unfamiliar with truffle, so I can't comment on whether there's a better way, but once you have a transaction receipt, you can poll using a transaction receipt like so (code taken from https://programtheblockchain.com/posts/2017/12/13/building-decentralized-apps-with-ethereum-and-javascript/):

function waitForReceipt(hash, cb) {
  web3.eth.getTransactionReceipt(hash, function (err, receipt) {
    if (err) {
      error(err);
    }

    if (receipt !== null) {
      // Transaction went through
      if (cb) {
        cb(receipt);
      }
    } else {
      // Try again in 1 second
      window.setTimeout(function () {
        waitForReceipt(hash, cb);
      }, 1000);
    }
  });
}

In your case, this would be:

instance.methodName.sendTransaction(parameter, {from: this.account, value: price}).then(function(hash) {
  waitForRecepit(hash, function (receipt) {
    ...
  });
});
3
  • Noob question - but what is 'cb' - is this the coinbase transaction? and if so, is their documentation on how to use it - because i see it used in a lot of different ways Commented May 17, 2018 at 6:55
  • 2
    It's a "callback": in this case, the function that's called when the transaction is mined.
    – user19510
    Commented May 17, 2018 at 12:00
  • When using sendTransaction, how do I get the transaction hash? And also, does sendTransaction return only after the transaction is mined? Commented Feb 11, 2020 at 4:46
4

I see this is the version of web3 that does not use async await but I think timeouts are not the recommended way anymore, because as shown above you need to set timeouts and nest the callbacks, which may lead to 'callback hell'.

If you're using web3 1.0 and above, I think using async await will help to simplify the code. Here's an example from a submit form in React (this.setState is for storing values, you can save them to an object if not using React):

onSubmit = async (event) => {
  event.preventDefault();
  try {
    // start mining the transaction
    await instance.methodName.sendTransaction(parameter, 
      {from: this.account, value: price}, 
      (err, txHash) => this.setState({isMining: true, txHash}
    );

    // mining is finished, display the gas used for the transaction
    await web3.eth.getTransactionReceipt(this.state.txHash, 
      (err, txReceipt) => this.setState({ 
         blockNumber: txReceipt.blockNumber,
         gasUsed: txReceipt.gasUsed, 
         isMining: false
      })
    );
  } catch(err) {
    console.log(err)
  }
}

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.