我的最终目标是获得代币在以太坊中的当前价格。为此,我使用 etherscan 的 api 获取合约 ABI,然后使用 ABI 和代币小数,获取 ETH 代币的当前价格。
但是,现在我想在不使用 API 调用的情况下获取这些数据,而是利用 web3 库函数调用。如何仅使用 web3 库获取以太坊合约地址的 ABI?
作为参考,这是我用来获取以太坊代币当前价格的代码。 getAbi 方法需要修复,因为它当前正在使用 api 调用,所以我不会包含它:
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;
}
}
经过验证的智能合约的 ABI 可以从 Etherscan 等区块浏览器下载。对于您的 Uniswap V2 路由器,您可以通过搜索合约地址此处(向下滚动到合约 ABI 部分)来找到它。
您需要的 ABI 通常是一个 JSON 文件,您可以将其导入到您的 dApp 中。
您还经常可以在协议智能合约的官方 GitHub 存储库中找到 ABI。未来,加入项目的 Discord 或寻求社区支持通常比在 StackOverflow 上发帖更有效。