估計Gas 的限制是什麼?它的估計什麼時候會大錯特錯?
web3.eth.estimateGas
和 JSON-RPC估計Gas 可用於在製作交易之前查看應該為交易指定多少氣體。既然是估計,有什麼限制嗎?在哪些情況下應該少依賴它,因為它可能會產生沒有意義或不准確的估計?
estimateGas的工作方式是假裝交易實際上包含在區塊鏈中,然後返回如果假裝操作是真實的,那麼將收取的確切氣體量。換句話說,它使用與礦工計算實際費用完全相同的程序。
考慮到這種方法,一個不經意的觀察者可能會認為沒有限制,並且估計總是完全正確的。不幸的是,他們會誤會。
想像一個簡單的合約,它檢查最近的區塊雜湊,然後僅當區塊雜湊中的第 10 位為 1 時才呼叫另一個耗油量大的合約。如果您使用estimateGas 來衡量呼叫這個簡單合約的交易的消耗,您的結果將完全取決於最近的塊是否在其塊雜湊的第 10 位中包含 1。 如果在您呼叫estimateGas 和實際包含交易之間發布了一個新塊,那麼您的估計有50% 的可能性是非常錯誤的。這似乎是一個人為的例子,但許多合約使用塊雜湊作為熵的來源,並根據雜湊是什麼來改變它們的行為。所以這在野外肯定會發生。
但它變得更糟。 如果你的交易呼叫的合約根據送出給它的交易改變了它的行為怎麼辦?現在,根據送出交易的順序**, gas 消耗可能會有所不同**。
例如,假設一個通常呼叫的合約幾乎總是只花費幾百個 gas 來呼叫。但它的程式碼中包含一個奇怪的子句,因此由特定密鑰簽名的消息會改變其行為,使其每次呼叫都會消耗數百萬的 gas。然後,相同的密鑰能夠改變行為。現在,該密鑰的所有者可以隨意更改合約的 gas 消耗量。 如果所有者是礦工,他們可以使用這個“受困合約”在他們計算的每個區塊開始時打開這種浪費氣體的行為,並在結束時關閉。只要他們從不公開發布這些私人交易,那麼每次呼叫estimateGas 都會返回一個低值,而每次呼叫estimateGas真正送出的交易將花費數百萬的氣體(直接進入礦工的口袋)。通過仔細的合約設計,他們甚至不必實際執行計算,因為他們知道結果會是什麼。他們可以隨意執行這種“竊取費用的攻擊”,只是偶爾執行它,所以直到很多使用者被吸引後才會意識到。
同樣,這個例子是人為的。但關鍵是,您應該始終考慮攻擊者是否可以通過您做出錯誤的估計來獲得收益。如果存在可能的向量,請在您的應用程序部分添加額外程式碼以處理您的估計錯誤的情況。 您應該始終使用的一種簡單技術是包括合理的氣體限制。這樣,攻擊者可以做的事情至少有一個上限。除此之外,請記住它被稱為估計Gas 呼叫,而不是GuaranteedMaximumGas呼叫,並且您對它的依賴是合理的。
**tl;dr:
如果您的交易結果有任何方式根據送出的時間或送出人而改變,則估計 Gas 可能會出現任意大的錯誤。採取額外的預防措施。**