Solidity極簡入門|第十九講: 接收ETH receive和fallback
BlockBeats 律動財經 2022-08-15 11:30
我最近在重新學 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。
暢行幣圈交易全攻略,專家駐群實戰交流
▌立即加入鉅亨買幣實戰交流 LINE 社群(點此入群)
不管是新手發問,還是老手交流,只要你想參與虛擬貨幣現貨交易、合約跟單、合約網格、量化交易、理財產品的投資,都歡迎入群討論學習!
- 從零開始學合約系列講座熱烈報名中
- 掌握全球財經資訊點我下載APP
文章標籤
上一篇
下一篇