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

Web3j中长十六进制字符串转BigInteger遇NumberFormatException求助

解决Web3j中长十六进制TokenID转BigInteger触发NumberFormatException的问题

问题描述

我在使用Web3j调用ERC1155合约的balanceOf方法时,尝试将一个长十六进制字符串转换为BigInteger作为tokenId传入,但始终抛出NumberFormatException。以下是相关代码和异常信息:

触发异常的代码

public void getBalance1155(String walletAddress) throws ExecutionException, InterruptedException {
    //define constant values
    Web3j web3j=Web3j.build(new HttpService("https://mainnet.infura.io/v3/<apiKey>"));
    String contractAddress = "0xfaaFDc07907ff5120a76b34b731b278c38d6043C";
    BigInteger tokenId=new BigInteger("0x1800000000001289000000000000000000000000000000000000000000000000",16);
    NoOpProcessor processor = new NoOpProcessor(web3j);
    Credentials credentials = Credentials.create("privatekey");
    TransactionManager txManager = new FastRawTransactionManager(web3j, credentials, processor);
    //Query Blockchain to get balance of WALLETADDRESS from Contract for given TokenID
    ERC1155 token = ERC1155.load(contractAddress, web3j, txManager, DefaultGasProvider.GAS_PRICE, DefaultGasProvider.GAS_LIMIT);
    RemoteCall<BigInteger> sendCall = token.balanceOf(walletAddress, tokenId);
    BigInteger balance=sendCall.sendAsync().get();
    log.info("balance >>>>>>>> " +balance);
}

异常信息

java.lang.NumberFormatException: For input string: "0x1800000000001289000000000000000000000000000000000000000000000000"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Long.parseLong(Long.java:692)
at java.base/java.lang.Long.parseLong(Long.java:817)

问题分析

问题出在BigInteger的构造逻辑上:当我们指定第二个参数为16(表示按十六进制解析)时,BigInteger的构造器不识别0x前缀。此时字符串中的0x会被当作普通字符处理,但x并不是有效的十六进制字符,因此直接触发格式异常。

异常栈中出现Long.parseLong是因为Web3j内部在处理ERC1155的tokenId时存在类型转换逻辑,但根本原因还是初始的BigInteger构造错误。

解决方案

通过移除十六进制字符串的0x前缀后再解析,就能成功创建BigInteger对象。修复后的代码如下:

String tokenIdStr = "0x1800000000001289000000000000000000000000000000000000000000000000";
BigInteger tokenId;
if (tokenIdStr.startsWith("0x")) {
    // 移除0x前缀,按十六进制解析为BigInteger
    tokenId = new BigInteger(tokenIdStr.substring(2), 16);
} else {
    // 兼容不带前缀的十六进制字符串(可选)
    tokenId = new BigInteger(tokenIdStr, 16);
}

将这段代码替换原代码中BigInteger tokenId=new BigInteger(...)的部分,再调用balanceOf方法就可以正常获取余额了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:07:30