# Web3j 余额显示异常：核对节点、区块参数和 wei 转换

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

以 4.14.0 的 HTTP RPC 和原生 ETH 余额为例，把请求执行错误与整数单位错误分开。

## 使用工具
- [Web3j](https://lianxiaozhi.com/tools/web3j) · [官方入口](https://docs.web3j.io/4.14.0/)

## 前置条件
- 准备 Web3j 4.14.0 工程或同版本脱敏读取代码，目标 Ethereum 地址、节点地址及查询时间。
- 节点读取权限与钱包私钥分开；托管 RPC 可要求 API key 和额度，排查用例不加载 Credentials。

## 1. 明确连接到哪个 HTTP 节点

用 Web3j.build(new HttpService("<RPC_URL>")) 指定已授权节点；空 HttpService() 默认 localhost:8545。先检查 web3.web3ClientVersion().send() 的响应；连接拒绝通常要检查本地节点是否启动、端口或网络权限，而非把余额解释为 0。

核对结果：记录脱敏节点、clientVersion 或连接错误；尚无有效响应时余额保持未知。
依据：[Web3j 4.14.0：节点连接与请求执行](https://docs.web3j.io/4.14.0/getting_started/interacting_with_node/)

## 2. 给余额请求带上区块参数

余额请求形如 web3.ethGetBalance("<ADDRESS>", DefaultBlockParameterName.LATEST).send()。源码明确把地址和区块参数一起发到 eth_getBalance；latest 随链变化，比较两个结果时应保留区块口径与时间，不能混用历史截图。

核对结果：请求包含完整地址、明确区块参数，结果没有被默认替换成零。
依据：[Web3j v4.14.0：ethGetBalance 请求实现](https://raw.githubusercontent.com/web3j/web3j/v4.14.0/core/src/main/java/org/web3j/protocol/core/JsonRpc2_0Web3j.java)
依据：[Web3j 4.14.0：节点连接与请求执行](https://docs.web3j.io/4.14.0/getting_started/interacting_with_node/)

## 3. 保留原始整数并检查错误

先判断响应是否含 JSON-RPC error，再处理 EthGetBalance 的余额值；认证/限流或 transport 异常和成功返回的零余额是不同情况。保留 BigInteger 或整数十进制字符串，不经 double 中转，也不要把 ERC-20 的 balanceOf 响应当成这个原生币请求。

核对结果：原始 wei 字符串与读取错误分别保存，地址和原生币身份未混淆。
依据：[Web3j v4.14.0：ethGetBalance 请求实现](https://raw.githubusercontent.com/web3j/web3j/v4.14.0/core/src/main/java/org/web3j/protocol/core/JsonRpc2_0Web3j.java)
依据：[Web3j 4.14.0：Java/Android Ethereum 客户端](https://docs.web3j.io/4.14.0/)

## 4. 用十进制定点转换显示值

使用 Convert.fromWei(new BigDecimal("<WEI_INTEGER>"), Convert.Unit.ETHER)，ETHER 的因子是 10^18。用 1000000000000000000 作为纯本地算术样例应得到 1 ETH；保存原值以便回算，避免对已格式化的 ETH 再除一次。其他代币须另取 decimals。

核对结果：样例换算为 1，实际显示值乘 10^18 可恢复原始 wei。
依据：[Web3j v4.14.0：Convert 的 ETHER 精度与 fromWei](https://raw.githubusercontent.com/web3j/web3j/v4.14.0/utils/src/main/java/org/web3j/utils/Convert.java)

## 5. 检查异步等待与写入边界

若改成 sendAsync，只有拿到完成结果才能显示余额；不等待 Future 或吞掉异常会把未完成请求伪装成零。同一官方页面还有 WalletUtils、Transfer.sendFunds 和 ethSendRawTransaction，这些属于钱包/广播流程；余额核对仅需节点读取代码。

核对结果：界面区分加载、读取失败和成功值；读取路径不含钱包解锁或交易广播。
依据：[Web3j 4.14.0：节点连接与请求执行](https://docs.web3j.io/4.14.0/getting_started/interacting_with_node/)
依据：[Web3j 4.14.0：Ether 单位换算](https://docs.web3j.io/4.14.0/transactions/transfer_eth/)

## 常见错误
- latest 的两次读取可能处于不同区块，不宜直接据此推断缺失资产。
- BigInteger 转 double 会损失大数精度；格式化数值不应覆盖原始整数。
- 成功读取原生 ETH 余额不等于读取了 ERC-20、跨链余额或可立即花费额度。

## 完成检查
- 能复核节点、地址、区块口径、原始 wei 与显示 ETH 五项。
- 官方 4.14.0 文档与源码核对通过；未运行钱包或 RPC 请求。

## 相关知识

## 官方依据
- [Web3j 4.14.0：节点连接与请求执行](https://docs.web3j.io/4.14.0/getting_started/interacting_with_node/)
- [Web3j v4.14.0：ethGetBalance 请求实现](https://raw.githubusercontent.com/web3j/web3j/v4.14.0/core/src/main/java/org/web3j/protocol/core/JsonRpc2_0Web3j.java)
- [Web3j 4.14.0：Java/Android Ethereum 客户端](https://docs.web3j.io/4.14.0/)
- [Web3j v4.14.0：Convert 的 ETHER 精度与 fromWei](https://raw.githubusercontent.com/web3j/web3j/v4.14.0/utils/src/main/java/org/web3j/utils/Convert.java)
- [Web3j 4.14.0：Ether 单位换算](https://docs.web3j.io/4.14.0/transactions/transfer_eth/)
