Оптимальный способ ожидания транзакций для майнинга в geth

В настоящее время я проверяю, была ли транзакция заминирована, используя следующую функцию (используя 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);
        }
    }

Есть ли способ избежать цикл блокировки?

Ответы (4)

У Xavier есть хорошее решение с наглядными примерами использования здесь: https://gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6 . Вы получаете квитанцию ​​о транзакции. Это неблокирующее решение, поэтому поток javascript не зависает в ожидании возврата обещания.

Это хорошо решается с помощью промисов и реализовано как расширение web3. Включите код в getTransactionReceiptMined.js дословно. Затем взаимодействуйте с ним, как в его примерах... основной отрывок ниже.

Вы отправляете транзакцию и получаете хэш транзакции (быстро), а затем вызываете его функцию, чтобы установить обещание ждать завершения транзакции (время блока). Затем запустите свой код с квитанцией о добытой транзакции.

Взято из его примера (с добавленным комментарием):

...
  // 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);
})

Вот версия ECMAScript 2016 для ожидания майнинга контракта (или любого хэша транзакции):

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

начиная с версии geth Geth/v1.6.7-stable-ab5646c5/linux-amd64/go1.8.1 у вас есть admin.sleepBlocksфункция, которая принимает целое число блоков для ожидания, а также admin.sleepчисло секунд с плавающей запятой.