Solidity进阶:发送、接收ETH

文章介绍了Solidity合约中用于接收ETH的receive和fallback函数,以及不同转账方法如transfer、send和call的使用和区别。receive函数仅在合约直接接收ETH时调用,而fallback则在无匹配函数或附加数据时触发。此外,文章还讨论了各种转账方法的gas限制和处理失败的情况。
摘要由CSDN通过智能技术生成

接收ETH

Solidity支持两种特殊的回调函数,receive()和fallback(),他们主要在两种情况下被使用:

  1. 接收ETH
  2. 调用合约中不存在的函数
payable函数

函数+payable:能够接收主币。

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract Payable {
	// 接收eth主币
    function deposit() external payable {}
	// 获取余额
    function getBalance() external view returns(uint) {
        return address(this).balance;
    }
}
receive函数

receive()只用于处理接收ETH。一个合约最多有一个receive()函数,声明方式与一般函数不一样,不需要function关键字:receive() external payable { … }。receive()函数不能有任何的参数,不能返回任何值,必须包含external和payable。

receive() external payable {}
fallback函数

fallback()函数会在调用合约不存在的函数时被触发。可用于接收ETH,也可以用于代理合约proxy contract。fallback()声明时不需要function关键字,必须由external修饰,一般也会用payable修饰,用于接收ETH:fallback() external payable { … }。

fallback() external payable {}
receive和fallback的区别

fallback函数与receive的区别是:Receive函数只在合约转账时调用,而Fallback函数除了可以在合约转账时调用外,在合约没有函数匹配或需要向合约发送附加数据时,也调用Fallback函数。
receive和fallback都能够用于接收ETH,他们触发的规则如下:
在这里插入图片描述

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract FallBack{
    event Log(string func, address sender, uint value, bytes data);
    fallback() external payable {
        emit Log("fallback", msg.sender, msg.value, msg.data);
    }
    receive() external payable {
        emit Log("receive", msg.sender, msg.value, "");
    }

    function getBalance() external view returns(uint) {
        return address(this).balance;
    }
}

发送ETH

Solidity有三种方法向其他合约发送ETH,他们是:transfer(),send()和call(),其中call()是被鼓励的用法。
transfer:用法是接收方地址.transfer(发送ETH数额),没有返回值。transfer()的gas限制是2300,足够用于转账,但对方合约的fallback()或receive()函数不能实现太复杂的逻辑。transfer()如果转账失败,会自动revert(回滚交易)。
send:用法是接收方地址.send(发送ETH数额)。send()的gas限制是2300,足够用于转账,但对方合约的fallback()或receive()函数不能实现太复杂的逻辑。send()如果转账失败,不会revert。send()的返回值是bool,代表着转账成功或失败,需要额外代码处理一下。
call:用法是接收方地址.call{value: 发送ETH数额}(“”)。call()没有gas限制,可以支持对方合约fallback()或receive()函数实现复杂逻辑。call()如果转账失败,不会revert。call()的返回值是(bool, data),其中bool代表着转账成功或失败,需要额外代码处理一下。

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract SendEth{
    constructor() payable {}

    receive() external payable{}
	
    function sendByTransfer(address payable _to, uint amount) external payable {
        _to.transfer(amount);
    }

    function sendBySend(address payable _to, uint amount) external payable {
        bool ok = _to.send(amount);
        require(ok, "send failed");
    }

    function sendByCall(address payable _to, uint amount) external payable {
        (bool ok,) = _to.call{value: amount}("");
        require(ok, "call failed");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值