7

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?

2

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);
})
2

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();
1
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.
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.

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.