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

使用ethers.js调用Uniswap V3 exactInput()交易失败求助

Uniswap V3 exactInput 交易失败排查与修复

问题根源分析

结合你提供的交易记录和代码,导致兑换失败的核心问题及次要问题如下:

1. 缺失ERC20授权(最关键)

Uniswap Router合约需要获得你钱包中WETH的转移权限才能完成兑换操作,但你的代码完全没有执行WETH的approve授权步骤,这是交易失败的直接原因。

2. 异步处理错误

tx.wait()是异步操作,你没有添加await关键字,导致无法正确获取交易回执,也无法确认交易是否成功。

3. 冗余交易参数

txArg中的from字段无需手动指定,signer.sendTransaction会自动使用签名者的地址作为交易发起方。

修复后的完整代码

const {abi: V3SwapRouterABI} = require('@uniswap/v3-periphery/artifacts/contracts/interfaces/ISwapRouter.sol/ISwapRouter.json')
const {abi: ERC20ABI} = require('@openzeppelin/contracts/build/contracts/ERC20.json')
const { ethers } = require("ethers")
require("dotenv").config()

const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET
const PRIVATE_KEY = process.env.PRIVATE_KEY
const WALLET_ADDRESS = process.env.WALLET_ADDRESS

const wethToken= "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"
const Uni= "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
const UniswapRouter="0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"

const provider = new ethers.providers.JsonRpcProvider(INFURA_URL_TESTNET)
const wallet = new ethers.Wallet(PRIVATE_KEY)
const signer = wallet.connect(provider)

// 初始化WETH合约实例用于授权
const wethContract = new ethers.Contract(wethToken, ERC20ABI, signer)
const UniV3Contract = new ethers.Contract(UniswapRouter, V3SwapRouterABI, signer)

const FEE_SIZE = 3

function encodePath(path, fees) {
    if (path.length != fees.length + 1) {
        throw new Error('path/fee lengths do not match')
    }

    let encoded = '0x'
    for (let i = 0; i < fees.length; i++) {
        encoded += path[i].slice(2)
        encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0')
    }
    encoded += path[path.length - 1].slice(2)

    return encoded
}

async function getToken() {
    const amountIn = ethers.utils.parseEther('0.01')
    
    // 前置步骤:授权Router合约转移指定数量的WETH
    const approveTx = await wethContract.approve(UniswapRouter, amountIn)
    await approveTx.wait()
    console.log('授权完成,交易哈希:', approveTx.hash)

    const path = encodePath([wethToken, Uni], [3000])
    const deadline = Math.floor(Date.now()/1000) + (60*10)  

    const params = {
        path: path,
        recipient: WALLET_ADDRESS,
        deadline: deadline,
        amountIn: amountIn,
        amountOutMinimum: 0
    }

    // 直接通过合约实例调用exactInput,无需手动编码函数数据
    const tx = await UniV3Contract.exactInput(params, {
        gasLimit: ethers.utils.hexlify(1000000)
    })
    console.log('兑换交易哈希:', tx.hash)
    const receipt = await tx.wait()
    console.log('交易完成,回执:', receipt)
}

module.exports = { getToken }

关键修复说明

  • 添加ERC20授权:调用WETH合约的approve方法,允许Router合约转移你指定数量的WETH,这是所有ERC20代币兑换的必要前置操作
  • 简化交易调用:直接使用合约实例的exactInput方法发起交易,避免手动编码函数数据的出错风险
  • 修复异步逻辑:给tx.wait()添加await,确保获取完整的交易回执
  • 移除冗余参数:删除不必要的from字段,由签名者自动处理交易发起方

额外建议

  • 不要设置amountOutMinimum: 0,这会让你完全暴露在滑点风险中,建议通过Uniswap Quoter合约查询当前行情下的合理最小输出量后再设置
  • 可根据实际情况调整gasLimit,避免设置过大造成Gas浪费或过小导致交易失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:55:14