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

Solidity跨合约发送ETH触发交易回退报错问题咨询

报错根因

交易回滚的核心原因有两个,刚好对应报错提示的两种触发场景:

  • 接收方合约receiveEther没有定义可接收原生以太币的入口。Solidity 0.8版本强制要求:如果合约要接收不指定调用函数的直接ETH转账(即通过transfer()/send()发起的转账),必须显式声明receive() external payable函数;如果转账时匹配不到对应函数,还需要带payable修饰的fallback()兜底,否则EVM会直接终止交易,抛出“被调用函数需标记为payable”的错误。
  • 发送方合约sendEther的send()函数逻辑错误。当前代码固定向目标地址转1wei,既没有使用调用该函数时传入的msg.value作为转账金额,也没有提前校验合约自身余额是否足够支付转账,一旦余额不足就会触发回滚。另外0.8版本后transfer()方法硬编码的2300gas限制在很多场景下会导致转账意外失败,已经不推荐使用。
修复后代码
pragma solidity ^0.8.15;

contract sendEther {
    function deposit() external payable {}

    function send(address payable _to) external payable {
        require(msg.value > 0, "transfer amount must be greater than 0");
        // 用call方法替代transfer,避免gas限制问题,转账金额取调用时传入的msg.value
        (bool success, ) = _to.call{value: msg.value}("");
        require(success, "ETH transfer failed");
    }

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

contract receiveEther {
    // 新增receive函数,允许合约接收直接转入的ETH
    receive() external payable {}

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

修复后按以下步骤操作即可正常完成转账:

  1. 部署两个合约后,调用sendEther.deposit()存入任意金额ETH,可通过sendEther.getBalance()确认余额到账。
  2. 调用sendEther.send(),参数填入receiveEther的合约地址,同时在交易的Value字段填入你要转账的金额,发起交易。
  3. 调用receiveEther.getBalance()即可查询到对应到账金额。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:06:25