Provider vs Contract:Balance 查询对比

一句话结论

  • ProvidergetBalance 查的是地址的原生币余额
  • Contract(如 ERC20)里的 balanceOf 查的是地址在该合约中的 Token 余额

1) Provider:getBalance(address)

含义

查询某个地址当前持有的原生代币数量。

典型场景

  • 查询 EOA 钱包地址的 ETH 余额
  • 查询合约地址持有的 ETH(比如某个合约金库里的 ETH)

关键点

  • 不关心该地址是否是 EOA/Contract,统一按“地址的原生币”查询
  • 不能直接查 ERC20(USDT/WETH/DAI)余额

示例

1
2
const eth1 = await provider.getBalance("0xEOA...");
const eth2 = await provider.getBalance("0xContract...");

2) Contract:balanceOf(address)(以 ERC20 为例)

含义

查询某地址在某个 Token 合约账本中的余额。

典型场景

  • 查询用户的 USDT/WETH/DAI 余额
  • 查询某地址在指定 ERC20 里的持仓

关键点

  • 必须先确定“哪一个 token 合约”
  • 同一个地址在不同 token 合约中的余额互不影响

示例

1
2
3
4
5
const usdt = new ethers.Contract(USDT_ADDR, erc20Abi, provider);
const weth = new ethers.Contract(WETH_ADDR, erc20Abi, provider);

const usdtBalance = await usdt.balanceOf("0xUser...");
const wethBalance = await weth.balanceOf("0xUser...");

3) 对比表

对比项 Provider getBalance Contract balanceOf
查询对象 地址的原生币余额 地址在某合约中的 token 余额
资产类型 ETH/BNB/MATIC 等原生币 ERC20/ERC721/ERC1155 等合约资产(方法不同)
是否需要合约 ABI
是否需要合约地址 否(只要目标地址) 是(必须指定 token 合约)
输入地址角色 EOA 或 Contract 都可 EOA 或 Contract 都可
常见误区 以为可直接查 ERC20 忘记切换到正确 token 合约

4) 常见误区澄清

  • 误区:给 provider.getBalance 传 token 合约地址,就能得到该 token 总余额。
    实际:得到的是“这个合约地址持有的原生币余额”,不是 token 余额。

  • 误区provider 不能查合约地址余额。
    实际:可以查,但查的是该合约地址的原生币余额。


5) 记忆口诀

  • 原生币 -> provider.getBalance
  • 合约资产 -> contract.xxx(...)(ERC20 用 balanceOf