Tokens

嘗試轉移 erc20 代幣,但始終遇到 gas * price + value 資金不足

  • September 2, 2020

我正在嘗試轉移一個 erc20 代幣,但是一直遇到 gas * price + value 的資金不足,無論我有多少 eth,我還有一個估計函式,它返回的值比我的值低幾倍乙。

我正在使用 Infura。

我的 ETH 餘額是:

79475000000000000 (0,079475)

這是我的估計輸出:

2020-08-31 14:49:26,036 INFO  [EthResource] (vert.x-worker-thread-1) ########## Entering doTokenEstimateTransactionFee...
2020-08-31 14:49:26,513 INFO  [Web3jService] (vert.x-worker-thread-1) >>>>>>>>>> (Token tx) DefaultGasProvider.GAS_LIMIT = 4300000
2020-08-31 14:49:26,673 INFO  [Web3jService] (vert.x-worker-thread-1) >>>>>>>>>> (Token tx) ethEstimateGas.amountUsed = 21584
2020-08-31 14:49:26,674 INFO  [Web3jService] (vert.x-worker-thread-1) >>>>>>>>>> (Token tx) ethGasPrice.gasPrice = 217000000000
2020-08-31 14:49:26,674 INFO  [Web3jService] (vert.x-worker-thread-1) >>>>>>>>>> (Token tx) estimated tx fee = 4683728000000000
2020-08-31 14:49:26,674 INFO  [EthResource] (vert.x-worker-thread-1) ########## (success) Leaving doTokenEstimateTransactionFee...

所以費用應該是0,004683728,比我的餘額少。

這是我的程式碼:

@Synchronized
fun TokenTransferFrom(TokenTransferFromDto: TokenTransferFromDto): ResultDto {
   return try {
       val sourceCredentials: Credentials = Util.generateCredentialsBip32(TokenTransferFromDto.sourceMnemonic)
       return if (TokenTransferFromDto.sourcePrivateKey == sourceCredentials.ecKeyPair.privateKey.toString(16)) {
           val fastRawTransactionManager = FastRawTransactionManager(web3j, sourceCredentials, NoOpProcessor(web3j))
           // Load contract by source
           val TokenSource = load(infuraTokenContractAddress, web3j, fastRawTransactionManager, DefaultGasProvider())
           val transactionReceipt = TokenSource.transfer(TokenTransferFromDto.destination, TokenTransferFromDto.amount).send()
           if (!transactionReceipt.isStatusOK) {
               return wrapError("transactionReceipt.isStatusOK false", transactionReceipt.status)
           }
           logger.info(">>>>>>>>>> TokenTransferFrom txHash = ${transactionReceipt.transactionHash}")
           ResultDto("success", null, "", transactionReceipt.transactionHash, null, null, null)
       } else {
           wrapError("", "Invalid mnemonic or private key")
       }
   } catch (e: Exception) {
       logger.error(">>>>>>>>>> EXCEPTION: ${e.message}")
       wrapError("", e.message.toString())
   }
}

有人能告訴我我必須改變什麼才能指定我自己的 GAS_LIMIT 嗎?

這是我不斷遇到的錯誤:

2020-08-31 14:54:34,787 ERROR [Web3jService] (vert.x-worker-thread-4) >>>>>>>>>> EXCEPTION: Error processing transaction request: insufficient funds for gas * price + value

我對 kotlin,java 完全陌生,如果我很笨,很抱歉。謝謝。

我設法解決了這個問題,這是由於應用程序將預設 GAS_PRICE 和 GAS_LIMIT 設置為我們太高或太低的值。

例如,web3j API 將合約的 GAS_LIMIT 設置為 4,300,000,但 GAS_PRICE 設置為 22 GWEI(22,000,000,000 WEI),遠低於網路平均 gas 價格 450 GWEI(450,000,000,000 WEI)。

首先,我調整了 GAS_PRICE 以匹配目前平均網路 GAS_PRICE,但仍然遇到相同的“gas * price + value 資金不足”錯誤,此時我認為 API 試圖保留的 Transaction cost (交易能夠保留的金額超過它將花費的金額)大於我的餘額

(450,000,000,000 * 4,300,000 = 1,935,000,000,000,000,000 WEI

$$ 1.935 ETH $$). 所以下一步是降低 GAS_LIMIT,對於正常的 ETH 交易,它通常設置為 21,000,但代幣交易更昂貴,所以我將其設置為 30,000。最後,我的交易通過並出現在網路上,但大約 10 分鐘後,交易失敗並出現錯誤 OUT OF GAS。這意味著我指定的 GAS_LIMIT 太低,所以我將其增加到 100,000。這意味著在目前的 GAS_PRICE 下,交易的最大成本約為 20 $ . The transaction went through again and got confirmed within a minute, costing me 9 $ .

這是更新後的程式碼,以防有人想知道我是如何更新 GAS_LIMIT 和 GAS_PRICE 的。

@Synchronized
fun TokenTransferFrom(TokenTransferFromDto: TokenTransferFromDto): ResultDto {
   return try {
       val sourceCredentials: Credentials = Util.generateCredentialsBip32(TokenTransferFromDto.sourceMnemonic)
       return if (TokenTransferFromDto.sourcePrivateKey == sourceCredentials.ecKeyPair.privateKey.toString(16)) {
           val fastRawTransactionManager = FastRawTransactionManager(web3j, sourceCredentials, NoOpProcessor(web3j))
           // Load contract by source
           val TokenSource = load(infuraTokenContractAddress, web3j, fastRawTransactionManager, DefaultGasProvider())

           //
           // NEW CODE STARTS HERE
           //
           
           // Generate a new gasProvider using the current network gasPrice and our own gasLimit
           val gasProvider = StaticGasProvider(TokenSource.requestCurrentGasPrice(), BigInteger.valueOf(100000))
           // Set our own gasProvider as the current gasProvider
           TokenSource.setGasProvider(gasProvider)
           
           //
           // NEW CODE ENDS HERE
           //
           
           val transactionReceipt = TokenSource.transfer(TokenTransferFromDto.destination, TokenTransferFromDto.amount).send()
           if (!transactionReceipt.isStatusOK) {
               return wrapError("transactionReceipt.isStatusOK false", transactionReceipt.status)
           }
           logger.info(">>>>>>>>>> TokenTransferFrom txHash = ${transactionReceipt.transactionHash}")
           ResultDto("success", null, "", transactionReceipt.transactionHash, null, null, null)
       } else {
           wrapError("", "Invalid mnemonic or private key")
       }
   } catch (e: Exception) {
       logger.error(">>>>>>>>>> EXCEPTION: ${e.message}")
       wrapError("", e.message.toString())
   }
}

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