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

Web3.py调用swapTokensForExactTokens报参数类型不匹配错误

web3.py调用swapTokensForExactTokens参数类型不匹配问题修复

报错核心提示:无法匹配swapTokensForExactTokens函数参数类型,传入参数类型为(<class 'int'>, <class 'int'>, <class 'list'>, <class 'str'>, <class 'int'>),目标函数签名为swapTokensForExactTokens(uint256,uint256,address[],address,uint256)。

这个问题是web3.py合约调用的常见问题,按以下顺序排查修复即可:

  • 首先核对合约ABI准确性
    单独提取Router合约ABI中swapTokensForExactTokens的定义,确认参数类型完全匹配:
    1. 第1位参数:uint256(amountOut)
    2. 第2位参数:uint256(amountInMax)
    3. 第3位参数:address[](注意是动态数组,不能写成固定长度的address[2],对应path路径)
    4. 第4位参数:address(对应收款地址to)
    5. 第5位参数:uint256(对应deadline过期时间)
      网上流传的公开ABI经常出现参数类型写错的问题,比如把address标成string、把动态数组标成固定长度数组,直接导致类型匹配逻辑错位。
  • 显式做全参数类型转换,跳过自动推断
    web3.py的自动类型推断经常失效,不要依赖自动转换,所有参数手动显式转成对应类型:
    所有地址类值(path内的两个代币地址、to收款地址、交易发起from地址)必须用当前连接节点的w3实例的toChecksumAddress()方法转换,不要传全小写/全大写地址,也不要用其他工具生成的校验和地址;所有数值类值(两个金额、deadline)显式套int()转换,禁止传浮点数、字符串格式数字。
    参考写法:
    import time
    
    amount_out = int(1)
    amount_in_max = int(1)
    path = [
        w3.toChecksumAddress("0x15F517ccAa1420A0bf882052A41A81a152D1A285"),
        w3.toChecksumAddress("0x72C262985366cf25Cc81629d01393CE3213C4F79")
    ]
    to_addr = w3.toChecksumAddress(acct.address)
    deadline = int(time.time()) + 100000
    
  • 补全交易构造参数
    原代码的buildTransaction缺失必填的chainId参数,虽然不会直接触发当前的类型报错,但会导致后续签名失败,chainId直接通过接口获取即可,不需要硬编码:
    tx_params = {
        'from': w3.toChecksumAddress(acct.address),
        "nonce": nonce,
        "gas": 200000,
        'gasPrice': gasprice,
        'chainId': w3.eth.chain_id
    }
    
  • 排查web3.py版本兼容性问题
    beta版web3.py、6.0以上新版本的类型检测逻辑存在已知bug,和大部分EVM兼容链节点兼容性最好的稳定版本是5.31.4,执行以下命令安装固定版本:
    pip install web3==5.31.4
    
  • 绕过自动重载匹配逻辑
    如果以上操作后仍报错,可以直接指定函数签名发起调用,跳过web3的自动重载类型匹配,从根源避免类型检测错误:
    # 直接通过签名获取目标函数,跳过自动匹配
    swap_func = Router.get_function_by_signature('swapTokensForExactTokens(uint256,uint256,address[],address,uint256)')
    # 传入参数构造调用
    contract_call = swap_func(amount_out, amount_in_max, path, to_addr, deadline)
    # 构造交易
    tx = contract_call.buildTransaction(tx_params)
    

完整修正后的调用代码参考:

ChecksumA = w3.toChecksumAddress("0x15F517ccAa1420A0bf882052A41A81a152D1A285")
ChecksumB = w3.toChecksumAddress("0x72C262985366cf25Cc81629d01393CE3213C4F79")
amount_out = int(1)
amount_in_max = int(1)
to_addr = w3.toChecksumAddress(acct.address)
deadline = int(time.time()) + 100000

tx = w3.eth.account.sign_transaction(
    Router.functions.swapTokensForExactTokens(
        amount_out,
        amount_in_max,
        [ChecksumA, ChecksumB],
        to_addr,
        deadline
    ).buildTransaction(
        {
            'from': w3.toChecksumAddress(acct.address),
            "nonce": nonce,
            "gas": 200000,
            'gasPrice': gasprice,
            'chainId': w3.eth.chain_id
        }
    ),
    priv
)
txsigned = w3.eth.send_raw_transaction(tx.rawTransaction)
tx_receipt = w3.eth.waitForTransactionReceipt(txsigned)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:54:28