我想要获取一个钱包地址所持有的代币合约列表,类似于bscscan所做的那样,但是需要通过编程的方式实现。bscscan.com/apis没有相关的端点,而web3js似乎只能报告以太坊余额。
这是可以实现的,因为bscscan报告了这个列表,许多代币跟踪器(如farmfol.io)似乎也可以提取这些信息。我只是找不到正确的方法。
我想要获取一个钱包地址所持有的代币合约列表,类似于bscscan所做的那样,但是需要通过编程的方式实现。bscscan.com/apis没有相关的端点,而web3js似乎只能报告以太坊余额。
这是可以实现的,因为bscscan报告了这个列表,许多代币跟踪器(如farmfol.io)似乎也可以提取这些信息。我只是找不到正确的方法。
每个地址的ERC-20令牌余额(以及类似于TRC-20,BEP-20等的ERC-20)存储在代币的合约中。
区块链浏览器会扫描每个交易以查找Transfer()
事件,并且如果发射器是代币合约,则会更新其单独数据库中的代币余额。每个地址的所有代币余额(来自此单独的数据库)随后显示为地址详细页面上的代币余额。
Etherscan和BSCScan目前不提供可以返回每个地址的代币余额的API。
要获取地址的所有ERC-20代币余额,最简单的解决方案(除了找到返回数据的API之外)是循环遍历所有代币合约(或者只是您感兴趣的代币),并调用它们的balanceOf(address)
函数。
const tokenAddresses = [
'0x123',
'0x456',
];
const myAddress = '0x789';
for (let tokenAddress of tokenAddresses) {
const contract = new web3.eth.Contract(erc20AbiJson, tokenAddress);
const tokenBalance = await contract.methods.balanceOf(myAddress).call();
}
https://api.bscscan.com/api?module=account&action=tokentx&address=0x7bb89460599dbf32ee3aa50798bbceae2a5f7f6a&page=1&offset=5&startblock=0&endblock=999999999&sort=asc&apikey=YourApiKeyToken
你可以尝试使用类似Covalent的聚合数据API——BSC的余额(获取地址的代币余额)终端点正是你所需的。
https://api.covalenthq.com/v1/56/address/{wallet_address}/balances_v2/?key={API_KEY}
有几种不同的方法可以获取钱包的代币余额。
从创世块开始索引整个区块链,跟踪其交易历史中的所有ERC-20合约,并计算钱包的代币余额。显然不建议这样做——它需要大量的开发工作和时间。
使用Token API。像Alchemy和Moralis这样的开发工具都有免费的API。
在Alchemy的情况下,使用“alchemy_getTokenBalances”端点。详细教程在此, 或者只需按照以下步骤操作。
运行脚本之前
在查询用户的代币余额时,您应该掌握一些关键参数:
OwnerAddress:这是拥有所询问代币的区块链地址。请注意,这不是代币本身的合约地址。 tokenContractAddress:您想要获取余额的所有代币的合约地址数组。或者,如果指定字符串erc20,则会包括地址曾经持有过的所有erc20代币。
以下是在您设置Alchemy账户后的操作指南(免费): 方法1(最简单): 使用Alchemy SDK + "alchemy_getTokenBalances"终端点。 请在命令行中运行以下命令:// Setup: npm install alchemy-sdk
import { Alchemy, Network } from "alchemy-sdk";
const config = {
apiKey: "<-- ALCHEMY APP API KEY -->",
network: Network.ETH_MAINNET,
};
const alchemy = new Alchemy(config);
//Feel free to switch this wallet address with another address
const ownerAddress = "0x00000000219ab540356cbb839cbe05303d7705fa";
//The below token contract address corresponds to USDT
const tokenContractAddresses = ["0xdAC17F958D2ee523a2206206994597C13D831ec7"];
const data = await alchemy.core.getTokenBalances(
ownerAddress,
tokenContractAddresses
);
console.log("Token balance for Address");
console.log(data);
方法二:使用 Node-Fetch
import fetch from 'node-fetch';
// Replace with your Alchemy API key:
const apiKey = "demo";
const fetchURL = `https://eth-mainnet.g.alchemy.com/v2/${apiKey}`;
// Replace with the wallet address you want to query:
const ownerAddr = "0x00000000219ab540356cbb839cbe05303d7705fa";
/*
Replace with the token contract address you want to query:
The below address Corresponds to USDT
*/
const tokenAddr = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
var raw = JSON.stringify({
"jsonrpc": "2.0",
"method": "alchemy_getTokenBalances",
"headers": {
"Content-Type": "application/json"
},
"params": [
`${ownerAddr}`,
[
`${tokenAddr}`,
]
],
"id": 42
});
var requestOptions = {
method: 'POST',
body: raw,
redirect: 'follow'
};
var data;
/*
** Fetching the token Balance with Alchemy's getTokenBalances API
*/
await fetch(fetchURL, requestOptions)
.then(response => response.json())
.then(response => {
//This line converts the tokenBalance values from hex to decimal
response["result"]["tokenBalances"][0]["tokenBalance"] = parseInt(response["result"]["tokenBalances"][0]["tokenBalance"], 16);
data = response.result;
console.log("Response Object for getTokenBalances\n", data)
})
.catch(error => console.log('error', error));
balanceOf()
函数的ABI,对于所有代币合同来说是相同的(假定它们都遵循ERC20标准),因为您仅调用此函数... 如果您想调用其他功能,则还需要将它们添加到ABI中。 - Petr Hejda