備份功能正在接受超過 2300 個氣體
引用solidity doc:
在這種情況下,函式呼叫通常只有很少的 gas 可用(準確地說是 2300 gas),所以讓備份函式盡可能便宜是很重要的。特別是,以下操作將消耗比提供給回退函式的津貼更多的氣體(將狀態變數 a 更新為 100):
- 寫入儲存
- 創建契約
- 呼叫消耗大量gas的外部函式
- 發送乙太幣
所以理想情況下,我不應該在回退功能中使用複雜的邏輯。並且fallback功能不能使用超過2300gas。
我試了一下。
pragma solidity ^0.4.18; contract TestFallback{ uint public a = 0; uint public loopsize = 100; function updateLoopSize(uint _size) public { loopsize = _size; } function() public payable{ uint i = 0; for (i=0; i<loopsize; i=i+1){ a +=1; } } }
我
fallback
用loopsize = 100
. 該函式成功執行,耗氣量如下:氣體:3000000;交易成本:585049;執行成本:563777
現在,這讓我對我剛剛讀到的段落感到困惑。我什至嘗試在備份功能中進行計算和代幣轉移。他們消耗了超過 100,000 個氣體,但執行成功。那麼我錯過了什麼?
- 我可以在回退函式中使用複雜的邏輯嗎?
- 如果我需要在使用者向智能合約支付乙太幣後立即執行某些功能(如發送代幣),除了在回退函式中編寫邏輯之外,還有哪些可能的方法。
PS:對於第二個查詢,我認為製作應付功能不會有幫助。在這種情況下,使用者必須呼叫智能合約的特定方法。但我希望該使用者只需從任何錢包發送乙太幣並接收資產。(使用者不需要任何 abi 將 eth 發送到合約)
fallback 函式就像任何其他函式一樣:它得到的gas 與傳遞給它的gas 一樣多。
回退函式的不同之處在於,它是在某人進行簡單的乙太幣轉賬時呼叫的函式,例如
msg.sender.transfer(amount)
在智能合約中,或從交易所轉賬等。在這些情況下,發送的氣體很少,所以如果你想要那些案例要成功,你應該小心你在回退函式中的內容。我認為還有其他原因可以避免使用備份功能,尤其是在幫助防止錯誤方面。請參閱https://programtheblockchain.com/posts/2017/12/16/be-careful-when-using-the-solidity-fallback-function/。
2300 gas 的問題在於呼叫來自智能合約。
如果您手動觸發交易,您可以控制回退功能所需的氣體,因此不會有任何問題。
但是,如果您從智能合約觸發 .send() 或 .transfer(),則目標回退函式將被呼叫,並且只有 2300 個 gas 限制。
如果你從智能合約呼叫你的函式,它將失敗。