You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web3.js中BN.js处理大幂指数数值时报错Assertion failed如何解决

问题原因
  • 核心问题出在JSON解析阶段:你接口返回的余额是超过JS安全整数范围(2^53-1)的大数字,调用await post_response_2.json()时,JS会自动把大数字转为Number类型,不仅会变成科学计数法格式,还会丢失精度。BN.js不支持接收已经失真的Number类型、或者科学计数法格式的字符串作为入参,所以触发了内部的assert断言报错。
  • 代码冗余问题:new BN()和web3.utils.fromWei()都不是异步方法,不需要加await关键字。
解决方案

方案1:优先调整服务端返回逻辑(最稳妥)

让服务端把代币余额以字符串类型返回,不要返回数字类型,从根源避免JS自动转Number丢失精度。调整后代码如下:

const post_response_2 = await fetch('/balanceOf-TKN-by-addr', {
  method: 'POST', 
  body: stringify_post_input, 
  headers: { "content-type": "application/json" }
});
var TKN_balance_response = await post_response_2.json(); 
console.log(TKN_balance_response);
// 直接传入字符串格式的余额即可
var TKN_BN = new BN(TKN_balance_response);
var TKN_balance = web3.utils.fromWei(TKN_BN, 'ether');
console.log("TKN_balance :: "+String(TKN_balance));

方案2:服务端无法修改的场景,手动解析响应文本

如果服务端逻辑没法调整,就不要直接调用json()方法解析,先拿到原始响应文本,用支持大整数的规则解析出完整的余额字符串:

const post_response_2 = await fetch('/balanceOf-TKN-by-addr', {
  method: 'POST', 
  body: stringify_post_input, 
  headers: { "content-type": "application/json" }
});
// 先获取原始响应文本
const rawResText = await post_response_2.text();
// 自定义解析逻辑,把大数字转成字符串保留完整精度
const parsedRes = JSON.parse(rawResText, (key, value) => {
  // 替换成你接口里余额对应的字段名
  if (key === 'balance' && typeof value === 'number') {
    return value.toLocaleString('fullwide', { useGrouping: false });
  }
  return value;
});
var TKN_balance_response = parsedRes.balance;
var TKN_BN = new BN(TKN_balance_response);
var TKN_balance = web3.utils.fromWei(TKN_BN, 'ether');
console.log("TKN_balance :: "+String(TKN_balance));
额外注意事项

BN.js的合法入参仅包括安全整数范围内的数字、完整的数字字符串、Buffer等类型,不要传入超过安全整数范围的Number、或者科学计数法格式的字符串,否则都会触发断言报错。

内容的提问来源于stack exchange,提问作者JDS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 07:06:03