如何获取以太坊区块链上的全部代币及用户钱包中的ERC20代币持有列表
嘿,针对你这三个关联的以太坊代币需求,我给你拆解成不同场景来讲解,都是实际开发或查询中常用的方法:
一、获取以太坊区块链上的全部代币
以太坊上的代币不止ERC20,还包括ERC721(NFT)、ERC1155(多标准代币)等多种类型,要获取全部代币的话,主要有两种思路:
- 自建链上扫描系统:运行一个全节点(比如Geth或Erigon),然后遍历从创世块到最新块的所有合约创建交易,对每个合约检测是否符合任意一种代币标准(通过验证接口方法,比如ERC20的
transfer、ERC721的safeTransferFrom等)。但这个方法成本极高,耗时极长,因为以太坊目前有数百万个合约,个人开发者很少这么做。 - 依赖专业链上索引服务:像Dune Analytics、Nansen这类平台已经完成了全链数据的索引,你可以通过它们的SQL查询界面或者官方API,筛选出所有标记为代币的合约。部分服务可能需要付费,但能节省大量时间。
二、获取所有现存ERC20代币的列表
ERC20有统一的接口标准,所以获取这类代币的方法更精准:
- 链上接口验证:针对每个合约,调用
supportsInterface(0x6fd9d721)(ERC20标准的接口ID),如果返回true则说明是ERC20代币。你可以用Ethers.js/Web3.js批量遍历合约地址来做验证,但还是需要全量合约列表的基础。 - 第三方数据提供商:CoinGecko、CoinMarketCap的开放API里有大量ERC20代币的收录,不过它们的列表偏向主流代币,一些小众、新部署的ERC20可能没被收录。如果要接近全量,还是得结合链上索引服务。
- 社区维护的代币列表:比如Uniswap的默认代币列表,只包含经过审核的主流ERC20,适合快速获取常用代币,但不是全量。
三、获取某用户钱包中持有的所有代币清单
这是最实用的需求,方法也最成熟:
- 用第三方节点服务的Token API(推荐):像Alchemy、Infura都提供了专门的代币余额查询接口,能直接返回钱包地址下所有有余额的ERC20代币,无需自己遍历全量代币。举个Ethers.js结合Alchemy的代码例子:
const { Alchemy, Network } = require('alchemy-sdk'); // 替换成你的API密钥和目标网络 const config = { apiKey: 'YOUR_ALCHEMY_KEY', network: Network.ETH_MAINNET }; const alchemy = new Alchemy(config); async function getWalletTokens(walletAddr) { const balanceRes = await alchemy.core.getTokenBalances(walletAddr); // 过滤掉余额为0的代币 const validTokens = balanceRes.tokenBalances.filter(item => item.tokenBalance !== '0'); // 可以进一步调用getTokenMetadata获取代币名称、符号等信息 const tokensWithMeta = await Promise.all( validTokens.map(token => alchemy.core.getTokenMetadata(token.contractAddress)) ); return tokensWithMeta; } - 自建查询逻辑:如果不想依赖第三方服务,可以先获取钱包地址的所有交易记录,筛选出ERC20转账交易(通过判断交易的
input数据是否符合ERC20的transfer或transferFrom方法签名),提取代币地址后,再批量调用每个代币的balanceOf(walletAddr)方法,过滤出余额大于0的代币。这种方法需要处理大量交易数据,效率较低,但适合对数据隐私有要求的场景。 - 钱包端工具:如果是前端应用,可以通过MetaMask等钱包的API获取授权,然后调用钱包内置的代币查询功能,不过底层还是依赖第三方数据服务。
注意事项
- 全量代币列表永远做不到100%完整,因为以太坊上随时有新的代币合约被部署。
- 查询钱包代币时,一定要过滤余额为0的条目,避免无效数据。
- 部分恶意合约可能伪装成ERC20,建议验证合约的接口实现和代码安全性(如果开源的话)。
内容的提问来源于stack exchange,提问作者Leahpar
相关产品推荐
相关产品推荐

