以太坊作为全球第二大公链,其代币(如ETH、ERC-20代币)的余额查询是区块链应用开发中的基础功能,无论是钱包、交易所还是DeFi协议,都需要通过以太坊余额查询接口获取地址的资产信息,本文将详细介绍以太坊余额查询的原理、常用接口、调用方法及开发注意事项,帮助开发者高效实现这一功能。
以太坊余额查询的核心原理
以太坊上的余额数据存储在区块链的状态树(State Tree)中,每个地址的余额和代币信息都通过Merkle Patricia树结构持久化,查询余额的本质,是通过节点或第三方服务,读取指定地址在当前最新区块(或指定区块)的状态数据。
根据数据来源的不同,余额查询可分为两类:
- 直接节点查询:连接以太坊全节点或轻节点,调用JSON-RPC接口直接读取链上数据;
- 第三方服务查询:通过区块链浏览器(如Etherscan)、Infura、Alchemy等节点服务商提供的API接口获取数据。
常用以太坊余额查询接口及方法
JSON-RPC接口(节点原生查询)
以太坊节点(如Geth、OpenEthereum)支持JSON-RPC协议,提供eth_getBalance方法查询ETH余额,以及eth_call方法查询ERC-20代币余额。
-
查询ETH余额
{ "jsonrpc": "2.0", "method": "eth_getBalance", "params": ["0x742d35Cc6634C0532925a3b844Bc454e4438f44e", "latest"], "id": 1 }params[0]:目标地址(需加"0x"前缀);params[1]:区块参数,如"latest"(最新区块)、"pending"(待打包区块)、"earliest"(创世区块)或具体区块号。- 返回值为余额的十六进制字符串,单位为wei(1 ETH = 10^18 wei),需转换为可读单位。
-
查询ERC-20代币余额
ERC-20代币的余额通过调用合约的balanceOf()方法获取,需构造eth_call请求:{ "jsonrpc": "2.0", "method": "eth_call", "params": [{ "to": "0xdAC17F958D2ee523a2206206994597C13D831ec7", // USDT合约地址 "data": "0x70a08231000000000000000000000000742d35Cc6634C0532925a3b844Bc454e4438f44e" // balanceOf(目标地址) }, "latest"], "id": 1 }data字段为balanceOf(address)的函数签名(0x70a08231)+ 目标地址(补零至64位);- 返回值为代币余额的十六进制字符串,需结合代币的
decimals(小数位)转换为可读单位(如USDT的
decimals=6)。
第三方API接口(简化开发)
对于不想自建节点的开发者,第三方服务商提供了更易用的REST或WebSocket接口,通常封装了复杂的参数构造,支持直接返回JSON格式数据。
-
Infura(主流节点服务商)
以查询ETH余额为例(需替换YOUR_PROJECT_ID):curl -X POST "https://mainnet.infura.io/v3/YOUR_PROJECT_ID" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x742d35Cc6634C0532925a3b844Bc454e4438f44e","latest"],"id":1}' -
Etherscan(区块链浏览器API)
Etherscan提供丰富的API,可查询ETH和ERC-20代币余额,需注册API Key:- 查询ETH余额:
https://api.etherscan.io/api?module=account&action=balance&address=0x742d35Cc6634C0532925a3b844Bc454e4438f44e&tag=latest&apikey=YOUR_API_KEY
- 查询ERC-20代币余额(以USDT为例):
https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=0xdAC17F958D2ee523a2206206994597C13D831ec7&address=0x742d35Cc6634C0532925a3b844Bc454e4438f44e&tag=latest&apikey=YOUR_API_KEY
- 查询ETH余额:
-
Alchemy(高性能节点服务)
Alchemy的API与Infura类似,但提供更高的稳定性和扩展功能,例如支持批量查询:{ "id": 1, "jsonrpc": "2.0", "method": "alchemy_getTokenBalances", "params": ["['0x742d35Cc6634C0532925a3b844Bc454e4438f44e']", ["0xdAC17F958D2ee523a2206206994597C13D831ec7"]] }
Web3.js/Ethers.js(前端/后端SDK封装)
在开发中,通常通过Web3.js或Ethers.js等SDK调用接口,简化代码逻辑。
-
Ethers.js示例(查询ETH余额):
import { ethers } from "ethers"; const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_PROJECT_ID"); const address = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"; const balance = await provider.getBalance(address); console.log(ethers.utils.formatEther(balance), "ETH"); // 转换为ETH单位 -
Ethers.js示例(查询ERC-20代币余额):
const tokenContract = new ethers.Contract( "0xdAC17F958D2ee523a2206206994597C13D831ec7", // USDT合约地址 ["function balanceOf(address) view returns (uint256)"], provider ); const tokenBalance = await tokenContract.balanceOf(address); console.log(ethers.utils.formatUnits(tokenBalance, 6), "USDT"); // 结合decimals转换
开发注意事项
-
节点同步与数据延迟
- 自建节点需保持同步,否则查询结果可能滞后;
- 第三方服务(如Infura、Alchemy)依赖其节点状态,高峰期可能存在延迟,建议选择高可用服务商。
-
API调用频率限制
免费API(如Etherscan免费版)通常有调用次数限制(如5次/秒),高频场景需升级付费接口或使用缓存策略。
-
代币合约兼容性
- 部分代币可能遵循非标准ERC-20接口(如缺少
decimals方法),需提前校验合约,避免查询失败。
- 部分代币可能遵循非标准ERC-20接口(如缺少
-
安全与隐私
- 查询地址时,避免在日志或前端代码中暴露敏感地址;
- 使用HTTPS协议调用API,防止中间人攻击。
-
批量查询优化
- 需查询多个地址余额时,优先选择支持批量查询的接口(如Alchemy的
getTokenBalances),减少网络请求次数。
- 需查询多个地址余额时,优先选择支持批量查询的接口(如Alchemy的
以太坊余额查询接口是区块链应用的基础组件,开发者可根据需求选择自建节点、第三方API或SDK封装方案,JSON-RPC接口灵活性高但需处理底层细节,第三方服务简化开发但依赖服务商,而Ethers.js/Web3.js等SDK则提供了更友好的开发体验,在实际开发中,需综合考虑性能、成本、安全性等因素,选择最适合的查询方式,确保应用的稳定与高效。
随着以太坊生态的不断发展,余额查询功能