测试网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; } }
额外验证项
- 确认
0x123456789是你自定义ERC20代币的正确合约地址,避免地址写错。 - 确保当前Exchange合约地址已持有足量的该ERC20代币,否则用户转入ETH时仍会触发余额不足的回滚。
- 测试时可先给Exchange合约转入少量代币,再调用
buyToken并传入ETH,验证交易是否正常执行。
内容的提问来源于stack exchange,提问作者Adri HM
相关产品推荐
相关产品推荐

