Web3/nodejs 不能在 Pancakeswapv2

问题描述

我在 BSC 上为 BNB 销售代币 BUNNY 时遇到了真正的问题。 这是我所知道的工作

  1. 检查配额表明我已批准在 PCSv2 路由器上交易 BUNNY
  2. 增加津贴也有效
  3. 花费 BNB 购买 BUNNY 也有效(swapExactETHforTokens)
  4. 在 BSC 扫描上手动写入合同也有效

不起作用的是 swapExactTokensForETH - 它消耗了一些gas但抛出了: “TRANSFER FROM Failed”...原因:“交易失败”,代码:“CALL_EXCEPTION” 这是来自 node.js 脚本的失败事务 https://bscscan.com/tx/0x55d45e5f1e937fcd55294fa3e4d8c4c24d9c578b7ba8361fb12b2a017d7e7a4b

现在我所做的所有研究都表明这是因为我需要批准支出者 - 我已经这样做了......我怎么知道?好吧,我写的函数说它很好,就像直接查询 BUNNY 一样 另一件奇怪的事情是这很完美(没有额外的批准) - 看截图

BSCScan Write Contract that works

这是路由器合约的 BSCscan 写入部分的成功交易 https://bscscan.com/tx/0xc8d2b999c08cef6ecceecf4bc5d6242bcd43571164016a8372bbf0c02d1a6185

如果有人能弄清楚为什么会抛出这个错误,这将是一个巨大的帮助 tyvm 代码如下:

const ethers = require('ethers');
const Web3 = require('web3');
const abi = require('human-standard-token-abi');
const {ChainId,Token,TokenAmount,Fetcher: v2Fetcher,Pair,Route,Trade,TradeType,Percent} = require('@pancakeswap-libs/sdk-v2');

const {JsonRpcProvider} = require("@ethersproject/providers");
const url = 'https://bsc-dataseed1.binance.org/';
const provider = new JsonRpcProvider('https://bsc-dataseed1.binance.org/');
const web3 = new Web3(url);

const secretKey = process.env.SECRETKEY;
const walletAddress = process.env.WALLETADDRESS;
const wallet = ethers.Wallet.fromMnemonic(secretKey);
const account = wallet.connect(provider);

const pcsRouterV2 = Web3.utils.tochecksumAddress('0x10ED43C718714eb63d5aA57B78B54704E256024E'); //v2 router
const routerV2 = new ethers.Contract (pcsRouterV2,[
    'function getAmountsOut(uint amountIn,address[] memory path) public view returns (uint[] memory amounts)','function swapExactETHForTokens(uint amountOutMin,address[] calldata path,address to,uint deadline) external payable returns (uint[] memory amounts)','function swapExactTokensForETH(uint amountIn,uint amountOutMin,uint deadline) external returns (uint[] memory amounts)','function swapExactTokensForTokens(uint amountIn,uint deadline) external returns (uint[] memory amounts)'
    ],account );

const bunnyAddress = Web3.utils.tochecksumAddress('0xc9849e6fdb743d08faee3e34dd2d1bc69ea11a51');
const wbnbAddress = Web3.utils.tochecksumAddress('0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'); // WBNB

const gasApprovalLimit = 100000;
const gasTradingLimit = 250000;
const gasPrice = 5;

const getAllowance = async (tickerTokenAddress,thisWalletAddress,liquidtyPoolRouter) => {
    var contract = new web3.eth.Contract(abi,tickerTokenAddress);
    let approvalLimit = await contract.methods.allowance(thisWalletAddress,liquidtyPoolRouter).call();
    let decimals = await contract.methods.decimals().call();
    // this comes back with 3 variables,an approval,an approval in token units and the decimals
    return [approvalLimit,approvalLimit / (10 ** decimals),decimals];
}

const getApproval = async (thisTokenAddress,approvalAmount,thisDecimals,walletAccount,liquidtyPoolRouter,thisGasPrice = gasPrice,thisGasLimit = gasApprovalLimit)  => {
    console.log(`getting approval`);
    let contract = new ethers.Contract(thisTokenAddress,abi,walletAccount);
    let approveResponse = await contract.approve(
        liquidtyPoolRouter,ethers.utils.parseUnits(approvalAmount.toString(),thisDecimals),{
            gasLimit: thisGasLimit,gasPrice: ethers.utils.parseUnits(thisGasPrice.toString(),'gwei')
        });
    console.log(approveResponse);
}

const swapExactBNBForTokens = async (buyAddress,buyDecimals,tokensIn,TradeSlippage,thisGasLimit = gasTradingLimit) => {
    let amountIn = ethers.utils.parseUnits(tokensIn.toString(),buyDecimals);
    let amounts = await routerV2.getAmountsOut(amountIn,[wbnbAddress,buyAddress]);
    let amountOutMin = amounts[1].sub(amounts[1].mul(TradeSlippage).div(100));
    let tx = await routerV2.swapExactETHForTokens(
        amountOutMin,buyAddress],walletAddress,Date.Now() + 1000 * 60 * 10,{
            value: amountIn,gasLimit: thisGasLimit,'gwei')
        }
    )
    console.log(`Transaction Submitted...`);
    let receipt = await tx.wait();
    console.log(receipt);
}

const swapExactTokensForBNB = async (sellAddress,sellDecimals,sellDecimals);
    let amounts = await routerV2.getAmountsOut(amountIn,[sellAddress,wbnbAddress]);
    let amountOutMin = amounts[1].sub(amounts[1].mul(TradeSlippage).div(100));

    let tx = await routerV2.swapExactTokensForETH(
        amountIn,amountOutMin,wbnbAddress],'gwei')
        }
    )
    console.log(`Transaction Submitted...`);
    let receipt = await tx.wait();
    console.log(receipt);
}

// USAGE
// swapExactBNBForTokens(bunnyAddress,18,0.3,2); // spending 0.3 BNB to buy BUNNY
// swapExactTokensForBNB(bunnyAddress,3,2); // spending 3 BUNNY to buy BNB
getAllowance(bunnyAddress,pcsRouterV2).then((value) => {console.log('V2 ' + value);});

解决方法

这是您在失败交易中提供的amountIn:3299718614161746000

这是您在成功交易中提供的amountIn:3299718614161745787,而且更少。

所以我假设您提供的金额不正确,金额大于您的余额。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...