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

Web3开发PancakeSwap测试网交易机器人遇LengthMismatch错误求助

问题排查与解决:PancakeSwap Universal Router交易触发LengthMismatch错误

错误原因

你调用PancakeSwap Universal Router的execute函数时,参数格式完全不符合合约要求,这是触发LengthMismatch错误的核心原因。

从合约ABI可以看到,execute函数的正确签名是:

function execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline) external payable;

而你的代码错误地传入了sender地址、代币路径数组作为前两个参数,参数的数量、类型和合约要求完全不匹配,导致合约校验时抛出长度不匹配的错误。

解决方案

需要按照Universal Router的规范构造commands(命令字节串,指定要执行的操作类型)和inputs(对应每个命令的参数数组),然后正确调用execute函数。以下是针对你需求(用BNB兑换指定代币)的修正代码:

修正后的完整代码片段

from web3 import Web3
import json
import config
import time

bsc = 'https://data-seed-prebsc-1-s1.binance.org:8545'
web3 = Web3(Web3.HTTPProvider(bsc))

print(web3.is_connected())

# PancakeSwap Universal Router 测试网地址
UniversalRouter = '0xd77C2afeBf3dC665af07588BF798bd938968c72E'

# 合约ABI(保持你原有的ABI即可)
panabi = '[{"inputs":[{"components":[{"internalType":"address","name":"permit2","type":"address"},{"internalType":"address","name":"weth9","type":"address"},{"internalType":"address","name":"seaportV1_5","type":"address"},{"internalType":"address","name":"seaportV1_4","type":"address"},{"internalType":"address","name":"openseaConduit","type":"address"},{"internalType":"address","name":"x2y2","type":"address"},{"internalType":"address","name":"looksRareV2","type":"address"},{"internalType":"address","name":"routerRewardsDistributor","type":"address"},{"internalType":"address","name":"looksRareRewardsDistributor","type":"address"},{"internalType":"address","name":"looksRareToken","type":"address"},{"internalType":"address","name":"v2Factory","type":"address"},{"internalType":"address","name":"v3Factory","type":"address"},{"internalType":"address","name":"v3Deployer","type":"address"},{"internalType":"bytes32","name":"v2InitCodeHash","type":"bytes32"},{"internalType":"bytes32","name":"v3InitCodeHash","type":"bytes32"},{"internalType":"address","name":"stableFactory","type":"address"},{"internalType":"address","name":"stableInfo","type":"address"},{"internalType":"address","name":"pancakeNFTMarket","type":"address"}],"internalType":"struct RouterParameters","name":"params","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BalanceTooLow","type":"error"},{"inputs":[],"name":"BuyPancakeNFTFailed","type":"error"},{"inputs":[],"name":"BuyPunkFailed","type":"error"},{"inputs":[],"name":"ContractLocked","type":"error"},{"inputs":[],"name":"ETHNotAccepted","type":"error"},{"inputs":[{"internalType":"uint256","name":"commandIndex","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"ExecutionFailed","type":"error"},{"inputs":[],"name":"FromAddressIsNotOwner","type":"error"},{"inputs":[],"name":"InsufficientETH","type":"error"},{"inputs":[],"name":"InsufficientToken","type":"error"},{"inputs":[],"name":"InvalidBips","type":"error"},{"inputs":[{"internalType":"uint256","name":"commandType","type":"uint256"}],"name":"InvalidCommandType","type":"error"},{"inputs":[],"name":"InvalidOwnerERC1155","type":"error"},{"inputs":[],"name":"InvalidOwnerERC721","type":"error"},{"inputs":[],"name":"InvalidPath","type":"error"},{"inputs":[],"name":"InvalidPoolAddress","type":"error"},{"inputs":[],"name":"InvalidPoolLength","type":"error"},{"inputs":[],"name":"InvalidReserves","type":"error"},{"inputs":[],"name":"InvalidSpender","type":"error"},{"inputs":[],"name":"LengthMismatch","type":"error"},{"inputs":[],"name":"SliceOutOfBounds","type":"error"},{"inputs":[],"name":"StableInvalidPath","type":"error"},{"inputs":[],"name":"StableTooLittleReceived","type":"error"},{"inputs":[],"name":"StableTooMuchRequested","type":"error"},{"inputs":[],"name":"TransactionDeadlinePassed","type":"error"},{"inputs":[],"name":"UnableToClaim","type":"error"},{"inputs":[],"name":"UnsafeCast","type":"error"},{"inputs":[],"name":"V2InvalidPath","type":"error"},{"inputs":[],"name":"V2TooLittleReceived","type":"error"},{"inputs":[],"name":"V2TooMuchRequested","type":"error"},{"inputs":[],"name":"V3InvalidAmountOut","type":"error"},{"inputs":[],"name":"V3InvalidCaller","type":"error"},{"inputs":[],"name":"V3InvalidSwap","type":"error"},{"inputs":[],"name":"V3TooLittleReceived","type":"error"},{"inputs":[],"name":"V3TooMuchRequested","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"indexed":true,"internalType":"address","name":"info","type":"address"}],"name":"SetStableSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"bytes","name":"looksRareClaim","type":"bytes"}],"name":"collectRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"bytes[]","name":"inputs","type":"bytes[]"}],"name":"execute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"commands","type":"bytes"},{"internalType":"bytes[]","name":"inputs","type":"bytes[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"execute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pancakeV3SwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_info","type":"address"}],"name":"setStableSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableSwapFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stableSwapInfo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]'

sender = '0x4182692466cF31f1EdbF6E06A7181CF0450F0fe6'
balance = web3.eth.get_balance(sender)
humanReadable = web3.from_wei(balance,'ether')

# 输入要购买的代币地址
tokenToBuy = web3.to_checksum_address(input("Enter TokenAddress: "))
# 测试网WBNB地址
weth9 = web3.to_checksum_address('0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd')

# 初始化合约
contract = web3.eth.contract(address=UniversalRouter, abi=panabi)
nonce = web3.eth.get_transaction_count(sender)
deadline = int(time.time()) + 10000

# -------------------------- 核心修正部分 --------------------------
# 1. 构造命令:0x00 代表 V2_SWAP_EXACT_IN(精确输入兑换)
commands = b'\x00'

# 2. 构造V2_SWAP_EXACT_IN的参数
# 参数说明:recipient, amountIn, amountOutMinimum, path, payer
# - recipient: 接收代币的地址
# - amountIn: 要兑换的BNB数量(已转成wei)
# - amountOutMinimum: 最小接收代币数量(这里设为0,实际建议根据滑点计算)
# - path: 兑换路径 [WBNB, 目标代币]
# - payer: 支付BNB的地址(即sender)
amount_in = web3.to_wei(0.003555283, 'ether')
amount_out_min = 0  # 实际使用时建议设置合理的滑点阈值
path = [weth9, tokenToBuy]

# 编码参数为bytes
swap_input = web3.codec.encode_abi(
    ['address', 'uint256', 'uint256', 'address[]', 'address'],
    [sender, amount_in, amount_out_min, path, sender]
)

# 3. inputs数组:每个命令对应一个参数bytes
inputs = [swap_input]

# 4. 正确调用execute函数
pancakeswap2_txn = contract.functions.execute(commands, inputs, deadline).build_transaction({
    'from': sender,
    'value': amount_in,  # 因为是用BNB支付,直接传入对应的wei数量
    'gas': 300000,  # 适当提高gas上限,避免gas不足
    'gasPrice': web3.to_wei('5', 'gwei'),
    'nonce': nonce,
})
# -----------------------------------------------------------------

# 签名并发送交易
signed_txn = web3.eth.account.sign_transaction(pancakeswap2_txn, private_key=config.private)
tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(f"交易哈希: {web3.to_hex(tx_hash)}")

关键说明

  1. 命令字节(commands):0x00对应Universal Router的V2_SWAP_EXACT_IN操作,如果你需要其他操作(比如V2_SWAP_EXACT_OUT),需要替换对应的命令码。
  2. 参数编码:使用web3.codec.encode_abi将兑换参数编码成合约要求的bytes格式,确保参数类型和顺序完全匹配。
  3. 滑点设置:示例中amount_out_min设为0,实际生产环境中建议根据滑点计算合理的最小值(比如允许1%滑点,则计算当前价格的99%作为最小接收量),避免因价格波动导致交易失败。
  4. Gas上限:适当提高gas上限到300000,确保交易有足够的gas完成兑换操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:57:33