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

使用JSON.stringify序列化Web3交易对象时遭遇BigInt序列化错误

JSON.stringify序列化Web3交易对象时遭遇BigInt序列化错误

我太懂这个坑了!你从Web3获取的交易对象里,那些带n后缀的(比如blockNumber: 0n、gas: 0n)都是BigInt类型,而JSON标准本身并不支持BigInt的序列化,所以直接用JSON.stringify就会抛出那个讨厌的类型错误。

问题根源

JS里的BigInt是为了处理超大整数而生的(毕竟以太坊里的数值经常会超过Number的安全精度范围2^53-1),但JSON规范里压根没这个类型,所以默认的序列化函数不知道该怎么处理它。

几种快速解决方法

1. 给JSON.stringify加Replacer函数(最推荐)

这是最灵活且无副作用的方式,在序列化时专门处理BigInt:

const txString = JSON.stringify(x, (key, value) => {
  // 把所有BigInt转成字符串,彻底避免精度丢失
  return typeof value === 'bigint' ? value.toString() : value;
});

如果你的交易数值都很小(比如测试网里的0n),也可以转成Number,但强烈不推荐在主网这么做——一旦数值超过2^53-1,转Number会直接丢失精度,字符串才是安全选项。

2. 扩展BigInt的toJSON方法(一劳永逸,但要注意副作用)

如果项目里经常要序列化BigInt,可以给BigInt原型加个toJSON方法,以后直接用JSON.stringify就行:

// 全局扩展BigInt的序列化逻辑
BigInt.prototype.toJSON = function() {
  return this.toString();
};

// 现在直接序列化交易对象就没问题了
const txString = JSON.stringify(x);

⚠️ 注意:修改原生对象原型可能会和其他库冲突,如果是团队项目最好先和队友沟通确认。

3. 手动转换字段(适合需要自定义处理的场景)

如果你只需要处理这一个交易对象,也可以手动遍历把所有BigInt字段转成字符串:

const serializableTx = {
  ...x,
  blockNumber: x.blockNumber.toString(),
  gas: x.gas.toString(),
  gasPrice: x.gasPrice.toString(),
  maxFeePerGas: x.maxFeePerGas.toString(),
  maxPriorityFeePerGas: x.maxPriorityFeePerGas.toString(),
  nonce: x.nonce.toString(),
  transactionIndex: x.transactionIndex.toString(),
  value: x.value.toString(),
  type: x.type.toString(),
  chainId: x.chainId.toString(),
  v: x.v.toString()
};
const txString = JSON.stringify(serializableTx);

这种方式虽然繁琐,但能精准控制每个字段的处理方式,比如某些字段你确实想转成Number也可以在这里改。

额外提醒

Web3返回BigInt而不是普通数字,本质是为了避免超大数值的精度丢失问题——比如以太坊里的gasPrice可能是1e18量级的,用Number存直接就变科学计数法且丢精度了,所以序列化时优先转字符串是最稳妥的选择。

备注:内容来源于stack exchange,提问作者Teyrox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 20:03:06