Gas
我怎麼知道我什麼時候以程式方式用完了gas?
這在 gitter 論壇上不斷出現,所以我想我會問並回答這個問題:你怎麼知道你什麼時候沒油了?
目前沒有明確的信號表明您的汽油已用完。正在向某些未來版本添加日誌消息。
目前我所做的是檢查gasSent == gasUsed。這要求您的程式碼記住您在特定交易中發送的氣體量並等待交易被探勘。如果 gasSent == gasUsed,你很可能用完了 gas。在我的 javascript 程式碼中,我拋出了一個異常。這為我節省了幾個令人尷尬的論壇文章和相當多的時間。
從理論上講,如果交易準確地消耗了所使用的氣體量,則該交易可能會被開採。我現在想不出辦法來解決這個問題,也許有人可以補充這個答案。如果您的跑步速度接近耗盡氣體的邊緣,那麼無論如何您可能應該發送更多的氣體。
我免費提供一些我用來擴展 web3 功能的程式碼,該功能等待本地節點探勘交易。它使用 Promise,但如果您不想使用 Promise,將其調整為回調樣式應該不難。我計劃將來擴展它以等待多個節點的共識,但我可能不會分享。
如果您沒有實例化日誌或創建輔助函式來查看是否設置了 var,您將無法在程式碼中複製和粘貼此程式碼。如果你還沒有做這些,你應該…
為合約合約呼叫編寫這個程式碼應該要小得多,所以我不會展示那個例子。相同的概念 - 只需檢查 gasSent == gasUsed 是否。
(是的,Promise 愛好者,我正在使用 Promise 反模式。我只是還沒來得及重寫它。功能是正確的。)
Object.getPrototypeOf(web3.eth).awaitConsensus = function(txhash, gasSent) { var deferred = Promise.pending(); ethP = this; filter = this.filter('latest'); // XXX make async callstack = new Error().stack; filter.watch(function(error, result) { // this callback is called multiple times, so can't promise-then it ethP.getTransactionReceiptAsync(txhash).then(function(receipt) { // XXX should probably only wait max 2 events before failing XXX if (receipt && receipt.transactionHash == txhash) { filter.stopWatching(); log.info({txreceipt: receipt}); if (js.isSet(gasSent)) { // note corner case of gasUsed == gasSent. It could // mean used EXACTLY that amount of gas and succeeded. // this is a limitation of ethereum. Hopefully they fix it if (receipt.gasUsed >= gasSent) { log.error({ badReceipt: receipt }); log.error({ originalStack: callstack }); throw(Error("ran out of gas, transaction likely failed!" + callstack)); } } deferred.resolve(receipt); } }); }); return deferred.promise.timeout(60000, "awaitConsensus timed out after 60000ms") .catch(function(e) { log.error(e); process.exit(1); });
}