9

I'm currently checking if a transaction has been mined using the following function (using web3.js):

function waitForTx(tx_hash) {
        var result = null;

        // This is not really efficient but nodejs cannot pause the running process
        while(result === null) {
            result = web3.eth.getTransactionReceipt(tx_hash);
        }
    }

Is there a way to avoid the blocking loop?

Sebi
  • 5,294
  • 6
  • 27
  • 52
  • 2
    Related: http://ethereum.stackexchange.com/questions/1187/how-can-a-dapp-detect-a-fork-or-chain-reorganization-using-web3-js-or-additional – eth Oct 26 '16 at 21:53

4 Answers4

4

Xavier has a good solution with clear usage examples here: https://gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6. You get a thenable transaction receipt. This is a non-blocking solution, so the javascript thread is not stuck while waiting for the promise to be returned.

It's well-solved using promises and implemented as an extension of web3. Include the code in getTransactionReceiptMined.js verbatim. Then, interact with it as in his examples ... salient excerpt below.

You send a transaction and you get the transaction hash (quick), then call his function to set up a promise to wait for the transaction to be mined (block time). Then, run your code with your mined transaction receipt.

Lifted from his example (with added commentary):

...
  // do something that sends a transaction 
  return meta.sendCoin(account_two, 6, { from: account_one });
})
.then(function (txnHash) {
  // now you have the unmined transaction hash, return receipt promise
  console.log(txnhash); // follow along
  return web3.eth.getTransactionReceiptMined(txnHash);
})
.then(function (receipt) {
  // now you have the mined transaction receipt as "receipt"
  console.log(receipt); // explore it :-) 
  // carry on with the next step
  return meta.getBalance.call(account_two);
})
Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
3

Here is a ECMAScript 2016 version of waiting a contract to be mined (or any transaction hash):

// await sleep trick
// http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// We need to wait until any miner has included the transaction
// in a block to get the address of the contract
async function waitBlock() {
  while (true) {
    let receipt = web3.eth.getTransactionReceipt(contract.transactionHash);
    if (receipt && receipt.contractAddress) {
      console.log("Your contract has been deployed at http://testnet.etherscan.io/address/" + receipt.contractAddress);
      console.log("Note that it might take 30 - 90 sceonds for the block to propagate befor it's visible in etherscan.io");
      break;
    }
    console.log("Waiting a mined block to include your contract... currently in block " + web3.eth.blockNumber);
    await sleep(4000);
  }
}

waitBlock();
Mikko Ohtamaa
  • 22,269
  • 6
  • 62
  • 127
2
var getPendingTransactions = function (ip, port) {
  var https = 'http://'+ip+':'+port;
  var webPo = new Web3(new web3.providers.HttpProvider(https));
  var n = webPo.txpool.status.pending;
  return n;
};
var pendingCount = 0;
do
{
  // sleep a while;
  pendingCount  = getPendingTransactions(ip,port);
}while(pendingCount ==0)
// confirm transaction has included in blockchain now.
Will Wu
  • 328
  • 3
  • 9
0

as of geth version Geth/v1.6.7-stable-ab5646c5/linux-amd64/go1.8.1, you have the admin.sleepBlocks function, which takes an integer number of blocks to wait for, also admin.sleep which takes a floating-point number of seconds.

jcomeau_ictx
  • 111
  • 4