Web3js
web3.js:N次確認後呼叫事件處理程序
web3.js 似乎在確認後直接呼叫事件的事件處理程序。我想知道是否可以僅在使用 web3.js 進行 5 次確認後呼叫事件處理程序。目前有可能嗎?
是的。
下面是我用來等待 N 次交易確認的 TypeScript 程式碼。
範例用法:
// Call a ERC-20 method const promiEvent = return token.methods.approve(contractAddr, numberOfTokens).send({ from: userAddress }); promiEvent.on("txHash", (hash) => { // We get transaction hash from MetaMask right after the user presses Confirm const receipt = await waitTransaction(web3, hash, {blocksToWait: 5, internal: 5000}) // Do something with transaction of 5 confirmations });
/** * 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 = 1500; const DEFAULT_BLOCKS_TO_WAIT = 1; interface Options { // Poll delay in milliseconds interval: number; // How many blocks to wait blocksToWait: number; } /** * Wait for one or multiple transactions to confirm. * * Usage: * ``` * const promiEvent = return this.oldToken.methods.approve(this.tokenSwapSmartContractAddress, inputs.fullBalance).send({ from: this.walletState.selectedAddress }); * promiEvent.on("txHash", (hash) => { * // We get transaction hash from MetaMask right after the user presses Confirm * const receipt = await waitTransaction(web3, hash, {blocksToWait: 5, internal: 5000}) * // Do something with transaction of 5 confirmations * }); * * ``` * * @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() { // this.logger.debug("Polling"); 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 { // TODO: // Hack fix for WalletModal reporting status=false even // though the transaction clearly went through. // Likely a web3.js bug. // Events are still set even if the status is set false. // blockHash: "0xc57dbdc96983d558cccadb591299e029c517e2ae548b4a683eb6968ede460411" // blockNumber: 10005547 // contractAddress: null // cumulativeGasUsed: 2923750 // events: // Approval: {address: "0xAf30D2a7E90d7DC361c8C4585e9BB7D2F6f15bc7", blockHash: "0xc57dbdc96983d558cccadb591299e029c517e2ae548b4a683eb6968ede460411", blockNumber: 10005547, logIndex: 18, removed: false, …} // from: "0x9b3979464c0d9c79fc34a4d4e9177891c4ef0ddb" // gasUsed: 24773 // status: false // to: "0xaf30d2a7e90d7dc361c8c4585e9bb7d2f6f15bc7" // transactionHash: "0x60781cd7c97281acc97d163641c6c211c47740f07abc36d63ce32ac158e9f9d2" // transactionIndex: 19 if(receipt.events) { if(receipt.events.Approval || receipt.events.Staked || receipt.events.Swapped) { return true; } } if (receipt.status == "0x1" || receipt.status == 1) { return true; } else { return false; } }