You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测发送至合约的代币?通过receive/fallback识别非ETH类代币地址

检测发送至合约的币/代币类型

原生币(ETH/BNB等)的处理

当用户直接向合约转账原生币时,会触发合约的receive()或fallback()函数。这类原生资产没有合约地址,可通过msg.value确认转账金额,直接判定为链原生币。

示例代码:

receive() external payable {
    emit NativeReceived(msg.sender, msg.value);
}

event NativeReceived(address indexed sender, uint256 amount);

ERC20类代币的核心检测方法

重要提示:直接向合约转账ERC20代币不会触发receive()或fallback()——因为ERC20转账本质是调用代币自身合约的transfer/transferFrom方法,而非直接向你的合约发送资产。要获取代币地址,需通过ERC20标准的回调机制实现:

实现步骤

  1. 实现IERC20Receiver接口的onERC20Received函数,当代币合约完成转账后,会自动调用该函数并传入代币地址参数。
  2. 函数需返回指定的selector值,否则代币合约会回滚转账。

示例代码:

pragma solidity ^0.8.0;

interface IERC20Receiver {
    function onERC20Received(address operator, address from, address token, uint256 amount, bytes calldata data) external returns (bytes4);
}

contract TokenDetector is IERC20Receiver {
    event ERC20Received(address indexed from, address indexed token, uint256 amount);

    function onERC20Received(address operator, address from, address token, uint256 amount, bytes calldata data) external override returns (bytes4) {
        // `token` 参数即为转入的代币合约地址(如WBNB、BUSD的地址)
        emit ERC20Received(from, token, amount);
        
        // 必须返回该selector以确认接收
        return IERC20Receiver.onERC20Received.selector;
    }

    // 处理原生币的receive函数
    receive() external payable {
        emit NativeReceived(msg.sender, msg.value);
    }

    event NativeReceived(address indexed sender, uint256 amount);
}

常见误区

  • 不要尝试在fallback()中获取ERC20代币地址:fallback()仅在调用合约不存在的函数且附带原生币时触发,与ERC20转账无关。
  • 必须返回正确的selector:合规的ERC20代币会验证接收合约的回调返回值,返回错误会导致转账失败。
  • 若仅需处理特定代币,可监听该代币的Transfer事件,但通用场景下回调函数更直接可靠。

内容的提问来源于stack exchange,提问作者hertac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:20:32