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

测试网ETH兑换自定义代币:buyToken带值交易失败求助

问题排查与修复

核心错误分析

  • 未声明变量误用:
    • 构造函数里使用了未定义的capCoin变量,合约内声明的是token,应改为给token赋值。
    • buyToken函数中调用transfer时,用了未声明的capCoinTokensToBuy,正确参数应为计算好的tokensToBuy。
  • 逻辑触发回滚:
    当msg.value>0时,会计算出需要兑换的代币数量tokensToBuy,此时会检查合约持有的代币余额是否足够。如果合约没有储备足够的对应ERC20代币,第二个require会触发交易回滚;而msg.value=0时,tokensToBuy=0,余额检查条件恒成立,所以交易能成功确认。

修复后的合约代码

pragma solidity >=0.8.2 <0.9.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";

contract Exchange {
    ERC20 public token;
    uint public RATE = 1;

    event BuyToken(address user, uint amount, uint boughtTokens, uint balance);

    constructor() {
        token = ERC20(0x123456789);
    }

    function buyToken() payable public returns (bool success) {
        require(msg.value > 0, "You must send some Ether to buy tokens");
        uint tokensToBuy = msg.value * RATE;
        require(token.balanceOf(address(this)) >= tokensToBuy, "Not enough tokens in the reserve");
        token.transfer(msg.sender, tokensToBuy);
        emit BuyToken(msg.sender, msg.value, tokensToBuy, address(this).balance);
        return true;
    }
}

额外验证项

  1. 确认0x123456789是你自定义ERC20代币的正确合约地址,避免地址写错。
  2. 确保当前Exchange合约地址已持有足量的该ERC20代币,否则用户转入ETH时仍会触发余额不足的回滚。
  3. 测试时可先给Exchange合约转入少量代币,再调用buyToken并传入ETH,验证交易是否正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:05:22