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

如何校验外部地址向智能合约转账ETH的操作是否成功

核心逻辑解答

Solidity中被payable修饰的函数具备ETH接收能力,以太坊交易的原子性保证了:当函数进入执行逻辑时,调用方本次调用附带的ETH(即msg.value对应数额)已经自动从msg.sender账户扣除,转入合约地址,不存在「转账半途中进入函数执行」的情况,不需要额外做合约侧的入账校验。

如果你要求调用方必须转入指定数额的ETH,只需要加对应判断即可:

// 示例要求至少转入1wei ETH,可按需调整阈值
require(msg.value > 0, "Must send ETH to call this function");

完整实现参考

你需要先提前定义对应存储变量,实现存mapping再转作者的逻辑:

// 提前初始化:存储tokenId对应作者的地址,注意要定义为payable才能接收ETH
mapping(uint => address payable) public tokenAuthor;
// 按你的需求存入mapping:记录每个tokenId累计收到的ETH总额
mapping(uint => uint) public tokenTotalReceived;

function sendToAuthor (uint tokenId) public payable{
    // 校验1:本次调用确实转入了符合要求的ETH
    require(msg.value > 0, "No ETH sent in this call");
    // 校验2:对应tokenId的作者地址有效
    require(tokenAuthor[tokenId] != address(0), "Token does not exist");

    // 先更新mapping存储记录
    tokenTotalReceived[tokenId] += msg.value;

    // 给对应作者转账,推荐使用call方法兼容不同地址类型
    (bool transferSuccess, ) = tokenAuthor[tokenId].call{value: msg.value}("");
    // 校验给作者的转账结果,失败则整个交易回滚,ETH会退回给调用方
    require(transferSuccess, "Failed to send ETH to author");
}

额外注意

  • 上述写法遵循了Solidity官方推荐的Checks-Effects-Interactions模式:先做参数校验、再更新合约内部状态、最后做外部地址调用,天然可以规避大部分重入风险。
  • 你不需要做任何额外逻辑校验msg.sender给合约的转账是否成功:如果转账失败,整个交易会直接回滚,根本不会进入函数内部执行逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 11:57:03