智能合约交互时BigInt无法转为JSON对象报错排查
问题分析与解决方案
错误根源
- 直接传递BigInt类型:从智能合约获取的
totalSupply和remainingSupply是BigInt类型(带n后缀),而JSON标准不支持原生BigInt的序列化,调用res.json()时会抛出TypeError: Do not know how to serialize a BigInt,触发500错误。 - 转换为Number的精度问题:你转换后的数值(如
189880000000000000)远超过JavaScript Number的安全整数范围(2^53 - 1,即9007199254740991),虽然打印时显示正常,但实际会丢失精度,且部分JSON处理逻辑对超大数值存在兼容性问题,同样可能导致序列化失败。
正确解决方案
将BigInt转换为字符串是最安全的处理方式:既不会丢失精度,也能被JSON正常序列化。
修正后的完整代码:
app.get('/stats', async (req, res) => { try { const totalSupply = await contract.methods.totalSupply().call(); const remainingSupply = await contract.methods.remainingSupply().call(); // 将BigInt转为字符串,避免序列化问题与精度丢失 const responseObj = { totalSupply: totalSupply.toString(), remainingSupply: remainingSupply.toString() }; console.log("JSON", responseObj); res.json(responseObj); } catch (error) { // 打印错误详情,方便后续排查 console.error("请求处理错误:", error); res.status(500).send(`500 Error: ${error.message}`); } });
额外建议
- 在catch块中打印完整错误信息,能快速定位具体报错原因(比如序列化失败、合约调用异常等)。
- 前端接收数据后,如果需要进行数值计算,可将字符串转回BigInt(
BigInt(totalSupply)),避免精度丢失。
内容的提问来源于stack exchange,提问作者Technically Web3
相关产品推荐
相关产品推荐

