Reputation: 29
My ultimate goal is to get the current price in ethereum of a token. To do this, I was using etherscan's api to get the contract ABI and then using the ABI and token decimals, get the current price of the token in ETH.
However, now I would like to get this data without using an API call and instead utilize the web3 library function calls. How can I get the ABI of an ethereum contract address only using the web3 library?
For reference, here is the code I am using to get the current price of a token in ethereum. The getAbi method needs to be fixed because it is currently using an api call so I will not include it:
async function getTokenPriceInEth(tokenAddress) {
try {
const uniswap_v2_router = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
const uniswap_v2_router_abi = await getAbi(uniswap_v2_router);
if (!uniswap_v2_router_abi) {
throw new Error('Failed to fetch Uniswap router ABI');
}
const router = new web3.eth.Contract(uniswap_v2_router_abi, uniswap_v2_router);
const tokenAbi = await getAbi(tokenAddress);
if (!tokenAbi) {
throw new Error(`Failed to fetch ABI for token: ${tokenAddress}`);
}
const tokenContract = new web3.eth.Contract(tokenAbi, tokenAddress);
const tokenDecimals = await tokenContract.methods.decimals().call();
const amountIn = '1' + '0'.repeat(parseInt(tokenDecimals));
const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; // Ethereum Mainnet WETH address
const path = [tokenAddress, WETH_ADDRESS];
const amounts = await router.methods.getAmountsOut(amountIn, path).call();
const ethAmount = web3.utils.fromWei(amounts[1], 'ether');
const tokenPriceInEth = parseFloat(ethAmount);
return tokenPriceInEth;
} catch (error) {
return 0;
}
}
Upvotes: 0
Views: 203
Reputation: 21
You don't need to request Etherscan to get the ABI, neither for the Uniswap router, nor for the tokens you want to price.
For the Uniswap router, since it's always the same for a given address, you can download it once and for all and have it as a constant in your code.
For tokens, you just use/call their decimals()
method. All tokens on Uniswap respects most of the ERC-20 standard, at least for this method. So here as well you can have the decimals()
method ABI as a constant in your code and use it for all your tokens:
[{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"}]
And you use this ABI instead of tokenAbi
. Indeed, you don't need to have the full ABI to build the Contract
object, just the parts for the methods or events you intend to use.
Also, if you wish, the above ABI can be simplified, only a few details are mandatory like the method name
and the inputs
.
Upvotes: 0
Reputation: 402
ABIs of verified smart contracts can be downloaded from block explorers like Etherscan. For your Uniswap V2 router, you can find it by searching for the contract address here (scroll down to Contract ABI section).
The ABI you need is typically a JSON file that you can import into your dApp.
You can also often find ABIs in the official GitHub repositories of the protocol’s smart contracts. In the future, it’s usually more effective to join a project’s Discord or seek support from the community rather than posting on StackOverflow.
Upvotes: 0