# Solidity极简入门: 20. 发送ETH transfer,send和call **Published by:** [0xAA](https://paragraph.com/@wtfacademy/) **Published on:** 2022-05-03 **URL:** https://paragraph.com/@wtfacademy/solidity-20-eth-transfer-send-call ## Content 我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。 欢迎关注我的推特:@0xAA_Science WTF技术社群discord,内有加微信群方法:链接 所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSoliditySolidity有三种方法向其他合约发送ETH,他们是:transfer(),send()和call(),其中call()是被鼓励的用法。接收ETH合约我们先部署一个接收ETH合约ReceiveETH。ReceiveETH合约里有一个事件Log,记录收到的ETH数量和gas剩余。还有两个函数,一个是receive(),收到ETH被触发,并发送Log事件;另一个是查询合约ETH余额的getBalance().contract ReceiveETH { // 收到eth事件,记录amount和gas event Log(uint amount, uint gas); // receive方法,接收eth时被触发 receive() external payable{ emit Log(msg.value, gasleft()); } // 返回合约ETH余额 function getBalance() view public returns(uint) { return address(this).balance; } } 部署好合约后,运行getBalance()函数,可以看到当前合约的ETH余额为0.发送ETH合约我们将实现三种方法向ReceiveETH合约发送ETH。首先,先在发送ETH合约SendETH中实现payable的构造函数和receive(),让我们能够在部署时和部署后向合约转账。contract SendETH { // 构造函数,payable使得部署的时候可以转eth进去 constructor() payable{} // receive方法,接收eth时被触发 receive() external payable{} transfer用法是transfer(发送ETH数额)。transfer()的gas限制是2300,足够用于转账,但对方合约的fallback()或receive()函数不能实现太复杂的逻辑。transfer()如果转账失败,会自动revert(回滚交易)。代码样例,注意参数中的_to填ReceiveETH合约的地址,amount是ETH转账金额: // 用transfer()发送ETH function transferETH(address payable _to, uint256 amount) external payable{ _to.transfer(amount); } send用法是send(发送ETH数额)。send()的gas限制是2300,足够用于转账,但对方合约的fallback()或receive()函数不能实现太复杂的逻辑。send()如果转账失败,不会revert。send()的返回值是bool,代表着转账成功或失败,需要额外代码处理一下。代码样例: // send()发送ETH function sendETH(address payable _to, uint256 amount) external payable{ // 处理下send的返回值,如果失败,revert交易并发送error bool success = _to.send(amount); if(!success){ revert SendFailed(); } } call用法是call{value: 发送ETH数额}("")。call()没有gas限制,可以支持对方合约fallback()或receive()函数实现复杂逻辑。call()如果转账失败,不会revert。call()的返回值是(bool, data),其中bool代表着转账成功或失败,需要额外代码处理一下。代码样例: // call()发送ETH function callETH(address payable _to, uint256 amount) external payable{ // 处理下call的返回值,如果失败,revert交易并发送error (bool success,) = _to.call{value: amount}(""); if(!success){ revert CallFailed(); } } 运行三种方法,可以看到,他们都可以成功的向ReceiveETH合约发送ETH。总结这一讲,我们介绍solidity三种发送ETH的方法:transfer,send和call。call没有gas限制,最为灵活,是最提倡的方法;transfer有2300 gas限制,但是发送失败会自动revert交易,是次优选择;send有2300 gas限制,而且发送失败不会自动revert交易,几乎没有人用它。 ## Publication Information - [0xAA](https://paragraph.com/@wtfacademy/): Publication homepage - [All Posts](https://paragraph.com/@wtfacademy/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@wtfacademy): Subscribe to updates - [Twitter](https://twitter.com/0xAA_Science): Follow on Twitter