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

Web3代币兑换触发TRANSFER_FROM_FAILED错误求助

问题

实现了两个Web3函数:一个将WBNB兑换为指定代币(buy函数),另一个将该代币换回WBNB(sell函数)。两者逻辑基本一致,仅兑换方向与amountIn的处理不同——buy函数对amountIn做了BNB单位转换,sell函数未做。执行sell函数时触发以下错误:

raise ContractLogicError(response['error']['message'])
web3.exceptions.ContractLogicError: execution reverted: TransferHelper: TRANSFER_FROM_FAILED

sell函数代码:

token = "0x2859e4544C4bB03966803b044A93563Bd2D0DD4D"

def sell(token, amountToSell):
    tokenToBuy = web3.toChecksumAddress("0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c")  # wbnb contract address
    spend = web3.toChecksumAddress(token)
    nonce = web3.eth.get_transaction_count(sender_address)
    pancakeswap2_txn = contractbuy.functions.swapExactTokensForTokens(
        amountToSell,
        #web3.toWei(amountToBuy, 'ether'),
        0,
        [spend, tokenToBuy],
        sender_address,
        (int(time.time()) + 10000)
    ).buildTransaction({
        'from': sender_address,
        #'value': amountToSell,
        #'value': web3.toWei(amountToSell, 'ether'),  # This is the Token(BNB) amount you want to Swap from
        'gasPrice': web3.toWei('5', 'gwei'),
        'nonce': nonce,
    })
    signed_txn = web3.eth.account.sign_transaction(pancakeswap2_txn,
                                                   private_key=privatekey)
    tx_token = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
    transaction_tx = web3.toHex(tx_token)
    print("Sell was succesfull, sold: " + transaction_tx)

    return transaction_tx

buy函数代码:

def buy(token, amountToBuy):
    spend = web3.toChecksumAddress("0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c")  # wbnb contract address
    tokenToBuy = web3.toChecksumAddress(token)
    nonce = web3.eth.get_transaction_count(sender_address)
    pancakeswap2_txn = contractbuy.functions.swapExactTokensForTokens(
        web3.toWei(amountToBuy, 'ether'),
        0,  # set to 0, or specify minimum amount of token you want to receive - consider decimals!!!
        [spend, tokenToBuy],
        sender_address,
        (int(time.time()) + 10000)
    ).buildTransaction({
        'from': sender_address,
        #'value': 1000,
        #'value': web3.toWei(amountToBuy, 'ether'),  # This is the Token(BNB) amount you want to Swap from
        'gasPrice': web3.toWei('5', 'gwei'),
        'nonce': nonce,
    })
    signed_txn = web3.eth.account.sign_transaction(pancakeswap2_txn,
                                                   private_key=privatekey)
    tx_token = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
    transaction_tx = web3.toHex(tx_token)
    print("succesfull, bought: " + transaction_tx)

    return transaction_tx

钱包中持有该代币与WBNB,但sell函数执行失败,buy函数可正常运行,不清楚问题所在。

解决方案

出现TransferHelper: TRANSFER_FROM_FAILED错误的核心原因是PancakeSwap合约没有权限从你的钱包划转要卖出的代币,加上你未处理代币小数位数导致参数错误,具体修复步骤如下:

  • 给PancakeSwap合约授权代币划转权限
    在执行sell交易前,必须调用目标代币的approve函数,允许PancakeSwap Router合约划转指定数量的代币。示例代码:

    # 标准ERC20代币ABI片段,可直接使用
    token_abi = [{"constant":true,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
    
    def approve_token(token_address, spender_address, amount):
        token_contract = web3.eth.contract(address=web3.toChecksumAddress(token_address), abi=token_abi)
        nonce = web3.eth.get_transaction_count(sender_address)
        approve_txn = token_contract.functions.approve(
            spender_address,
            amount
        ).buildTransaction({
            'from': sender_address,
            'gasPrice': web3.toWei('5', 'gwei'),
            'nonce': nonce,
        })
        signed_txn = web3.eth.account.sign_transaction(approve_txn, private_key=privatekey)
        tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
        web3.eth.wait_for_transaction_receipt(tx_hash)
        print("授权成功")
    
    # 在sell函数调用前执行授权,spender_address填你的contractbuy(PancakeSwap Router)地址
    approve_token(token, contractbuy.address, amount_to_sell_wei)
    
  • 处理代币的小数位数
    不同代币的小数位数可能不是18位(和WBNB不同),不能直接用web3.toWei转换,需根据代币实际小数位数计算最小单位数量:

    def get_token_decimals(token_address):
        token_contract = web3.eth.contract(address=web3.toChecksumAddress(token_address), abi=token_abi)
        return token_contract.functions.decimals().call()
    
    # 获取目标代币小数位数
    decimals = get_token_decimals(token)
    # 转换为最小单位数量
    amount_to_sell_wei = int(amountToSell * (10 ** decimals))
    

    之后在swapExactTokensForTokens中传入amount_to_sell_wei作为第一个参数。

  • 确认参数正确性

    1. 检查amount_to_sell_wei不能超过钱包中该代币的实际余额(转换为最小单位后)
    2. 确认路由数组[spend, tokenToBuy]顺序正确(要卖出的代币在前,WBNB在后)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:36:33