/ 币圈行情

Java以太坊钱包开发,从入门到实践

发布时间:2026-03-24 05:43:53

以太坊作为全球第二大区块链平台,其原生代币ETH和智能合约功能催生了丰富的应用场景,而钱包作为管理数字资产、与区块链交互的核心工具,成为开发者的必备技能,Java凭借其跨平台性、稳定性和庞大的生态,在金融和企业级应用中占据重要地位,因此使用Java开发以太坊钱包兼具实用性与学习价值,本文将从技术基础、核心功能实现、开发步骤及注意事项四个维度,系统介绍Java以太坊钱包的开发流程。

Java以太坊钱包开发的技术基础

在动手开发前,需先掌握以下核心技术基础,这些是构建钱包的“基石”。

以太坊核心概念

  • 账户模型:以太坊采用“账户”而非“UTXO”模型,分为外部账户(EOA,由公私钥控制)和合约账户(由代码控制),钱包主要管理外部账户,包括地址、余额、 nonce等属性。
  • 公私钥体系:基于椭圆曲线加密(ECDSA,secp256k1曲线),私钥生成公钥,公钥通过Keccak-256哈希生成地址,私钥是资产控制的核心,需严格保密。
  • 交易结构:以太坊交易包含发送方地址、接收方地址、转账金额、nonce、gasLimit、gasPrice、数据字段等,需通过私钥签名后广播到网络。

Java开发环境与工具

  • JDK:推荐JDK 11或更高版本,确保支持最新的语言特性和安全性。
  • 以太坊Java库:主流选择包括Web3j(轻量级、与以太坊JSON-RPC API集成)、Nethereum(功能全面,支持.NET和Java生态),本文以Web3j为例,其简化了与以太坊节点的交互。
  • 构建工具:Maven或Gradle,用于管理项目依赖(如Web3j核心库、加密库等)。

关键依赖库

以Maven为例,核心依赖如下:

<dependencies>
    <!-- Web3j核心库 -->
    <dependency>
        <groupId>org.web3j</groupId>
        <artifactId>core</artifactId>
        <version>4.9.8</version>
    </dependency>
    <!-- 以太坊加密工具(Bouncy Castle) -->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.70</version>
    </dependency>
    <!-- JSON处理(Gson) -->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.10.1</version>
    </dependency>
</dependencies>

Java以太坊钱包核心功能实现

钱包的核心功能包括密钥管理交易签名与发送余额查询地址生成等,下面结合代码逐一实现。

以太坊地址与密钥生成

以太坊地址从私钥推导而来,流程为:私钥 → 公钥(未压缩) → 地址(Keccak-256哈希取后20字节),Web3j提供了Credentials类封装密钥与地址的生成逻辑:

import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Keys;
import org.web3j.crypto.WalletUtils;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
public class WalletGenerator {
    public static void main(String[] args) 
            throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException {
        // 1. 随机生成EC密钥对
        ECKeyPair keyPair = Keys.createEcKeyPair();
        // 2. 从密钥对获取凭证(包含地址与私钥)
        Credentials credentials = Credentials.create(keyPair);
        // 3. 输出地址与私钥
        System.out.println("地址: "   credentials.getAddress());
        System.out.println("私钥: "   keyPair.getPrivateKey().toString(16));
        // 4. 可选:生成加密钱包文件(推荐,避免明文存储私钥)
        String walletFile = WalletUtils.generateWalletFile("password", keyPair, WalletUtils.getDefaultDirectory());
        System.out.println("钱包文件路径: "   walletFile);
    }
}

运行结果示例:

地址: 0x742d35Cc6634C0532925a3b844Bc9e7595f8dDe2  
私钥: 8da4ef21b864d2cc526dbdb2a120bd2874c36c9d0a1fb7f8c63d7f7a8b41de8f  

注意:实际开发中需通过WalletUtils.generateWalletFile生成加密钱包文件(JSON格式,包含密钥的加密信息),避免私钥明文存储。

连接以太坊节点

钱包需与以太坊网络交互,可通过连接本地节点(如Geth、Parity)或公共节点(如Infura、Alchemy)实现,Web3j通过Web3j类建立连接:

import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
import java.io.IOException;
public class NodeConnector {
    public static void main(String[] args) throws IOException {
        // 连接本地节点(默认端口8545)
        Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
        // 连接Infura公共节点(需替换为你的项目ID)
        // Web3j web3j = Web3j.build(new HttpService("https://mainnet.infura.io/v3/YOUR_PROJECT_ID"));
        // 检查连接是否成功
        String clientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
        System.out.println("节点版本: "   clientVersion);
        // 关闭连接
        web3j.shutdown();
    }
}

查询账户余额

通过eth_getBalance RPC接口查询指定地址的ETH余额,单位为“wei”(1 ETH = 10^18 wei):

import org.web3j.protocol.core.methods.response.EthGetBalance;
import java.io.IOException;
import java.math.BigInteger;
public class BalanceChecker {
    public static void main(String[] args) throws IOException {
        Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
        String address = "0x742d35Cc6634C0532925a3b844Bc9e7595f8dDe2"; // 替换为目标地址
        EthGetBalance balance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send();
        BigInteger balanceWei = balance.getBalance();
        // 转换为ETH(保留18位小数)
        double balanceEth = balanceWei.doubleValue() / Math.pow(10, 18);
        System.out.println("地址 "   address   " 的余额: "   balanceEth   " ETH");
        web3j.shutdown();
    }
}

发送ETH交易

发送交易需经历构建交易签名广播三个步骤,Web3j的Transfer工具类简化了这一过程:

import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
public class TransactionSender {
    public static void main(String[] args) 
            throws IOException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException {
        // 1. 初始化Web3j与凭证(从加密钱包文件加载)
        Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
        String walletFilePath = "path/to/wallet.json"; // 钱包文件路径
        String password = "your_password"; // 钱包密码
        Credentials credentials = WalletUtils.loadCredentials(password, walletFilePath);
        // 2. 构建交易参数
        String toAddress = "0xRecipientAddressHere"; // 接收方地址
        BigInteger value = Convert.toWei("0.1", Convert.Unit.ETH).toBigInteger(); // 转账金额(0.1 ETH)
        BigInteger gasLimit = BigInteger.valueOf(21000); // 标准转账

免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

如有疑问请发送邮件至:bangqikeconnect@gmail.com