Web3.js – How to Send uint256 and Address Types to Smart Contract in JavaScript

contract-developmentethers.jsjavascriptuint256web3js

Im trying to send a query to Pancakeswap's router function getAmoutsOut
here the code for importing the contract using ethers ABI:

const router = new ethers.Contract('0x10ED43C718714eb63d5aA57B78B54704E256024E', [
'function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts)',
'function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts)'
], account);

As you can already tell the parameters are in uint256 and an array of Address type objects.
how Ami supposed to send valid parameter type to the contract. I've tried a couple of built in ethers utilities functions but so far no luck. I'm 90% sure the error comes from the BNB amount.

Also side note yes ethers works fine with BSC provided you use a BSC node. much like web3.
Anyway here's the code for contract deployment.

desiredCoin = 'coin contract address example';
bnb = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
const amountIn = 1000000000000000000 // 1 bnb
const pairAddress = [ethers.utils.getAddress(bnb), ethers.utils.getAddress(desiredCoin)];
amounts = await router.getAmountsOut(
    ethers.utils.getAddress('0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73'), //this is the factory address.
    amountIn,
    pairAddress);
    amountOutMin = amounts.sub(amounts[1].div(slippage) //(Ik that if we were to work with hex this wouldnt be valid :/)
);

Best Answer

It seems like you are trying to use the wrong getAmountsOut function:

// performs chained getAmountOut calculations on any number of pairs
function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) {
    require(path.length >= 2, 'PancakeLibrary: INVALID_PATH');
    amounts = new uint[](path.length);
    amounts[0] = amountIn;
    for (uint i; i < path.length - 1; i++) {
        (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]);
        amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
    }
}

This function is marked as internal so it can only be called inside this contract or any contract that derived from the PancakeRouter contract. The right function to call would be this which is also located in the PancakeRouter contract:

function getAmountsOut(uint amountIn, address[] memory path) public pure virtual override returns (uint[] memory amounts) {
    return PancakeLibrary.getAmountsOut(factory, amountIn, path);
}

--

To give you an example on how to use it with Javascript:

const router = new ethers.Contract('0x10ED43C718714eb63d5aA57B78B54704E256024E', [
'function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts)',
'function getAmountsOut(uint amountIn, address[] memory path) public pure virtual override returns (uint[] memory amounts)'
], account);

const amountIn = 1
const fromTokenAddress = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' //BNB
const toTokenAddress = '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56' //BUSD

let amountOuts = await router.getAmountsOut(amountIn, [fromTokenAddress, toTokenAddress])

-> The first array element of amountOuts will be the amountIn you sent

EDIT: Decimal values can be send using the wei unit representation. Just multiply the value you want to send with 10 ** 18 like in the following example:

22.5 BNB -> 22.5 * 10 ** 18 = 22500000000000000000

There are lots of helpful libraries that can help you handling those numbers and providing functions for calculation. For example ethers.js includes such implementation which can be easily used just beware of the version you are using because the usage of BigNumbers in ethers.js is different in version.