Java实现以太坊开发实战,使用Web3j构建区块链应用完整指南
2026.10.22 23:28:42 2 0
随着区块链技术的蓬勃发展,以太坊作为最流行的智能合约平台,吸引了大量开发者,虽然以太坊生态以JavaScript为主流开发语言,但Java作为企业级开发的中坚力量,在区块链领域同样有着强大的支持,本文将详细介绍如何使用Java与以太坊进行交互,涵盖账户管理、转账交易、智能合约调用等核心功能。
技术选型:Web3j简介
Web3j 是一个轻量级的Java库,专门用于与以太坊区块链交互,它具有以下特点:
- 无需编写原生以太坊节点代码,通过JSON-RPC API与节点通信
- 支持Java 8及以上版本
- 提供完整的以太坊功能支持:交易、智能合约、钱包管理等
- 支持响应式编程(RxJava)
- 可以自动生成智能合约的Java包装类
环境准备
1 添加Maven依赖
在项目的 pom.xml 中添加以下依赖:
<dependencies>
<!-- Web3j 核心依赖 -->
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.10.3</version>
</dependency>
</dependencies>
如果使用Gradle,则添加:
implementation 'org.web3j:core:4.10.3'
2 以太坊节点准备
与以太坊交互需要一个节点,常见的选择有:
- 自建节点:Geth或OpenEthereum(适合测试)
- 测试网络:Sepolia、Goerli等测试链的公共节点
- 第三方服务:Infura、Alchemy等提供的节点服务(推荐生产使用)
本文以Infura为例,注册后可获得一个API地址,格式如:
https://sepolia.infura.io/v3/你的项目ID
连接以太坊网络
我们创建与以太坊节点的连接:
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
import java.io.IOException;
public class EthereumConnector {
public static Web3j connect() {
// 连接到Infura节点
String rpcUrl = "https://sepolia.infura.io/v3/你的项目ID";
Web3j web3j = Web3j.build(new HttpService(rpcUrl));
return web3j;
}
public static void main(String[] args) throws IOException {
Web3j web3j = connect();
// 查询当前区块高度
var blockNumber = web3j.ethBlockNumber().send();
System.out.println("当前区块高度: " + blockNumber.getBlockNumber());
// 查询客户端版本
var clientVersion = web3j.web3ClientVersion().send();
System.out.println("客户端版本: " + clientVersion.getWeb3ClientVersion());
}
}
运行成功后,控制台将输出当前连接的区块高度,说明连接成功。
创建以太坊钱包
1 生成新钱包
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Keys;
import org.web3j.crypto.Wallet;
import org.web3j.crypto.Credentials;
public class WalletCreator {
public static void main(String[] args) throws Exception {
// 生成椭圆曲线密钥对
ECKeyPair keyPair = Keys.createEcKeyPair();
// 获取私钥和公钥
String privateKey = keyPair.getPrivateKey().toString(16);
String publicKey = keyPair.getPublicKey().toString(16);
// 生成以太坊地址
String address = "0x" + Keys.getAddress(keyPair);
System.out.println("私钥: " + privateKey);
System.out.println("公钥: " + publicKey);
System.out.println("地址: " + address);
// 通过私钥加载凭证(后续交易签名使用)
Credentials credentials = Credentials.create(privateKey);
System.out.println("凭证地址: " + credentials.getAddress());
}
}
⚠️ 安全提示:私钥是资产的唯一控制凭证,务必妥善保管,切勿硬编码在代码中或提交到版本控制系统。
2 创建 keystore 钱包文件
import org.web3j.crypto.WalletUtils;
import java.io.File;
public class KeystoreCreator {
public static void main(String[] args) throws Exception {
String password = "你的钱包密码";
String directory = "./wallet";
// 生成keystore文件
String fileName = WalletUtils.generateNewWalletFile(
password, new File(directory), true);
System.out.println("钱包文件: " + fileName);
// 从keystore文件加载凭证
Credentials credentials = WalletUtils.loadCredentials(
password, directory + "/" + fileName);
System.out.println("钱包地址: " + credentials.getAddress());
}
}
查询账户余额
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.utils.Convert;
import java.math.BigDecimal;
import java.math.BigInteger;
public class BalanceChecker {
public static BigDecimal getBalance(Web3j web3j, String address) throws Exception {
// 查询地址余额(单位:wei)
var balance = web3j.ethGetBalance(
address,
DefaultBlockParameterName.LATEST
).send();
BigInteger wei = balance.getBalance();
// 将wei转换为ether(1 ether = 10^18 wei)
return Convert.fromWei(wei.toString(), Convert.Unit.ETHER);
}
public static void main(String[] args) throws Exception {
Web3j web3j = EthereumConnector.connect();
String address = "0x某个以太坊地址";
BigDecimal balance = getBalance(web3j, address);
System.out.println("余额: " + balance + " ETH");
}
}
实现ETH转账交易
转账是以太坊最基础的操作,完整流程包括:构建交易 → 估算Gas → 签名 → 广播:
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
import java.math.BigInteger;
public class EthTransfer {
public static String transfer(Web3j web3j, Credentials credentials,
String toAddress, String amountInEther) throws Exception {
// 1. 获取 nonce(交易序号,防止重放攻击)
BigInteger nonce = web3j.ethGetTransactionCount(
credentials.getAddress(),
DefaultBlockParameterName.PENDING
).send().getTransactionCount();
// 2. 获取Gas价格建议
BigInteger gasPrice = web3j.ethGasPrice().send().getGasPrice();
// 3. 设置转账金额(ether转wei)
BigInteger value = Convert.toWei(amountInEther, Convert.Unit.ETHER).toBigInteger();
// 4. 转账交易的Gas本文转载自互联网,如有侵权,联系删除
