Web3js

如何等到交易被確認 web3.js?

  • January 1, 2022

我是 web3 的新手。我正在嘗試將 UI 與 web3 連接起來。Metamask 版本是 6.0.1 和 web3 版本注入(不知道是誰),但它是 0.20.3。以下是我將乙太幣發送到我的合約函式的程式碼,該函式也在使用 Oracalize 內部,

var option = {from: accounts[0], to: contractAddress, value:4000000000000000};
       mycontract.update.sendTransaction(option, function(error,result){});

我想在確認此交易的基礎上執行一些其他程式碼。等到交易被確認然後我可以執行更多程式碼的最佳方法是什麼?確保我被這個版本的 web3 卡住了,我不能使用 1.0.0 版本,“發送”功能也是如此。

sendTransaction``transactionHash在回調中返回。如果交易是合約創建,則在交易被探勘後使用 web3.eth.getTransactionReceipt() 獲取合約地址。

web3.eth.sendTransaction({data: code}, function(err, transactionHash) {
 if (!err)
   console.log(transactionHash);

 var receipt = web3.eth.getTransactionReceipt(transactionHash);
});

為了等到交易被探勘,你可以使用這個模組:

module.exports = function getTransactionReceiptMined(txHash, interval) {
   const self = this;
   const transactionReceiptAsync = function(resolve, reject) {
       self.getTransactionReceipt(txHash, (error, receipt) => {
           if (error) {
               reject(error);
           } else if (receipt == null) {
               setTimeout(
                   () => transactionReceiptAsync(resolve, reject),
                   interval ? interval : 500);
           } else {
               resolve(receipt);
           }
       });
   };

   if (Array.isArray(txHash)) {
       return Promise.all(txHash.map(
           oneTxHash => self.getTransactionReceiptMined(oneTxHash, interval)));
   } else if (typeof txHash === "string") {
       return new Promise(transactionReceiptAsync);
   } else {
       throw new Error("Invalid Type: " + txHash);
   }
};

這是精煉的 TypeScript 程式碼

  • 允許您等待 N 次確認以進行交易
  • 檢查探勘後的交易是否成功

該程式碼基於範例和 Github MIT 原始碼。

/**
* Wait transactions to be mined.
*
* Based on https://raw.githubusercontent.com/Kaisle/await-transaction-mined/master/index.js
*/

import Web3 from 'web3';

const DEFAULT_INTERVAL = 500;

const DEFAULT_BLOCKS_TO_WAIT = 0;

interface Options {
 interval: number;
 blocksToWait: number;
}

/**
* Wait for one or multiple transactions to confirm.
*
* @param web3
* @param txnHash A transaction hash or list of those
* @param options Wait timers
* @return Transaction receipt
*/
export function waitTransaction(web3: Web3, txnHash: string|string[], options: Options = null): Promise<any> {
   const interval = options && options.interval ? options.interval : DEFAULT_INTERVAL;
   const blocksToWait = options && options.blocksToWait ? options.blocksToWait : DEFAULT_BLOCKS_TO_WAIT;
   var transactionReceiptAsync = async function(txnHash, resolve, reject) {
       try {
           var receipt = web3.eth.getTransactionReceipt(txnHash);
           if (!receipt) {
               setTimeout(function () {
                   transactionReceiptAsync(txnHash, resolve, reject);
               }, interval);
           } else {
             if (blocksToWait > 0) {
               var resolvedReceipt = await receipt;
               if (!resolvedReceipt || !resolvedReceipt.blockNumber) setTimeout(function () { transactionReceiptAsync(txnHash, resolve, reject);
               }, interval);
               else {
                 try {
                 var block = await web3.eth.getBlock(resolvedReceipt.blockNumber)
                 var current = await web3.eth.getBlock('latest');
                 if (current.number - block.number >= blocksToWait) {
                   var txn = await web3.eth.getTransaction(txnHash)
                   if (txn.blockNumber != null) resolve(resolvedReceipt);
                   else reject(new Error('Transaction with hash: ' + txnHash + ' ended up in an uncle block.'));
                 }
                 else setTimeout(function () {
                     transactionReceiptAsync(txnHash, resolve, reject);
                 }, interval);
                 }
                 catch (e) {
                   setTimeout(function () {
                       transactionReceiptAsync(txnHash, resolve, reject);
                   }, interval);
                 }
               }
             }
             else resolve(receipt);
           }
       } catch(e) {
           reject(e);
       }
   };

   // Resolve multiple transactions once
   if (Array.isArray(txnHash)) {
       var promises = [];
       txnHash.forEach(function (oneTxHash) {
           promises.push(waitTransaction(web3, oneTxHash, options));
       });
       return Promise.all(promises);
   } else {
       return new Promise(function (resolve, reject) {
               transactionReceiptAsync(txnHash, resolve, reject);
           });
   }
};


/**
* Check if the transaction was success based on the receipt.
*
* https://ethereum.stackexchange.com/a/45967/620
*
* @param receipt Transaction receipt
*/
export function isSuccessfulTransaction(receipt: any): boolean {
 if(receipt.status == '0x1' || receipt.status == 1) {
   return true;
 } else {
   return false;
 }
}

引用自:https://ethereum.stackexchange.com/questions/67232