我正在尝试使用web3在Pancakeswap上执行交换,但在计算交易成本时出现错误
我是以太坊开发的新手,我正在编写一个简单的脚本来使用 Pancakeswap 执行交换。在我建立交易并计算交易成本之前,一切似乎都运行良好。我正在使用 UniswapRouterV02 abi 创建我的 Pancakeswap 合约。编码:
const init = async () => {
const [WBNB, BUSD] = await Promise.all(
[addresses.WBNB, addresses.BUSD].map(tokenAddress => (
new Token(
ChainId.MAINNET,
tokenAddress,
18
)
)));
const pair = await Fetcher.fetchPairData(WBNB, BUSD, provider)
const route = await new Route([pair], WBNB)
const trade = await new Trade(route, new TokenAmount(WBNB, tradeAmount), TradeType.EXACT_INPUT)
const executionPrice = trade.executionPrice.toSignificant(12)
// Correct prices; everything seems correct up until here
const slippageTolerance = new Percent('50', '10000')
const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw
const path = [WBNB.address, BUSD.address]
const to = MY_ADDRESS
const deadline = Math.floor(Date.now() / 1000) + 60 * 20
const value = trade.inputAmount.raw
// Correct prices everything seems correct up until here
const pancakeSwap = new web3.eth.Contract(
abis.uniswapRouter.abi,
addresses.PANCAKE_ROUTER //'0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F'
);
let tx = pancakeSwap.methods.swapExactTokensForTokens(
tradeAmount,
web3.utils.toBN(amountOutMin.toString()),
path,
to,
deadline
)
const [gasPrice, gasCost] = await Promise.all([
web3.eth.getGasPrice(),
tx.estimateGas({from: admin}),
]);
console.log(`gasPrice: ${gasPrice}`)
console.log(`gasCost: ${gasCost}`)
}
init()
回答
事实证明,使用 web3 不可能与 Pancakeswap 合约进行交互。我找到了一个使用 ethers.js 的解决方案。以下代码对我有用,可以在主网上的 Pancake 上执行交换。在执行第一个事务之前需要允许Pancakeswap,这段代码被注释掉了。我不得不稍微调整一下 gasprice 和 gasLimit 才能让它发挥作用。
require("dotenv").config()
const ethers = require('ethers')
const {ChainId, Token, TokenAmount, Fetcher, Pair, Route, Trade, TradeType, Percent} =
require('@pancakeswap-libs/sdk');
const Web3 = require('web3');
const web3 = new Web3('wss://apis.ankr.com/wss/c40792ffe3514537be9fb4109b32d257/946dd909d324e5a6caa2b72ba75c5799/binance/full/main');
const {JsonRpcProvider} = require("@ethersproject/providers");
const provider = new JsonRpcProvider('https://bsc-dataseed1.binance.org/');
const { address: admin } = web3.eth.accounts.wallet.add(process.env.PRIVATE_KEY)
const addresses = {
WBNB: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
BUSD: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
PANCAKE_ROUTER: '0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F'
}
const ONE_ETH_IN_WEI = web3.utils.toBN(web3.utils.toWei('1'))
const tradeAmount = ONE_ETH_IN_WEI.div(web3.utils.toBN('1000'))
const init = async () => {
const [WBNB, BUSD] = await Promise.all(
[addresses.WBNB, addresses.BUSD].map(tokenAddress => (
new Token(
ChainId.MAINNET,
tokenAddress,
18
)
)));
const pair = await Fetcher.fetchPairData(WBNB, BUSD, provider)
const route = await new Route([pair], WBNB)
const trade = await new Trade(route, new TokenAmount(WBNB, tradeAmount), TradeType.EXACT_INPUT)
const slippageTolerance = new Percent('50', '10000')
// create transaction parameters
const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw
const path = [WBNB.address, BUSD.address]
const to = admin
const deadline = Math.floor(Date.now() / 1000) + 60 * 20
// Create signer
const wallet = new ethers.Wallet(
Buffer.from(
process.env.PRIVATE_KEY, // paste your private key from metamask here
"hex"
)
)
const signer = wallet.connect(provider)
// Create Pancakeswap ethers Contract
const pancakeswap = new ethers.Contract(
addresses.PANCAKE_ROUTER,
['function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'],
signer
)
// Allow Pancakeswap
// let abi = ["function approve(address _spender, uint256 _value) public returns (bool success)"]
// let contract = new ethers.Contract(WBNB.address, abi, signer)
// await contract.approve(addresses.PANCAKE_ROUTER, ethers.utils.parseUnits('1000.0', 18), {gasLimit: 100000, gasPrice: 5e9})
// Execute transaction
const tx = await pancakeswap.swapExactTokensForTokens(
ethers.utils.parseUnits('0.001', 18),
ethers.utils.parseUnits(web3.utils.fromWei(amountOutMin.toString()), 18),
path,
to,
deadline,
{ gasLimit: ethers.utils.hexlify(200000), gasPrice: ethers.utils.parseUnits("10", "gwei") }
)
console.log(`Tx-hash: ${tx.hash}`)
const receipt = await tx.wait();
console.log(`Tx was mined in block: ${receipt.blockNumber}`)
}
init()
- The code works with the pancake router v1, but with the new router v2 (0x10ed43c718714eb63d5aa57b78b54704e256024e) it doesn't work. All transactions fail. What would have to be modified to work with v2?
THE END
二维码