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

为什么我部署在Ropsten的Solidity智能合约无法转出1以太币?

问题原因及修复方案
  • 合约无足够余额完成转账
    你调用payRequest方法时发起的交易value为0,既没有在调用时向合约转入对应金额的ETH,也没有提前给合约充值ETH,合约账户本身没有可用于转出的余额,因此call操作返回的success字段为false,转账实际失败。
  • payRequest方法缺少payable修饰符
    如果你希望调用payRequest的同时由调用方直接支付转账金额,必须给payRequest方法添加payable修饰符,否则该方法无法接收用户调用时附带的ETH。
  • 转账逻辑缺少校验规则
    当前代码中即使call转账失败也不会回滚交易,还会正常触发RequestPaid事件,会造成转账成功的假象。你需要在收到success为false的返回后主动回滚交易,或者做对应的错误处理。
修复后参考代码
// SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;

contract Leger {
    struct TransferRequest {
        string title;
        uint256 amount;
        string bsb;
        string accountName;
        string accountNumber;
    }

    event PaymentReceive(address from, uint256 amount);
    event TransactionBytes(bytes transactionBytes);
    event RequestPaid(address receiver, uint256 amount);

    // 添加payable修饰符,允许调用时转入ETH
    function payRequest(address payable _recipient, uint256 _amount) public payable {
        // 校验调用方转入的ETH金额与约定转账金额一致
        require(msg.value == _amount, "Transfer amount mismatch");
        (bool success, bytes memory transactionBytes) = _recipient.call{value:_amount}('');
        // 转账失败直接回滚交易
        require(success, "Transfer to recipient failed");
        
        emit TransactionBytes(transactionBytes);
        emit RequestPaid(_recipient, _amount);
    }

    receive() external payable {
        emit PaymentReceive(msg.sender, msg.value);
    }
}
使用说明
  • 采用上述修改方案后,调用payRequest方法时,需要将交易的value设置为你要转账的1ETH,同时_amount参数也传入1ETH对应的wei数值(1ETH = 10^18 wei)
  • 如果你希望用合约预先存储的余额转账,不需要调用方每次转账,那么不需要给payRequest加payable修饰符,但需要提前向合约地址转入足够的ETH,确保合约余额大于等于你要转出的_amount数值

内容的提问来源于stack exchange,提问作者Joey Yi Zhao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:36:04