使用 Web3j 连接以太坊私有链,从环境搭建到 Java 开发实战指南
在企业级区块链应用开发中,以太坊私有链(Private Chain)因其可控性、隐私性和免 gas 费用等优势,成为许多团队进行 DApp 开发测试的首选方案,而 Web3j 作为 Java 生态中最流行的以太坊交互库,让 Java 开发者能够以原生的方式与区块链进行交互,本文将完整介绍如何搭建以太坊私有链,并使用 Web3j 进行连接和开发。
什么是以太坊私有链?
以太坊私有链是由单个组织或机构控制的区块链网络,与公有链相比,它具有以下特点:
- 权限控制:只有授权的节点才能加入网络
- 性能更高:节点数量少,交易确认速度快
- 数据隐私:数据不对外公开,适合企业内部业务
- 零成本:无需消耗真实的以太币
- 完全可控:可自定义出块速度、gas 限制等参数
常见的应用场景包括:企业内部溯源系统、供应链金融、存证系统以及 DApp 的开发测试环境。
搭建以太坊私有链
1 安装 Geth
Geth 是以太坊官方的 Go 语言实现,是搭建私有链的核心工具。
# Ubuntu 安装 sudo apt-get install software-properties-common sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get update sudo apt-get install ethereum # 验证安装 geth version
2 创建创世区块配置文件
创建 genesis.json 文件:
{
"config": {
"chainId": 666,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"clique": {
"period": 5,
"epoch": 30000
}
},
"difficulty": "1",
"gasLimit": "8000000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": {
"balance": "300000000000000000000000000"
}
}
}
注意:
chainId必须是唯一的,避免与公有链或测试链冲突,这里使用 POA(Clique)共识机制,出块速度为 5 秒。
3 初始化并启动私有链
# 初始化创世区块 geth --datadir ./data init genesis.json # 启动节点,开启 RPC 服务 geth --datadir ./data \ --networkid 666 \ --http \ --http.addr "0.0.0.0" \ --http.port 8545 \ --http.api "eth,net,web3,personal,miner,admin,debug,txpool" \ --http.corsdomain "*" \ --allow-insecure-unlock \ --nodiscover \ console
4 创建账户并挖矿
在 Geth 控制台中执行:
// 创建新账户
personal.newAccount("123456")
// 解锁账户(私钥操作必需)
personal.unlockAccount(eth.accounts[0], "123456", 0)
// 启动挖矿
miner.start(1)
// 停止挖矿
miner.stop()
Web3j 快速入门
1 添加 Maven 依赖
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.10.3</version>
</dependency>
2 连接私有链
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
public class Web3jDemo {
public static void main(String[] args) {
// 连接私有链节点
Web3j web3j = Web3j.build(new HttpService("http://127.0.0.1:8545"));
// 测试连接
try {
Web3ClientVersion clientVersion = web3j.web3ClientVersion().send();
System.out.println("客户端版本: " + clientVersion.getWeb3ClientVersion());
EthBlockNumber blockNumber = web3j.ethBlockNumber().send();
System.out.println("当前区块高度: " + blockNumber.getBlockNumber());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Web3j 核心操作实战
1 查询账户余额
public static BigInteger getBalance(Web3j web3j, String address) throws Exception {
EthGetBalance balance = web3j.ethGetBalance(
address, DefaultBlockParameterName.LATEST).send();
// 将 Wei 转换为 Ether
BigDecimal ether = Convert.fromWei(
balance.getBalance().toString(), Convert.Unit.ETHER);
System.out.println("余额: " + ether + " ETH");
return balance.getBalance();
}
2 转账交易
public static String transfer(Web3j web3j, Credentials credentials,
String toAddress, BigDecimal amount) throws Exception {
// 获取 nonce
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
credentials.getAddress(), DefaultBlockParameterName.PENDING).send();
BigInteger nonce = ethGetTransactionCount.getTransactionCount();
// 手续费(EIP-1559)
BigInteger gasLimit = BigInteger.valueOf(21000);
BigInteger maxPriorityFeePerGas = Convert.toWei("2", Convert.Unit.GWEI).toBigInteger();
BigInteger maxFeePerGas = Convert.toWei("50", Convert.Unit.GWEI).toBigInteger();
// 构建交易
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
chainId, nonce, gasLimit,
toAddress, Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger());
// 签名并发送
byte[] signedMessage = TransactionEncoder.signMessage(
rawTransaction, chainId, credentials);
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction response = web3j.ethSendRawTransaction(hexValue).send();
if (response.hasError()) {
throw new RuntimeException("转账失败: " + response.getError().getMessage());
}
return response.getTransactionHash();
}
3 部署与调用智能合约
首先编写一个简单的智能合约:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Storage {
uint256 private storedData;
event DataStored(uint256 newValue);
function set(uint256 x) public {
storedData = x;
emit DataStored(x);
}
function get() public view returns (uint256) {
return storedData;
}
}
使用 Web3j 命令行工具生成 Java 包装类:
web3j generate generate \ -a ./build/contracts/Storage.abi \ -b ./build/contracts/Storage.bin \ -o ./src/main/java \ -p com.example.contracts
在 Java 中部署和调用:
// 部署合约
Credentials credentials = Credentials.create(privateKey);
Storage contract = Storage.deploy(
web3j, credentials,
new StaticGasProvider(
Convert.toWei("20", Convert.Unit.GWEI).toBigInteger(),
BigInteger.valueOf(3000000)))
.send();
System.out.println("合约地址: " + contract The End
发布于:2026-10-11,除非注明,否则均为原创文章,转载请注明出处。
