在Solidity中,回退函数(fallbackfunctions)是在合约接收到以太币或调用不存在的函数时触发的特殊函数。自Solidity0.6.0版本起,回退函数分为两种:fallback函数和receive函数。
在Solidity中,回退函数(fallback functions)是在合约接收到以太币或调用不存在的函数时触发的特殊函数。自Solidity 0.6.0版本起,回退函数分为两种:fallback
函数和receive
函数。
receive
函数:用于处理接收纯以太币转账(即直接向合约地址发送以太币,而不调用任何函数)。
必须是external
和payable
的,且不能有参数和返回值。
fallback
函数:当调用不存在的函数或向合约发送以太币但没有receive
函数时触发。
可以是payable
或非payable
,但若希望处理以太币转账,必须是payable
的。
通常用于记录调用日志、反应错误的调用或处理某些特殊逻辑。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FallbackExample {
// 记录合约的所有者
address public owner;
// 事件:当收到以太币时触发
event EtherReceived(address indexed sender, uint256 amount);
// 事件:当调用了不存在的函数时触发
event FallbackCalled(address indexed sender, uint256 amount, bytes data);
// 构造函数:设置合约所有者
constructor() {
owner = msg.sender;
}
// receive函数:接收纯以太币转账时调用
receive() external payable {
emit EtherReceived(msg.sender, msg.value);
}
// fallback函数:调用不存在的函数或向合约发送以太币但没有receive函数时调用
fallback() external payable {
emit FallbackCalled(msg.sender, msg.value, msg.data);
// 处理传入的数据
if (msg.data.length > 0) {
// 简单示例:解析前四个字节(函数选择器)
bytes4 selector;
assembly {
selector := mload(add(msg.data, 32))
}
// 根据函数选择器执行不同的逻辑
if (selector == bytes4(keccak256("someFunction()"))) {
// 调用内部函数someFunction
someFunction();
} else {
// 其他处理
}
}
}
// 提取资金函数:仅合约所有者可以调用
function withdraw(uint256 _amount) external onlyOwner {
require(address(this).balance >= _amount, "Insufficient contract balance");
payable(owner).transfer(_amount);
}
// 获取合约当前余额
function getContractBalance() external view returns (uint256) {
return address(this).balance;
}
// 修饰符:限制只有合约所有者可以调用
modifier onlyOwner() {
require(msg.sender == owner, "Only the contract owner can call this function");
_;
}
}
合约声明:
contract FallbackExample {}
: 定义一个合约。合约所有者:
address public owner;
: 记录合约的所有者地址。事件:
event EtherReceived(address indexed sender, uint256 amount);
: 当收到以太币时触发。event FallbackCalled(address indexed sender, uint256 amount, bytes data);
: 当调用不存在的函数或向合约发送以太币但没有receive
函数时触发。构造函数:
constructor() { owner = msg.sender; }
: 部署合约时执行,设置合约所有者。receive
函数:
receive() external payable { emit EtherReceived(msg.sender, msg.value); }
: 接收纯以太币转账时调用,记录发送者和金额。fallback
函数:
fallback() external payable { emit FallbackCalled(msg.sender, msg.value, msg.data); ... }
: 当调用不存在的函数或向合约发送以太币但没有receive
函数时调用,记录发送者、金额和调用数据。
if (msg.data.length > 0) { ... }
: 检查传入数据是否存在。
assembly { selector := mload(add(msg.data, 32)) }
: 使用内联汇编从msg.data
中加载前四个字节作为函数选择器。
if (selector == bytes4(keccak256("someFunction()"))) { ... }
: 检查函数选择器是否匹配特定函数,并调用相应逻辑。
提现函数:
function withdraw(uint256 _amount) external onlyOwner { ... }
: 提取合约中的以太币,只有合约所有者可以调用。获取合约余额函数:
function getContractBalance() external view returns (uint256) { return address(this).balance; }
: 返回合约当前的以太币余额。修饰符:
modifier onlyOwner() { require(msg.sender == owner, "Only the contract owner can call this function"); _; }
: 限制只有合约所有者可以调用某些函数。receive
函数:用于处理接收纯以太币转账。fallback
函数:用于处理调用不存在的函数或向合约发送以太币但没有receive
函数时的情况。可以根据传入的msg.data
执行不同的逻辑。fallback
函数可以使用内联汇编解析传入的数据,并根据数据执行相应的逻辑,如调用特定的内部函数。如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!