使用 Web3j 连接以太坊私有链,从环境搭建到 Java 开发实战指南

博主:neragonerago 2026-10-11 15:23:23 2

在企业级区块链应用开发中,以太坊私有链(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,除非注明,否则均为区块链社区- 欧亿APP下载原创文章,转载请注明出处。