Solidity

回退函式可以完成多少計算?

  • October 17, 2021

只需將 Ether 發送到合約,即可執行合約的程式碼。在 Solidity 中,此程式碼映射到它所謂的回退函式。

回退功能可以完成多少工作?

備份函式可以進行與獲得多少氣體一樣多的計算。

有 2 個案例(基本上recipient.sendrecipient.call{value:...}("")),案例 2 具有安全隱患,是 2016 年 6 月 17 日 DAO 如何被攻擊和利用的關鍵部分。

案例一:2300氣

如果使用orrecipient呼叫合約的備份功能,則只能獲得2300 的 gas 津貼recipient.transfer``recipient.sendrecipient這與使用 支付的外部帳戶相同web3.eth.sendTransaction({to:recipient, gas:21000, ...})

乙太坊部落格文章的最後一部分解釋說:

如果你想讓你的合約接收乙太幣,你必須降低它的備份功能。它只能使用 2300 gas,既不允許任何儲存寫入,也不允許沿 Ether 發送的函式呼叫。基本上,您在回退函式中唯一應該做的就是記錄一個事件,以便外部程序可以對事實做出反應。

外部程序的範例包括web3.js 過濾器和監視。

**注意:**自 2019 年 12 月起,recipient.transfer不再recipient.send推薦:在伊斯坦布爾更新後 transfer() 是否仍然安全?

案例2:盡可能多的氣體,注意安全

recipient.call{value:...}("")(並使用相關功能,如.callcode, .delegatecall)將提供備份功能幾乎

$$ 1 $$與呼叫者剩餘的氣體一樣多。 為了獲得與案例 1 相同的效果(2300 gas 津貼)和安全性,呼叫者在呼叫recipientby 時必須明確將 gas 限制為零: recipient.call{gas: 0, value: ...}("")

(theDAO沒有限制gas, 2016年6月17日遭遇重入攻擊。 )


腳註

$$ 1 $$解釋為什麼一個備份函式得到了幾乎所有的氣體,但不是所有的氣體。chriseth (Solidity 作者)

這是 EVM 的古怪之處之一。你不能只說“把我所有的汽油和電話一起送出去”,你總是必須給出一個明確的號碼。我們確實有 GAS 操作碼,它為我們提供了仍然可用的 gas 量,但問題是執行呼叫本身也會消耗一些 gas,所以我們必須從 GAS 提供的值中減去呼叫成本的 gas 量,並且我們還必須減去執行減法所需的氣體量……

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