Solidity
Solidity 0.6.1 Receive Fallback Forwarder 由於 gas 不足而恢復
我正在使用 Solidity 0.6.1 並嘗試建構一個簡單的資金轉發器。因此 ETH 被發送到合約,並將資金發送到另一個地址。
我將它部署到 Ropsten。但是每次我將 ETH 發送到合約地址時,交易都會失敗,因為
Warning! Error encountered during contract execution [Out of gas]
這是我的契約
pragma solidity ^0.6.1; contract testFallback { address payable public addr = 0x...; receive() external payable { if (msg.value > 0) { if (!addr.send(address(this).balance)) revert(); } } }
以及一個交易失敗的例子。
我試過使用
fallback() external payable
功能也一樣。我一直在這裡閱讀它,但我不確定。為什麼我的合約不能接受然後轉發 ETH i=我發送它。謝謝你的幫助。
根據評論,這可能只是氣體估算問題,您可以通過提供更多氣體來解決它。
您可以使用可能看起來有點嚇人的語法強制發送一定量的氣體。這種發送的長手方式:
bool success = address(0).call.value(msg.value).gas(2300)(abi.encodeWithSelector(""));
一些警告:
- 我不相信這個問題是由於那個
send
用完的接收器。您應該圍繞它進行測試以確定哪個步驟失敗。- 發送額外
send
的 gas 會破壞 gas 津貼,並可能使您的合約更容易受到重入攻擊。如果您遵循最佳實踐,這不是問題,因此您不依賴汽油津貼提供的保護。- 將 gas 預算硬編碼到契約中是一個失敗點。Gas 津貼和 OPCODE 的定價都會隨著時間的推移而變化。不要假設今天的算術/發現將是明天的。Aragon 項目在最近的 EVM 分叉中遇到了這種麻煩。如果您找到這樣做的理由,您可能需要不時更改常量以避免過時/失敗的方法。
更有可能的是,MetaMask 沒有提供足夠的氣體,因為估計是錯誤的。在這種情況下,它必須在客戶端解決。
您已經知道如何手動完成。一個良好的基於 Web 的 UI 將通過以下方式形成事務:
var txn = await instance.revert({value: amount, from: me, gasPrice: bid, gas: HERE});
並且您可以添加一點填充,因為您知道 MetaMask需要您的估計而不是它自己的估計。
希望能幫助到你。