Solidity

估算 Solidity 中函式呼叫的 Gas 成本(鏈上)

  • March 6, 2022

我期待在solidity onChain中獲得特定函式呼叫的交易成本。我找到了使用web3.estimateGasCost(). 但我需要的是,我應該能夠在鏈上計算這個。無論如何我可以在鏈上計算這個。

我的目的是,如果有人在我的契約中存入一筆金額,gas 價格應該低於他存入金額的 1%,否則應該跳過一些步驟。

謝謝

據我所知-您實際上無法從固體中估計氣體。

兩個可能有用的相關功能:

  1. 您可以使用gasLeft(); 全域變數

您可以呼叫此函式來了解交易執行中剩餘的氣體量。您還可以在函式呼叫之前和之後呼叫它,以了解該函式使用了多少氣體。

  1. tx.gasprice也可用作全域變數

成功載入合約後,呼叫函式,呼叫函式會返回一個對象。

 const result = await contract.methods
   .purchase(...args)
   .send({ from: account.data, value });
 console.log("result of calling contract function", result);

日誌的結果將是這樣的:

       {
// we need this hash to create the transaction    transactionHash:'0x1fef7f56dfa3e29aea427545de0d2b2a170c4a6e6df827a34949d37c9076ad6a', 
   transactionIndex: 0, 
   blockHash:'0x5ea8d44dc43ed4390083a6f7a9288215cf8d825dbe19771547d3c4be6ced5c3c', blockNumber: 423, from: '0xd75536f6b5712f78d444ba0c3b8aae74b7a226ba', …}
       blockHash: "0x5ea8d44dc43ed4390083a6f7a9288215cf8d825dbe19771547d3c4be6ced5c3c"
       blockNumber: 423
       contractAddress: null
       cumulativeGasUsed: 133009
       events: {}
       from: "0xd75536f6b5712f78d444ba0c3b8aae74b7a226ba"
       // ------------WE NEED gasUsed----------------
       gasUsed: 133009
       logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
       status: true
       to: "0xf2654762d9348d332ab707ca51d40cc8f84f9bb3"
       transactionHash: "0x1fef7f56dfa3e29aea427545de0d2b2a170c4a6e6df827a34949d37c9076ad6a"
       transactionIndex: 0
       [[Prototype]]: Object
  • 從上面得到的“transactionHash”創建交易
const tx = await web3.eth.getTransaction(result.transactionHash);

從 tx 我們可以得到gasPrice

console.log("transaction",tx)

這是tx我們需要的對象gasPrice

   {
v: '0x0a96', 
r: '0x015550053e18134d342879d0255ba1b4dce9b60339764e7c61538397bf91ddaa', 
s: '0x5d995ff90c19b98fb0b941f4cab7022d140fa7f9a5b2ba74f1eff397e8a61e00', 
to: '0xF2654762d9348D332Ab707CA51d40cc8f84F9BB3', gas: 201726, …} 
accessList: null 
blockHash: null 
blockNumber: null 
from: "0xD75536f6b5712f78D444bA0C3b8Aae74B7A226bA" 
gas: 201726 
// ------- we need gasPrice--------
gasPrice: "20000000000" 
hash: "0xc9665699efc0da2fb3adc23cec11a0e662ca65d1fab4b6a2517de5bade392155" input: "0xd76821cb38343733353500000000000000000000000000000000000000000000000000002bd67188592a17673351fbfbcf90c77bced32546b2528ba30334b36f4a4f9630" nonce: 259 r: "0x015550053e18134d342879d0255ba1b4dce9b60339764e7c61538397bf91ddaa" s: "0x5d995ff90c19b98fb0b941f4cab7022d140fa7f9a5b2ba74f1eff397e8a61e00" to: "0xF2654762d9348D332Ab707CA51d40cc8f84F9BB3" transactionIndex: null type: 0 v: "0x0a96"
value: "3609000000000000" 
[[Prototype]]: Object
  • 到目前為止,我們得到gasUsedgasPrice,很容易計算 gas 價格。在使用solidity數字之前,將它們轉換為BigNumber對像以精確工作很重要,BN對像也有額外的方法可以使用:

// 定義一個可重用的函式 const toBN = (value) => web3.utils.toBN(value);

然後計算gasUsedgasPrice

 const gasUsed = toBN(result.gasUsed);
 const gasPrice = toBN(tx.gasPrice);

最後

 // gasUsed is BN object and "mul" is for multiplication
 const gas = gasUsed.mul(gasPrice);

請注意,不同的包最終會產生不同的資料結構,因此請確保記錄結果和事務並獲取正確的路徑

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