Web3js
如何等到交易被確認 web3.js?
我是 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; } }