以太坊作为全球第二大公链,其代币(如ETH、ERC-20代币)的余额查询是区块链应用开发中的基础功能,无论是钱包、交易所还是DeFi协议,都需要通过以太坊余额查询接口获取地址的资产信息,本文将详细介绍以太坊余额查询的原理、常用接口、调用方法及开发注意事项,帮助开发者高效实现这一功能。

以太坊余额查询的核心原理

以太坊上的余额数据存储在区块链的状态树(State Tree)中,每个地址的余额和代币信息都通过Merkle Patricia树结构持久化,查询余额的本质,是通过节点或第三方服务,读取指定地址在当前最新区块(或指定区块)的状态数据。

根据数据来源的不同,余额查询可分为两类:

  1. 直接节点查询:连接以太坊全节点或轻节点,调用JSON-RPC接口直接读取链上数据;
  2. 第三方服务查询:通过区块链浏览器(如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  
  • 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转换  

开发注意事项

  1. 节点同步与数据延迟

    • 自建节点需保持同步,否则查询结果可能滞后;
    • 第三方服务(如Infura、Alchemy)依赖其节点状态,高峰期可能存在延迟,建议选择高可用服务商。
  2. API调用频率限制

    免费API(如Etherscan免费版)通常有调用次数限制(如5次/秒),高频场景需升级付费接口或使用缓存策略。

  3. 代币合约兼容性

    • 部分代币可能遵循非标准ERC-20接口(如缺少decimals方法),需提前校验合约,避免查询失败。
  4. 安全与隐私

    • 查询地址时,避免在日志或前端代码中暴露敏感地址;
    • 使用HTTPS协议调用API,防止中间人攻击。
  5. 批量查询优化

    • 需查询多个地址余额时,优先选择支持批量查询的接口(如Alchemy的getTokenBalances),减少网络请求次数。

以太坊余额查询接口是区块链应用的基础组件,开发者可根据需求选择自建节点、第三方API或SDK封装方案,JSON-RPC接口灵活性高但需处理底层细节,第三方服务简化开发但依赖服务商,而Ethers.js/Web3.js等SDK则提供了更友好的开发体验,在实际开发中,需综合考虑性能、成本、安全性等因素,选择最适合的查询方式,确保应用的稳定与高效。

随着以太坊生态的不断发展,余额查询功能