Solidity

松露測試 gasUsed 值我可以信任多少?

  • January 21, 2022

我試圖保證在 VRF 完成隨機呼叫上我不會要求超過 200k 的氣體限制。

我正在執行 truffles 測試,它們向我展示gasUsed了函式呼叫的 txn 值:

氣體用作 88252

所以主要問題是:在主網上會不會一樣gasUsed?在相同的條件下,在不同的環境主網、測試網或本地呼叫該函式;會為所有人提供相同的氣體嗎?

我可以信任 truffle test gasUsed 嗎?

PS:我知道 gasPrice 會根據時刻而變化。

Truffle 向您顯示的gasUsed值來自乙太坊客戶端返回的交易收據(參見eth_getTransactionReceiptjson-rpc)。如果使用 Truffle 在本地執行測試,使用的客戶端是Ganache

客戶端通過在其 EVM 實現上執行交易來計算氣體。在 Ganache 的情況下,使用的 EVM 是EthereumJS

EthereumJS 使用乙太坊共識測試來確保它與其他客戶端兼容。這包括確保天然氣成本相同。所有客戶端都獲得相同的值至關重要,因為沒有它他們無法正確驗證塊。當然,像trufflesuite/ganache#977這樣的錯誤總是有可能的,但這些錯誤通常會很快被發現並修補。

EVM 的工作方式不會根據合約是在主網、測試網還是本地執行而改變。不過,它確實取決於EVM 版本。確保您沒有在設置中使用舊版本,因為這確實會影響操作碼定價。

請注意,這gasUsed是實際使用的氣體量,而不是估計值。您的擔憂可能來自於看到不准確的氣體估算。通過 gas 估算,您通常會嘗試獲得給定合約函式的大致數字,有時甚至沒有指定具體的參數值,也沒有考慮您的合約可能呼叫的任何外部部署程式碼(或者至少不使用確切的外部字節碼將在主網上呼叫)。通過函式的不同路徑的成本可能大不相同,外部程式碼通常是所用氣體的很大一部分。即使你只想要一個上限,獲得一個可靠的數字通常也不容易。

我試圖保證我不會需要超過 200k 的氣體

棘手的部分是,雖然你可以指望它gasUsed是準確的,但它只會顯示你在測試套件中的確切參數以及它執行的確切區塊鏈狀態使用了多少氣體。最終你不能保證你沒有錯過任何東西,除非你的功能足夠簡單以至於這很明顯。如果您絕對需要一個可靠的上限,則沒有簡單的方法可以解決它 - 您必須徹底分析程式碼(包括您呼叫的任何外部程式碼),確定最昂貴的路徑,然後使用執行這些路徑的測試案例驗證您的假設。

即便如此,也不能絕對依賴。許多合約都是可升級的,您可以通過代理呼叫它們。如果他們得到更新,他們的成本可能會增加。例如,這始終是一種可能性fulfillRandomness()

同樣,當使用新的 EVM 版本更新主網時,某些操作碼可能會重新定價,從而導致您的合約成本不同。在這種情況下,差異可能是微不足道的,也可能是巨大的——取決於您使用這些特定操作碼的頻率。這也不僅僅是一個理論上的考慮 - 以 EIP-1884 為例,它具有破壞 Soliditytransfer()功能提供的氣體津貼的副作用,因為津貼機制在很大程度上取決於固定數量的 2300 氣體足以做某些事情。請參閱立即停止使用 Solidity 的 transfer()

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