This article mainly analyzes the process of automated transactions through code calls to the UnisWAp/Pancakeswap interface

This paper is mainly based on PancakesWAp, other exchanges unisWAp/Mdex are basically similar

This paper mainly realizes three functions

  • Exchange BNB for other tokens
  • Replace other tokens with BNB
  • To exchange one TOKEN for another

1. Development environment

  • The development language is Javascript/Typescript
  • Interact with the chain through ethers. Js

2. Build provider and wallet objects

const provider = ethers.getDefaultProvider(
  "https://bsc-dataseed1.binance.org:443"
);
const wallet = new ethers.Wallet(config.privateKey, provider);
Copy the code

Here we first build a Provider object based on the official node of the BSC, and then build a wallet object using the private key

3. Build the Pancakeswap Router contract object

const router = new ethers.Contract(
  "0x10ED43C718714eb63d5aA57B78B54704E256024E"["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 swapExactTokensForETHSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)"."function swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline) external returns (uint[] memory amounts)"."function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline) external returns (uint[] memory amounts)",
  ],
  wallet
);
Copy the code

The above address is the Pancakeswap Router2 address, and all transactions are executed through this contract.

The following four functions are defined, which do the following

  • GetAmountsOut estimates AmountOut based on AmountIn at the time of token conversion
  • SwapExactETHForTokens swap BNB for designated tokens. Note that there is a “payable” modifier to indicate that BNB is payable for this interface
  • SwapExactTokensForETHSupportingFeeOnTransferTokens will specify tokens with BNB
  • SwapExactTokensForTokens/swapExactTokensForTokensSupportingFeeOnTransferTokens these two methods is to replace some token ERC20 agreement with another ERC20 agreement token

4. Change BNB into other tokens

async function bnb2Token(bnbValue, tokenAddress) {
  const amountIn = bnbValue;
  // Estimate how many tokens can be obtained
  const amounts = await router.getAmountsOut(amountIn, [
    pancakeAddress.WBNB,
    tokenAddress,
  ]);
  / / points
  const amountOutMin = amounts[1].sub(amounts[1].div(config.slide));
  // Initiate the transaction
  const path = [pancakeAddress.WBNB, tokenAddress];
  const gasPrice = await provider.getGasPrice();
  const tx = await router.swapExactETHForTokens(
    amountOutMin,
    path,
    wallet.address,
    Date.now() + 10 * 60 _000,
    {
      gasPrice,
      gasLimit: config.gasLimit,
      value: amountIn,
    }
  );
  console.log('Transaction initiated, https://bscscan.com/tx/${tx.hash}`);
  try {
    await tx.wait();
    console.log("Deal done.");
  } catch (err) {
    console.log("Deal failed.");
    throwerr; }}Copy the code

Note that there is a path variable, which represents the transaction path specified by us. Swap constructs an ERC20 token called WrappedBNB, which is WBNB in the code, for the convenience of contract processing. Convert to WBNB and use the transaction path of WBNB -> TOKEN to complete the transaction

5. Replace other tokens with BNB

// First we need to have a constructor to build the ERC20 contract
function erc20Contract(tokenAddress) {
  return new ethers.Contract(
    tokenAddress,
    [
      "function symbol() public view returns (string)"."function decimals() public view returns (uint)"."function balanceOf(address user) public view returns (uint)"."function allowance(address a, address b) public view returns (uint)"."function approve(address a, uint amount) public",
    ],
    wallet
  );
}

// There needs to be an authorization function that authorizes tokens to pancakeswap processing
async function approve(tokenContract) {
  const amount = await tokenContract.allowance(
    wallet.address,
    pancakeAddress.router
  );
  // Already authorized
  if (amount.gt(0)) {
    return;
  }
  const gasPrice = await provider.getGasPrice();
  // Re-invoke authorization
  const tx = await tokenContract.approve(
    pancakeAddress.router,
    ethers.constants.MaxUint256,
    {
      gasPrice,
      gasLimit: config.gasLimit,
    }
  );
  console.log("Token grant initiated", tx.hash);
  await tx.wait();
  console.log("Authorization successful");
}

// Replace TOKEN with BNB's main function
// amount sells all if not specified
async function token2Bnb(tokenAddress, amount) {
  // Obtain the ERC20 contract with token
  const tokenContract = erc20Contract(tokenAddress);

  // Authorize pancakeswap first
  await approve(tokenContract);

  // Check the remaining number
  let amountIn = await tokenContract.balanceOf(wallet.address);
  if (Number(amountIn) === 0) {
    console.log("The quantity is zero. We can't sell it.");
    return;
  }
  // Specify the quantity
  if (amount) {
    amount = ethers.BigNumber.from(amount);
    // Specify the quantity to sell
    if (amountIn.lt(amount)) {
      console.log("Insufficient balance");
      return;
    }
    amountIn = amount;
  }
  / / sell
  const gasPrice = await provider.getGasPrice();
  const tx = await router.swapExactTokensForETHSupportingFeeOnTransferTokens(
    amountIn,
    0,
    [tokenAddress, pancakeAddress.WBNB],
    wallet.address,
    Date.now() + 10 * 60 _000,
    {
      gasPrice,
      gasLimit: config.gasLimit,
    }
  );
  console.log('Transaction initiated, https://bscscan.com/tx/${tx.hash}`);
  try {
    await tx.wait();
    console.log("Deal done.");
  } catch (err) {
    console.log("Deal failed.");
    throwerr; }}Copy the code

6. Exchange one TOKEN for another

// Token for token, the third parameter indicates the number, if all indicates all
async function token2Token(token1, token2, amount) {
  // Obtain the ERC20 contract with token
  const token1Contract = erc20Contract(token1);

  // Authorize pancakeswap first
  await approve(token1Contract);

  // Calculate the quantity sold
  let amountIn;
  if (amount === "all") {
    amountIn = await token1Contract.balanceOf(wallet.address);
  } else {
    amountIn = amount;
  }

  // The transaction path is BNB
  const path = [token1, pancakeAddress.WBNB, token2];
  // Initiate the transaction
  const args = [amountIn, 0, path, wallet.address, Date.now() + 10 * 60 _000];
  // Check whether the transaction is successful
  try {
    awaitrouter.callStatic.swapExactTokensForTokensSupportingFeeOnTransferTokens( ... args ); }catch (e) {
    console.log("An error occurred in the test initiating trade.");
    throw e;
  }

  const gasPrice = await provider.getGasPrice();
  const tx = awaitrouter.swapExactTokensForTokensSupportingFeeOnTransferTokens( ... args, { gasPrice,gasLimit: config.gasLimit,
    }
  );
  console.log('Transaction initiated, https://bscscan.com/tx/${tx.hash}`);
  try {
    await tx.wait();
    console.log("Deal done.");
  } catch (err) {
    console.log("Deal failed.");
    throwerr; }}Copy the code

7. Achieve results

We wrap up the above program with a simple command line

In the next article we will combine the Telegram robot to achieve an interactive command trading robot

Previous articles

The transaction data of Babydoge in pancakeswap is monitored through the program

Contact the author

WeChat: czz5242199

telegram: @zhuozhongcao