Solidity
估算 Solidity 中函式呼叫的 Gas 成本(鏈上)
我期待在solidity onChain中獲得特定函式呼叫的交易成本。我找到了使用
web3.estimateGasCost()
. 但我需要的是,我應該能夠在鏈上計算這個。無論如何我可以在鏈上計算這個。我的目的是,如果有人在我的契約中存入一筆金額,gas 價格應該低於他存入金額的 1%,否則應該跳過一些步驟。
謝謝
據我所知-您實際上無法從固體中估計氣體。
兩個可能有用的相關功能:
- 您可以使用
gasLeft()
; 全域變數您可以呼叫此函式來了解交易執行中剩餘的氣體量。您還可以在函式呼叫之前和之後呼叫它,以了解該函式使用了多少氣體。
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
- 到目前為止,我們得到
gasUsed
和gasPrice
,很容易計算 gas 價格。在使用solidity數字之前,將它們轉換為BigNumber對像以精確工作很重要,BN對像也有額外的方法可以使用:// 定義一個可重用的函式 const toBN = (value) => web3.utils.toBN(value);
然後計算
gasUsed
和gasPrice
const gasUsed = toBN(result.gasUsed); const gasPrice = toBN(tx.gasPrice);
最後
// gasUsed is BN object and "mul" is for multiplication const gas = gasUsed.mul(gasPrice);
請注意,不同的包最終會產生不同的資料結構,因此請確保記錄結果和事務並獲取正確的路徑