Solidity極簡入門|第十九講: 接收ETH receive和fallback

22-08-15 11:04
閱讀本文需 6 分鐘
总结 AI 總結
看總結 收起
原文標題:《 Solidity 極簡入門: 19. 接收 ETH receive 和 fallback 》
原文作者:0xAA 


我最近在重新學 solidity,鞏固一下細節,也寫一個「Solidity 極簡入門」,供小白們使用(編程大佬可以另找教程),每週更新 1-3 講。


所有代碼和教程開源在 github: github.com/AmazingAng/WTFSolidity


回調函數


Solidity 支持兩種特殊的回調函數,receive() 和 fallback(),他們主要在兩種情況下被使用:


- 接收 ETH 

- 處理合約中不存在的函數調用(代理合約 proxy contract)


我們這一講主要介紹接收 ETH 的情況。


接收 ETH 函數 receive


receive() 只用於處理接收 ETH。一個合約最多有一個 receive() 函數,聲明方式與一般函數不一樣,不需要 function 關鍵字:receive() external payable { ... }


receive() 函數不能有任何的參數,不能返回任何值,必須包含 external 和 payable。


當合約接收 ETH 的時候,receive() 會被觸發。receive() 最好不要執行太多的邏輯因爲如果別人用 send 和 transfer 方法發送 ETH 的話,gas 會限制在 2300,receive() 太複雜可能會觸發 Out of Gas 報錯;如果用 call 就可以自定義 gas 執行更復雜的邏輯(這三種發送 ETH 的方法我們之後會講到)。


我們可以在 receive() 裏發送一個 event,例如:



有些惡意合約,會在 receive() 函數嵌入惡意消耗 gas 的內容,使得一些退款合約不能正常工作:Akutar NFT項目因此被永久鎖定了 11539 ETH,接近 2 億元!因此寫包含退款等邏輯的合約時候,一定要注意這種情況。


回退函數 fallback


fallback() 函數會在調用合約不存在的函數時被觸發。可用於接收 ETH,也可以用於代理合約 proxy contract。fallback() 聲明時不需要 function 關鍵字,必須由 external 修飾,一般也會用 payable 修飾,用於接收 ETH:fallback() external payable { ... }。


我們定義一個 fallback() 函數,被觸發時候會釋放 fallbackCalled 事件,並輸出 msg.sender,msg.value 和 msg.data:



receive 和 fallback 的區別


receive 和 fallback 都能夠用於接收 ETH,他們觸發的規則如下:



簡單來說,合約接收 ETH 時,msg.data 爲空且存在 receive() 時,會觸發 receive();msg.data 不爲空或不存在 receive() 時,會觸發 fallback(),此時 fallback() 必須爲 payable。


receive() 和 payable fallback() 均不存在的時候,向合約發送 ETH 將會報錯。


總結


這一講,我介紹了 Solidity 中的兩種特殊函數,receive() 和 fallback(),他們主要在兩種情況下被使用,他們主要用於處理接收 ETH 和代理合約 proxy contract。


原文鏈接


欢迎加入律动 BlockBeats 官方社群:

Telegram 订阅群:https://t.me/theblockbeats

Telegram 交流群:https://t.me/BlockBeats_App

Twitter 官方账号:https://twitter.com/BlockBeatsAsia

举报 糾錯/舉報
選擇文庫
新增文庫
取消
完成
新增文庫
僅自己可見
公開
保存
糾錯/舉報
提交