Erc-20

使用 ethers js 估算 ERC20 代幣的傳輸氣體,無需代幣

  • June 25, 2021

我試圖能夠準確估計使用 Ethers js 發送 ERC20 令牌所需的氣體,而無需首先需要該令牌。目前,我能夠得到一個估計,儘管它似乎不是非常準確。我的程式碼是:

const {ethers} = require("ethers");

const provider = new ethers.providers.EtherscanProvider('homestead', 'API_KEY');

const sendGas = async (to, tokenAddress, amount) => {
   const abi = [
       // Some details about the token
       "function name() view returns (string)",
       "function symbol() view returns (string)",
     
       // Get the account balance
       "function balanceOf(address) view returns (uint)",
     
       // Send some of your tokens to someone else
       "function transfer(address to, uint amount)",
     
       // An event triggered whenever anyone transfers to someone else
       "event Transfer(address indexed from, address indexed to, uint amount)"
   ];


   const signer = new ethers.Wallet('PRIVATE_KEY');
   const account = signer.connect(provider);

   const contract = new ethers.Contract(
       tokenAddress,
       abi,
       account
   ); 

   const gasCost = await contract.estimateGas.transfer(to, amount)
   console.log(parseInt(gasCost, 10));
   return gasCost;
   
}

sendGas('PUBLIC_KEY', '0xa36085F69e2889c224210F603D836748e7dC0088', '0');

當我在給定正確輸入的情況下執行程式碼時,它似乎按預期工作。除了實際使用的氣體和估計的數量可能會有很大差異。首先,為了讓函式正確執行,我需要將金額作為 0 傳遞,因為我希望能夠估計我還沒有的代幣的氣體。如果我嘗試使用非零餘額獲取我沒有的代幣,我會收到餘額不足的錯誤。我的問題是我需要氣體精確到幾千氣體,但它目前到處都是。例如,我嘗試在 kovan 上轉移一枚硬幣,估計需要 21560 個 gas,然而,它最終使用 35322 個 gas 進行實際交易(我發現甚至有很大的差異)。這是由於發送金額為0造成的嗎?如果是這樣的話,

不太重要,但如果有人有見識,我將不勝感激,我如何確定令牌的轉移 abi?我目前使用的只是 ethers js 文件中提供的標準。這適用於所有代幣嗎?如果沒有,有沒有辦法讓 abi 轉移任何代幣?

TLDR;並非所有 ERC20 轉賬的成本都相同。影響 gas 成本的 ERC20 轉賬主要有四種情況。大多數情況下,您最好為gasLimit. 但是,如果您真的想將其最小化,則可以盡力弄清楚情況。

首先,為了讓函式正確執行,我需要將金額作為 0 傳遞,因為我希望能夠估計我還沒有的代幣的氣體

如果你傳入 0,你可能會得到一個估計值,它可能與實際的 gas 消耗量不同,因為 EVM gas 的定價方式。

假設轉賬金額非零,有四種情況:

  • 使用者正在轉移到一個已經擁有一些代幣的帳戶(由於 SSTORE 5000 定價,這會便宜一些)
  • 使用者正在轉移到一個沒有餘額的帳戶(由於 SSTORE 20000 定價,這將是昂貴的)
  • 使用者正在轉移他們所有的代幣(這將在清空插槽時產生 15000 的退款,這使得 tx 更便宜,但此退款已被使用 gas 代幣利用,EIP3298建議刪除此退款)
  • 使用者正在轉移他們的一些代幣(由於插槽未清空,因此不會退款)。

ERC20 Transfer tx的gas消耗可以分解為:

gas = intrinsic + computation

intrinsic = 21000 + calldata cost
data ~= 560 (in case of ERC20 transfer)

computation ~= balanceof SLOAD + updatebalance SSTORE x 2 + event emit

例如,我嘗試在 kovan 上轉移一枚硬幣,並得到 21560 gas 的估計

您很可能將 tx 發送到沒有任何字節碼的地址。這不會使您的交易失敗。估計/消耗的氣體將只是內在成本。

如何確定代幣的轉賬 abi?我目前使用的只是 ethers js 文件中提供的標準。這適用於所有代幣嗎?

ABI 由 ERC20 標准定義。它應該適用於所有“ERC20”代幣。如果某些令牌具有不同的標準(如 ERC777),它可能無法正常工作,您必須使用正確的 ABI。

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