Solidity fallback函数和receive函数详解(2023版)

本文介绍了智能合约中的两个关键函数:receive()和fallback(),用于处理外部转账。当合约接收到资金时,receive函数自动执行,增加合约的总金额并记录发送者地址。如果调用不匹配,fallback函数作为备用执行。示例代码展示了如何在合约中实现这些功能,以便从MetaMask等钱包向合约转账。

receive函数

  • 原型:receive() external payable;
  • 作用:接受外部转账时需要实现此函数;

fallback函数

  • 原型:fallback() external [payable];
  • 作用:合约函数调用不匹配且合约未实现receive函数,则触发fallback函数执行;

示例代码如下:

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

contract receive_demo{
    uint256 totalAmount;
    address[] public addrs;
    receive() external payable{
        totalAmount+=msg.value;
        addrs.push(msg.sender);

    }

    function getBalance()public view returns(uint256,uint256)
    {
        return(totalAmount,address(this).balance);
    }

    fallback() external{}
}

通过这两个特殊函数,我们就可以实现外部转账的功能,比如从metamask账户转账到该合约中。

### 详细说明 在Solidity中,`call`是`address`类型的低级成员函数,用于与其他合约交互。其返回值为`(bool, bytes memory)`,分别对应`call`是否成功以及目标函数的返回值。它是官方推荐的通过触发`fallback`或`receive`函数发送ETH的方法。不过,不推荐用`call`来调用另一个合约,因为调用不安全合约的函数时,会把主动权交给对方合约,推荐的方法仍是声明合约变量后调用函数。当不知道对方合约的源代码或ABI,无法生成合约变量时,可以通过`call`调用对方合约的函数 [^1]。 ### 使用方法 #### 仅发送ETH,不传入data ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.26; contract SendEther { // 构造函数,payable使得部署的时候可以转eth进去 constructor() payable {} function callEther(address payable recipient, uint256 amount) public returns (bool) { (bool success, ) = recipient.call{value: amount}(""); require(success, "Transfer failed."); return success; } } ``` 此代码中,`recipient.call{value: amount}("")`仅发送指定数量的ETH给`recipient`地址,不传入额外的数据 [^2]。 #### 调用合约函数 使用`call`调用合约函数,首先需要外部合约的地址,通过合约地址`.call(函数标志符)`的方式来调用合约。函数标志符是对于函数声明哈希之后的前4个字节的数据。例如,若要调用`cat`合约中的`eat`方法: ```solidity // 假设已知外部合约cat的地址 address c = 0x345678...; c.call(bytes4(keccak256("eat()"))); ``` 这里`bytes4(keccak256("eat()"))`就是`eat()`函数函数标志符 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值