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

如何在Solidity合约中与Goerli WETH合约交互实现ETH包装?

解决Goerli链上与官方WETH合约交互包装ETH的问题

问题分析

你当前的代码错误地继承了ERC20并创建了新的WETH代币,完全没有和Goerli链上的官方WETH合约(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6)产生交互。要实现包装ETH为官方WETH,核心是直接调用该合约的标准方法,而非自行发行代币。

核心解决方案

  1. 定义WETH合约接口:官方WETH合约提供deposit()(存ETH换WETH)和withdraw(uint256)(销毁WETH提ETH)等核心方法,只需声明这些方法即可实现交互。
  2. 移除不必要的ERC20继承:无需自行创建代币,专注于和已部署的官方WETH合约交互。
  3. 实现交互逻辑:让用户通过合约存入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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:20:15