如何在Solidity合约中与Goerli WETH合约交互实现ETH包装?
解决Goerli链上与官方WETH合约交互包装ETH的问题
问题分析
你当前的代码错误地继承了ERC20并创建了新的WETH代币,完全没有和Goerli链上的官方WETH合约(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6)产生交互。要实现包装ETH为官方WETH,核心是直接调用该合约的标准方法,而非自行发行代币。
核心解决方案
- 定义WETH合约接口:官方WETH合约提供
deposit()(存ETH换WETH)和withdraw(uint256)(销毁WETH提ETH)等核心方法,只需声明这些方法即可实现交互。 - 移除不必要的ERC20继承:无需自行创建代币,专注于和已部署的官方WETH合约交互。
- 实现交互逻辑:让用户通过合约存入ETH兑换官方WETH,后续可直接用于Uniswap交易。
修改后的完整代码
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; pragma abicoder v2; import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol'; import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol'; // 定义WETH合约核心接口,仅声明需要调用的方法 interface IWETH { function deposit() external payable; function withdraw(uint256 amount) external; function transfer(address to, uint256 amount) external returns (bool); function balanceOf(address account) external view returns (uint256); } contract SwapExamples { ISwapRouter public immutable swapRouter; // Goerli官方WETH合约地址 address public constant WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6; uint24 public constant poolFee = 3000; constructor(ISwapRouter _swapRouter) { swapRouter = _swapRouter; } // 存入ETH兑换为官方WETH,WETH将留存于合约中(可用于后续Uniswap交易) function wrapETH() external payable { IWETH(WETH).deposit{value: msg.value}(); } // 将合约中的WETH转换为ETH并转回调用者 function unwrapWETH(uint256 amount) external { require(IWETH(WETH).balanceOf(address(this)) >= amount, "WETH余额不足"); IWETH(WETH).withdraw(amount); payable(msg.sender).transfer(amount); } // 示例:用WETH在UniswapV3进行单路径兑换(如WETH换USDC) function swapWETHToToken(address tokenOut, uint256 amountIn, uint256 minAmountOut) external returns (uint256) { TransferHelper.safeTransferFrom(WETH, msg.sender, address(this), amountIn); TransferHelper.safeApprove(WETH, address(swapRouter), amountIn); ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({ tokenIn: WETH, tokenOut: tokenOut, fee: poolFee, recipient: msg.sender, deadline: block.timestamp, amountIn: amountIn, amountOutMinimum: minAmountOut, sqrtPriceLimitX96: 0 }); return swapRouter.exactInputSingle(params); } // 接收ETH的回调(WETH合约转回ETH时触发) receive() external payable {} }
关键说明
- IWETH接口:仅声明需要调用的方法即可与已部署合约交互,无需导入完整合约代码,这是链上合约交互的标准方式。
- wrapETH方法:用户调用时传入ETH,合约会将ETH转入官方WETH合约,自动获得等量WETH并存储在合约地址中。
- unwrapWETH方法:将合约中的WETH销毁并转换为ETH,转回给调用者。
- Uniswap交互:后续可直接使用合约中的WETH调用Uniswap Router完成兑换,示例中的
swapWETHToToken方法展示了基础的单路径兑换逻辑。
内容的提问来源于stack exchange,提问作者Oriok
相关产品推荐
相关产品推荐

