:2026-02-20 9:15 点击:1
在区块链应用开发中,经常需要查询以太坊地址中持有的代币数量,本文将详细介绍如何使用Java语言实现以太坊地址币数量的检验功能,包括环境搭建、核心代码实现和常见问题解决方案。
在开始之前,我们需要准备以下技术栈:
在项目中添加Web3j依赖(Maven配置):
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.9.8</version>
</dependency>
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
public class EthereumConnector {
private Web3j web3j;
public EthereumConnector(String nodeUrl) {
this.web3j = Web3j.build(new HttpService(nodeUrl));
}
public Web3j getWeb3j() {
return web3j;
}
}
import org.web3j.protocol.core.methods.response.EthGetBalance;
import java.io.IOException;
import java.math.BigInteger;
public class EthBalanceChecker {
public static BigInteger getEthBalance(Web3j web3j, String address) throws IOException {
EthGetBalance ethGetBalance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST)
.send();
return ethGetBalance.getBalance();
}
public static void main(String[] args) {
String nodeUrl = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID";
String ethAddress = "0x742d35Cc6634C0532925a3b844Bc9e7595f8e9e9";
EthereumConnector connector = new EthereumConnector(nodeUrl);
try {
BigInteger balance = getEthBalance(connector.getWeb3j(), ethAddress);
System.out.println("ETH Balance: " + balance.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
要查询ERC20代币余额,我们需要与代币合约进行交互。
使用Web3j的代码生成功能生成Java合约包装类:
web3j generate solidity -a Token.sol -o ./src/main/java -p com.example.contracts
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import java.math.BigDecimal;
import java.math.BigInteger;
public class TokenBalanceChecker {
public static BigDecimal getTokenBalance(Web3j web3j, String tokenContractAddress,
String userAddress, int decimals) throws Exception {
// 加载代币合约
Token token = Token.load(tokenContractAddress, web3j,
new Credentials("YOUR_PRIVATE_KEY"),
Contract.GAS_PRICE, Contract.GAS_LIMIT);
// 调用balanceOf方法
BigInteger balance = token.balanceOf(userAddress).send();
// 根据精度转换
BigDecimal tokenBalance = new BigDecimal(balance).divide(
new BigDecimal(Math.pow(10, decimals)),
decimals,
BigDecimal.ROUND_DOWN
);
return tokenBalance;
}
public static void main(String[] args) {
String nodeUrl = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID";
String tokenAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7"; // USDT合约地址
String userAddress = "0x742d35Cc6634C0532925a3b844Bc9e7595f8e9e9";
int decimals = 6; // USDT精度
EthereumConnector connector = new EthereumConnector(nodeUrl);
try {
BigDecimal balance = getTokenBalance(connector.getWeb3j(), tokenAddress, userAddress, decimals);
System.out.println("Token Balance: " + balance.toPlainString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
为了使代码更加健壮,我们可以添加异常处理和参数验证:
import org.web3j.utils.Convert;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.regex.Pattern;
public class EthereumBalanceService {
private static final Pattern ETHEREUM_ADDRESS_PATTERN = Pattern.compile("^0x[0-9a-fA-F]{40}$");
public static BigDecimal getEthBalanceInEth(Web3j web3j, String address) throws InvalidAddressException, IOException {
if (!isValidEthereumAddress(address)) {
throw new InvalidAddressException("Invalid Ethereum address: " + address);
}
BigInteger balance = EthBalanceChecker.getEthBalance(web3j, address);
return Convert.fromWei(new BigDecimal(balance), Convert.Unit.ETH);
}
public static BigDecimal getTokenBalance(Web3j web3j, String tokenContractAddress,
String userAddress, int decimals)
throws InvalidAddressException, ContractCallException {
if (!isValidEthereumAddress(tokenContractAddress) || !isValidEthereumAddress(userAddress)) {
throw new InvalidAddressException("Invalid address provided");
}
try {
return TokenBalanceChecker.getTokenBalance(web3j, tokenContractAddress, userAddress, decimals);
} catch (Exception e) {
throw new ContractCallException("Failed to get token balance: " + e.getMessage(), e);
}
}
public static boole
an isValidEthereumAddress(String address) {
return ETHEREUM_ADDRESS_PATTERN.matcher(address).matches();
}
// 自定义异常类
public static class InvalidAddressException extends Exception {
public InvalidAddressException(String message) {
super(message);
}
}
public static class ContractCallException extends Exception {
public ContractCallException(String message, Throwable cause) {
super(message, cause);
}
}
}
public class Main {
public static void main(String[] args) {
String nodeUrl = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID";
String ethAddress = "0x742d35Cc6634C0532925a3b844Bc9e7595f8e9e9";
String usdtAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
EthereumConnector connector = new EthereumConnector(nodeUrl);
try {
// 查询ETH余额
BigDecimal ethBalance = EthereumBalanceService.getEthBalanceInEth(
connector.getWeb3j(), ethAddress);
System.out.println("ETH Balance: " + ethBalance + " ETH");
// 查询USDT余额
BigDecimal usdtBalance = EthereumBalanceService.getTokenBalance(
connector.getWeb3j(), usdtAddress, ethAddress, 6);
System.out.println("USDT Balance: " + usdtBalance);
} catch (EthereumBalanceService.InvalidAddressException |
EthereumBalanceService.ContractCallException | IOException e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
本文详细介绍了如何使用Java和Web3j库实现以太坊地址ETH和ERC20代币余额的查询功能,通过封装和异常处理,我们可以构建健壮的区块链交互服务,随着区块链技术的发展,类似的查询功能在DeFi、NFT等应用场景中将发挥越来越重要的作用,开发者可以根据实际需求进一步扩展功能,如添加多地址批量查询、历史余额查询等高级特性。
本文由用户投稿上传,若侵权请提供版权资料并联系删除!