部署Solidity Uniswap合约传入ETH触发回滚错误,求修复方案
部署合约传入ETH失败的解决方案
问题原因
你部署Uniswap合约时传入ETH报错,核心原因是合约的构造函数没有payable修饰符。部署合约的本质是调用合约构造函数,只有标记为payable的函数(包括构造函数)才能接收ETH,非payable函数收到ETH会直接触发回滚。
修复代码
如果需要在部署时接收ETH,给Uniswap合约的构造函数加上payable关键字即可:
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract CustomToken is ERC20 { constructor(string memory name, string memory symbol) ERC20(name, symbol){ _mint(msg.sender, 1000000 * 10 ** 18); } } contract Uniswap { string[] public tokens = ["CoinA", "CoinB", "CoinC"]; mapping(string => ERC20) public tokenInstanceMap; uint256 ethValue = 100000000000000; // 给构造函数添加payable修饰符 constructor() payable { for (uint i=0; i<tokens.length; i++) { CustomToken token = new CustomToken(tokens[i], tokens[i]); tokenInstanceMap[tokens[i]] = token; } } function getBalance(string memory tokenName, address _address) public view returns (uint256) { return tokenInstanceMap[tokenName].balanceOf(_address); } function getTotalSupply(string memory tokenName) public view returns (uint256) { return tokenInstanceMap[tokenName].totalSupply(); } function getName(string memory tokenName) public view returns (string memory) { return tokenInstanceMap[tokenName].name(); } function getTokenAddress(string memory tokenName) public view returns (address) { return address(tokenInstanceMap[tokenName]); } function getEthBalance() public view returns (uint256) { return address(this).balance; } function swapEthToToken(string memory tokenName) public payable returns (uint256) { uint256 inputValue = msg.value; uint256 outputValue = (inputValue / ethValue) * 10 ** 18; require(tokenInstanceMap[tokenName].transfer(msg.sender, outputValue)); return outputValue; } }
补充说明
- 你之前用0 ETH部署成功,是因为非payable函数可以接收0 ETH,不会触发回滚。
- 你的
swapEthToToken函数已经正确标记payable,调用该函数时传入ETH是正常的,问题仅出在部署阶段的构造函数上。
内容的提问来源于stack exchange,提问作者Hai Nam
相关产品推荐
相关产品推荐

