# ethers v6 查余额与交易：先核网络，再解释 null 回执

整理：链小知（AI 辅助）
资料核对日期：2026-10-12
引用地址：https://lianxiaozhi.com/tools/guides/ethers-v6-provider-network-balance-receipt
难度：进阶
核验方式：官方文档整理，未执行真实账户操作

在已有开发项目用 Provider 读取指定区块余额和交易回执，把链错、历史节点缺失、待确认与回滚分开。

## 使用工具
- [ethers.js v6](https://lianxiaozhi.com/tools/ethers-js) · [官方入口](https://docs.ethers.org/v6/)

## 前置条件
- 准备已有 v6 项目、获准使用的 RPC URL、期望 chainId、完整公开地址和交易 hash；不要把URL中的令牌写入日志或分享。记录项目锁定 ethers 版本。
- 教程给官方只读方法与预期类型；阅读已有日志也可完成诊断。使用节点读取需遵守服务认证/额度；不需要 getSigner、钱包连接、私钥或广播。

## 1. 确认 v6 Provider 与连接地址

从项目锁文件核 ethers 主版本，在 v6 使用 import { JsonRpcProvider, formatEther, isError } from 'ethers'，构造 new JsonRpcProvider(rpcUrl)。URL用既有获准端点，不复制文档账户、CDN版本或公共端点当生产配置。

检查是否误用了 v5 的 ethers.providers 或 Web3Provider；BrowserProvider 是注入钱包的适配，不是查普通HTTP节点的必要步骤。RPC错误先保留原错误与脱敏端点，不能转去请求钱包授权。

核对结果：记录包版本、transport类型和脱敏RPC来源；没有引入Signer。
依据：[ethers v6 入门：Provider、Contract与导入](https://docs.ethers.org/v6/getting-started/)
依据：[ethers JSON-RPC：staticNetwork与批次](https://docs.ethers.org/v6/api/providers/jsonrpc/)
依据：[ethers v5 到 v6：bigint与方法变化](https://docs.ethers.org/v6/migrating/)

## 2. 读实际 chainId，拒绝静态掩盖错链

使用 await provider.getNetwork()，保存 network.chainId.toString() 与期望chainId的十进制字符串比较；返回chainId是bigint，不能用字符串标签或RPC域名代替观察结果。

若NETWORK_ERROR或期望不匹配，检查URL和项目链配置，停止解释后续余额。staticNetwork跳过后续网络变化验证，仅确定URL网络不会改变时才可用；不要为消除错误开启，更不能用于可切链MetaMask。

核对结果：期望chainId与所读网络一致，或明确停在网络未证实分支。
依据：[ethers v6 Provider：网络、余额与回执](https://docs.ethers.org/v6/api/providers/)
依据：[ethers JSON-RPC：staticNetwork与批次](https://docs.ethers.org/v6/api/providers/jsonrpc/)
依据：[ethers 错误：code与CALL_EXCEPTION](https://docs.ethers.org/v6/api/utils/errors/)

## 3. 固定区块与公开地址再读余额

对当前余额可 await provider.getBalance(address)；要与旧交易时点比较，先固定已有区块号，用 getBlock(blockNumber) 保存块hash和timestamp，再 getBalance(address, blockNumber)。余额是原生币wei的bigint，不是该地址全部ERC20资产。

历史blockTag需要节点archive支持。块为空、历史状态不可用或超时应保留未知，不能回落latest后仍标同一历史时点；两次latest读取也不保证同块。timestamp为秒，展示时再换成毫秒。

核对结果：地址、chainId、块号/块hash、原始wei整数与读取时间齐全；不把缺失填0。
依据：[ethers v6 Provider：网络、余额与回执](https://docs.ethers.org/v6/api/providers/)
依据：[ethers 错误：code与CALL_EXCEPTION](https://docs.ethers.org/v6/api/utils/errors/)

## 4. 将原整数与显示数量并存

以 raw.toString()保存原余额，用 formatEther(raw) 得到18位原生币显示字符串；例如1000000000000000000n显示'1.0'。如果是合约token余额另取其decimals并使用formatUnits，不能借原生币18位假设。

不要把bigint转Number后再计算；v6 bigint只表示整数，混用普通number会报错。保留原始整数和显示字符串两列，后续比较在整数层做。

核对结果：显示值可由原wei逆核，未丢大整数精度或误当ERC20余额。
依据：[ethers 单位：formatUnits与parseUnits](https://docs.ethers.org/v6/api/utils/)
依据：[ethers v5 到 v6：bigint与方法变化](https://docs.ethers.org/v6/migrating/)
依据：[ethers v6 Provider：网络、余额与回执](https://docs.ethers.org/v6/api/providers/)

## 5. 分别取交易与回执解释 null

对原hash分别使用 getTransaction(hash) 和 getTransactionReceipt(hash)。交易对象存在而回执null可提示尚未挖出，但仍需标明读取节点与时点；两者都null不能直接宣布丢失或失败。

文档明确未知交易和裁剪旧记录的节点也可能返回null；receipt有值时核 hash/from/to/blockHash/blockNumber，to可null例如部署。status=1表示该执行成功、0表示revert、null保留未知，不用成功状态推所有业务资产到账。

核对结果：交易存在性、回执存在性和执行status分开，无null→失败或0的错误转换。
依据：[ethers v6 Provider：网络、余额与回执](https://docs.ethers.org/v6/api/providers/)

## 6. 核确认数与错误，不把回执当最终业务结论

已有receipt可 await receipt.confirmations()记录该时点确认数，另存receipt.fee.toString()（wei）和gasUsed；fee是回执字段，不是预先getFeeData推荐报价。对具体到账还要核同链资产/地址/日志，不以status=1代替。

用isError(err,'CALL_EXCEPTION')等分类。call阶段异常可能无receipt；NETWORK_ERROR/SERVER_ERROR/TIMEOUT与链上revert不同。仅归档脱敏code/action/data/reason和读取时点，不在重试脚本中加入send或broadcast。

核对结果：交付网络—区块—余额—回执对照，未知/重组与实际到账仍有独立检查边界。
依据：[ethers v6 Provider：网络、余额与回执](https://docs.ethers.org/v6/api/providers/)
依据：[ethers 错误：code与CALL_EXCEPTION](https://docs.ethers.org/v6/api/utils/errors/)

## 常见错误
- 收据null不是唯一待确认状态，裁剪节点会丢旧记录。
- getBalance只读原生币；节点有服务费/限流，读取不表示第三方RPC可信。
- 本教程是文档核验；示例和方法未在钱包或RPC实测，不证明任何hash最终完成。

## 完成检查
- 形成可复核的原输入、chainId、块号/hash、余额整数/显示和回执状态记录。
- 缺网络/历史状态/回执时保留具体未知；未发送、签名或广播任何交易。

## 相关知识
- [私有 RPC 能防止所有抢跑和夹子交易吗？](https://lianxiaozhi.com/learn/private-rpc-trust-boundaries)
- [区块确认与最终性是什么？交易成功和充值到账为何不同步](https://lianxiaozhi.com/learn/confirmations-and-finality)
- [原始、解码和整理后的链上数据有什么区别？](https://lianxiaozhi.com/learn/raw-decoded-curated-data)

## 官方依据
- [ethers v6 入门：Provider、Contract与导入](https://docs.ethers.org/v6/getting-started/)
- [ethers JSON-RPC：staticNetwork与批次](https://docs.ethers.org/v6/api/providers/jsonrpc/)
- [ethers v5 到 v6：bigint与方法变化](https://docs.ethers.org/v6/migrating/)
- [ethers v6 Provider：网络、余额与回执](https://docs.ethers.org/v6/api/providers/)
- [ethers 错误：code与CALL_EXCEPTION](https://docs.ethers.org/v6/api/utils/errors/)
- [ethers 单位：formatUnits与parseUnits](https://docs.ethers.org/v6/api/utils/)
