Web3.js解析ETH事件日志:JS BigNumber转WEI/ETH值失败求助
问题:Web3解析事件日志后BigNumber转WEI/ETH格式失败
背景
原本通过receipt.events.MyEvent.returnValues.marketShare可正常获取格式化后的事件数据,该方式失效后,改用web3.eth.abi.decodeLog解析日志,代码如下:
var eventAbi = [ { "indexed": false, "internalType": "uint256", "name": "earnings", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "marketShare", "type": "uint256" }, ]; var myEvent = web3.eth.abi.decodeLog(eventAbi, receipt.logs[1].data, receipt.logs[1].topics);
问题现象
解析后返回原生JS的BigInt格式数值:
earnings: 32n marketShare: 47691443057146912922899395050909650362856399929838832537703884369061582418996n
尝试以下方法转换格式均未得到正确结果:
console.log(myEvent.marketShare.toLocaleString()); console.log(web3.utils.fromWei(myEvent.marketShare, "ether")); console.log(myEvent.marketShare.toNumber()); console.log(myEvent.marketShare.toFixed()); console.log(web3.utils.toBN(myEvent.marketShare));
解决方案
你得到的是原生JS的BigInt类型,而非Web3.js的BN对象,因此需要调整转换方式:
- 转WEI格式:直接调用
toString()即可得到WEI的字符串形式
const weiMarketShare = myEvent.marketShare.toString(); console.log(weiMarketShare);
- 转ETH格式:先将BigInt转为字符串,再传入
web3.utils.fromWei处理(部分新版Web3.js已支持直接传入BigInt,若版本不兼容则用字符串方式)
// 兼容所有Web3.js版本的写法 const ethMarketShare = web3.utils.fromWei(myEvent.marketShare.toString(), 'ether'); console.log(ethMarketShare); // 新版Web3.js可直接传入BigInt // const ethMarketShare = web3.utils.fromWei(myEvent.marketShare, 'ether');
失败原因说明
toNumber():数值超出JS安全整数范围(2^53-1),导致溢出失真toFixed():原生BigInt无此方法,调用会报错web3.utils.fromWei直接传BigInt:旧版Web3.js不支持,会抛出类型错误web3.utils.toBN直接传BigInt:部分版本不兼容,需先转字符串
内容的提问来源于stack exchange,提问作者730wavy
相关产品推荐
相关产品推荐

