原文: 《Solidity 極簡入門: 20. 發送ETH transfer,send 和call》

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

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

Solidity 有三種方法向其他合約發送ETH,他們是:transfer(),send() 和call(),其中call() 是被鼓勵的用法。

接收ETH 合約

我們先部署一個接收ETH 合約ReceiveETH。 ReceiveETH 合約裡有一個事件Log,記錄收到的ETH 數量和gas 剩餘。還有兩個函數,一個是receive(),收到ETH 被觸發,並發送Log 事件;另一個是查詢合約ETH 餘額的getBalance().

WTF Solidity極簡入門第二十講:發送ETH transfer,send和call

部署好合約後,運行getBalance() 函數,可以看到當前合約的ETH 餘額為0.

發送ETH 合約

我們將實現三種方法向ReceiveETH 合約發送ETH。首先,先在發送ETH 合約SendETH 中實現payable 的構造函數和receive(),讓我們能夠在部署時和部署後向合約轉賬。

WTF Solidity極簡入門第二十講:發送ETH transfer,send和call

transfer

- 用法是transfer(發送ETH 數額)。

- transfer() 的gas 限制是2300,足夠用於轉賬,但對方合約的fallback() 或receive() 函數不能實現太複雜的邏輯。

- transfer() 如果轉賬失敗,會自動revert(回滾交易)。

代碼樣例,注意參數中的_to 填ReceiveETH 合約的地址,amount 是ETH 轉賬金額:

WTF Solidity極簡入門第二十講:發送ETH transfer,send和call

send

- 用法是send(發送ETH 數額)。

- send() 的gas 限制是2300,足夠用於轉賬,但對方合約的fallback() 或receive() 函數不能實現太複雜的邏輯。

- send() 如果轉賬失敗,不會revert。

- send() 的返回值是bool,代表著轉賬成功或失敗,需要額外代碼處理一下。

代碼樣例:

WTF Solidity極簡入門第二十講:發送ETH transfer,send和call

call

- 用法是call{value: 發送ETH 數額}("")。

- call() 沒有gas 限制,可以支持對方合約fallback() 或receive() 函數實現複雜邏輯。

- call() 如果轉賬失敗,不會revert。

- call() 的返回值是(bool, data),其中bool 代表著轉賬成功或失敗,需要額外代碼處理一下。

代碼樣例:

WTF Solidity極簡入門第二十講:發送ETH transfer,send和call

運行三種方法,可以看到,他們都可以成功的向ReceiveETH 合約發送ETH。

總結

這一講,我們介紹solidity 三種發送ETH 的方法:transfer,send 和call。

call 沒有gas 限制,最為靈活,是最提倡的方法;transfer 有2300 gas 限制,但是發送失敗會自動revert 交易,是次優選擇;send 有2300 gas 限制,而且發送失敗不會自動revert 交易,幾乎沒有人用它。

推特: @0xAA_Science

社區: Discord微信群官網wtf.academy

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