Javascript

ethers gasLimit gasPrice

  • May 19, 2021

我是菜鳥。我正在嘗試設置gasPricegasLimit因為我遇到了氣體估計錯誤。

我只是不明白在哪裡/如何將它插入到交易中。這是在 BSC 網路上。

錯誤資訊:

ERROR:
reason: 'cannot estimate gas; transaction may fail or may require manual gas limit',
   code: 'UNPREDICTABLE_GAS_LIMIT',
   error: Error: gas required exceeds allowance (3807079) or always failing transaction 
 const tx = await router.swapExactTokensForTokens(
   amountIn,
   amountOutMin,
   [tokenIn, tokenOut],
   addresses.recipient,
   Date.now() + 1000 * 60 * 3 //3 minutes
 );
 const receipt = await tx.wait(); 
 console.log('Transaction receipt');
 console.log(receipt);

讓我們把它分成兩部分,需要注意的是,在對第一部分做任何事情之前,你應該先看看第二部分。

在 Ethers 中設置gasLimitandgasPrice

是文件中的相關部分,但讓我們解釋一下。每當您通過乙太幣進行交易時,您都可以overrides在您的參數之後設置一個對象。在這種情況下,這是您的原始合約呼叫:

const tx = await router.swapExactTokensForTokens(
   amountIn,
   amountOutMin,
   [tokenIn, tokenOut],
   addresses.recipient,
   Date.now() + 1000 * 60 * 3 //3 minutes
 );

因此,如果您想設置 agasPrice為 100 和 agasLimit為 9M,您可以輸入:

const tx = await router.swapExactTokensForTokens(
   amountIn,
   amountOutMin,
   [tokenIn, tokenOut],
   addresses.recipient,
   Date.now() + 1000 * 60 * 3, //3 minutes
   {
       gasPrice: 100,
       gasLimit: 9000000
   }
 );

就是這樣!

注意:gasPrice在這種情況下沒有理由設置高。這裡的問題是沒有足夠的 gas 或內部錯誤,而不是您沒有為 gas 支付足夠的費用。一般來說,雖然只是在一般情況下,低gas價格不會讓你的交易失敗,只會讓它們需要很長時間才能被開採。gasLimit是調節您可以花費多少汽油的因素,因此增加它在理論上會有所幫助(儘管在這種情況下可能不是,見下文)。

探勘錯誤

但是在你跑去設置一個 high 之前gasLimit,讓我們看看那個錯誤:

ERROR:
reason: 'cannot estimate gas; transaction may fail or may require manual gas limit',
   code: 'UNPREDICTABLE_GAS_LIMIT',
   error: Error: gas required exceeds allowance (3807079) or always failing transaction 

該錯誤列出了兩個可能的原因:

  1. 氣體限制太低 ( gas required exceeds allowance)
  2. 有錯誤 ( always failing transaction)

你知道如何解決第一個問題,但你怎麼知道它是第一個還是第二個?這裡有一個提示 - 估算器告訴你它設置了什麼gasLimit:3807079。快速瀏覽一下GasNow,它看起來像 Uniswap v2(這是你正在使用的 BSC 上交換程式碼的基礎)是〜 34.5K 氣體。這是一個暗示,其他事情是錯誤的。

值得一提的是,目前準確錯誤消息的狀態還沒有那麼發達,所以你會經常遇到這樣的錯誤,知道如何查看它們並獲得線索是很好的。

所以氣體暗示​​了另一個錯誤。查看您提供的程式碼,並將其與 Uniswap 文件中的程式碼進行比較(我在頁面上使用了一個片段作為參考),看起來他們的程式碼與您的deadline參數之間存在很大差異。你的程式碼:

Date.now() + 1000 * 60 * 3, //3 minutes

他們的:

Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time

最大的區別是他們Math.floor()用來確保他們沒有任何小數。您很可能將浮點數作為deadline參數,並且很有可能導致事情失敗。(它們還除以 1000 而不是添加它,這意味著您的數量不是像您想像的那樣 3 分鐘 -Date.now返回以毫秒為單位的時間(Source。)嘗試將該行包裝進去Math.floor(並除以 1000 而不是添加)。

希望有幫助!

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