从返回bigNumber的智能合约函数提取普通整数的实现方案咨询
BigNumber类型转普通整数方案评估
现有写法判断
你给出的const bal = parseInt(formatUnits(balance,"wei"));属于欠妥的变通方案,存在两个核心问题:
- 不必要的冗余操作:
formatUnits的设计目的是将wei单位的BigNumber转换为指定精度的高阶单位(如ether)字符串,传入单位为"wei"时相当于做了一次无意义的字符串转换,额外消耗性能。 - 极高的精度丢失风险:JavaScript普通Number类型的安全整数范围仅为
-2^53 ~ 2^53-1(约等于正负9e15),而以太坊主网1ETH等于1e18 wei,哪怕仅0.01ETH的余额换算成wei就已经超过安全整数范围,用parseInt转普通Number会直接出现精度丢失,导致业务逻辑错误。
更优实现方案
根据你的使用场景选择对应方案即可:
- 确认数值一定在安全整数范围内(比如小于1e15的计数类结果)
直接使用BigNumber实例自带的转换方法,不需要额外引入工具函数:
- ethers v5版本:
const bal = balance.toNumber() - ethers v6/viem等支持原生bigint的库:
const bal = Number(balance)
- 数值可能超过安全整数,仅用于页面展示
直接转字符串使用,不需要转普通整数:
- 保留wei单位:
const balWei = balance.toString() - 需要转成ether等单位展示:
const balEth = formatUnits(balance, 18)
- 需要对大数做算术运算
不要转普通Number,直接使用BigNumber实例自带的运算方法,或者基于原生bigint做运算,完全避免精度问题。
内容的提问来源于stack exchange,提问作者PrashanthDev
相关产品推荐
相关产品推荐

