如何通过以太坊地址获取ERC-20代币及NFT余额(求Python通用代码)
用web3.py实现以太坊地址的ERC-20总余额与NFT统计
要实现输入钱包地址后获取ETH余额、所有ERC-20代币总价值(以ETH计价)及NFT持有统计,核心是借助链上数据索引服务(如Alchemy)来高效查询代币和NFT数据——以太坊链本身没有全局代币注册表,直接遍历合约事件效率极低且不现实。以下是完整可运行代码:
依赖安装
先安装所需库:
pip install web3 python-dotenv alchemy-sdk
完整代码
创建.env文件,填入你的Alchemy API信息(免费账号即可获取):
ALCHEMY_URL=https://eth-mainnet.g.alchemy.com/v2/你的API密钥 ALCHEMY_API_KEY=你的API密钥
Python代码:
from web3 import Web3 from alchemy import Alchemy, Network from dotenv import load_dotenv import os # 加载环境变量 load_dotenv() # 初始化Web3连接(用于ETH余额查询) w3 = Web3(Web3.HTTPProvider(os.getenv('ALCHEMY_URL'))) if not w3.is_connected(): raise ConnectionError("无法连接到以太坊节点") # 初始化Alchemy客户端(用于代币和NFT批量查询) alchemy = Alchemy( api_key=os.getenv('ALCHEMY_API_KEY'), network=Network.ETH_MAINNET ) def get_eth_balance(address): """获取地址ETH余额""" if not w3.is_address(address): raise ValueError("无效的以太坊地址格式") balance_wei = w3.eth.get_balance(address) return round(w3.from_wei(balance_wei, 'ether'), 6) def get_total_erc20_value(address): """计算所有ERC-20代币的总ETH价值""" token_balances = alchemy.core.get_tokens_for_owner(address) total_eth = 0.0 for token in token_balances['tokens']: # 跳过余额为0的代币 if int(token['balance']) == 0: continue # 获取代币的ETH计价价格 price_data = alchemy.core.get_token_price(token['contractAddress']) if not price_data.get('eth'): continue # 跳过无法获取价格的代币 # 转换余额为可读单位并计算ETH价值 token_amount = float(token['balance']) / (10 ** token['decimals']) eth_value = token_amount / price_data['eth'] total_eth += eth_value return round(total_eth, 4) def get_nft_collection_stats(address): """统计地址持有的NFT按集合分类的数量""" nfts = alchemy.nft.get_nfts_for_owner(address, exclude_fungible_tokens=True) collection_counts = {} for nft in nfts['ownedNfts']: collection_name = nft['contract']['name'] or nft['contract']['address'] collection_counts[collection_name] = collection_counts.get(collection_name, 0) + 1 return collection_counts if __name__ == "__main__": target_address = input("请输入0x格式的以太坊钱包地址:").strip() try: # 获取ETH余额 eth_balance = get_eth_balance(target_address) print(f"\nETH余额:{eth_balance} ETH") # 获取ERC-20总价值 total_erc20_eth = get_total_erc20_value(target_address) print(f"所有ERC-20代币总价值(ETH计价):{total_erc20_eth} ETH") # 获取NFT统计 nft_stats = get_nft_collection_stats(target_address) print("\nNFT持有统计:") if not nft_stats: print("未持有任何NFT") else: for collection, count in nft_stats.items(): print(f"- {collection}: {count} 个") except ValueError as e: print(f"错误:{e}") except ConnectionError as e: print(f"节点连接错误:{e}")
关键说明
- 为什么用Alchemy?:以太坊链上没有内置的代币/ NFT索引,直接通过web3.py遍历所有Transfer事件不现实(耗时极长且容易出错)。Alchemy提供了预索引的批量查询接口,大幅提升效率。
- 代币价值计算:代码中通过Alchemy的代币价格接口将ERC-20余额转换为ETH计价的总价值,也可修改为USD计价(直接使用
price_data['usd'])。 - NFT过滤:默认跳过fungible类NFT(如半同质化代币),如需包含可移除
exclude_fungible_tokens=True参数。 - 测试网适配:只需将
Network.ETH_MAINNET改为Network.ETH_GOERLI等测试网枚举值即可。
内容的提问来源于stack exchange,提问作者Vladimir Propuskov
相关产品推荐
相关产品推荐

