1. 概述
加密货币是一种安全且去中心化的价值存储方式。它采用点对点(P2P)网络进行交易传播和验证。
BitcoinJ 是一个 Java 库,能简化比特币应用的开发,让用户无缝执行加密货币交易。
本教程将深入探讨 BitcoinJ 的核心功能和组件,并演示如何创建钱包、充值钱包以及向其他钱包转账。
2. 什么是 BitcoinJ?
BitcoinJ 是一个简化比特币应用开发的 Java 库。它提供创建和管理比特币钱包、收发交易的工具,并支持与比特币主网(mainnet)、测试网(testnet)和回归测试网(regtest)的集成。
此外,它提供简化支付验证(SPV)功能,无需下载完整区块链即可与比特币网络交互。
3. BitcoinJ 的核心功能
✅ 钱包管理:轻松创建比特币钱包,包括生成地址、管理公私钥和处理助记词恢复
✅ 交易处理:支持比特币交易的发送和接收
✅ 网络集成:支持比特币主网(真实交易)、测试网和回归测试网(测试环境)
✅ 事件监听:通过事件监听器响应交易到账或区块链变更等事件
4. 基础配置
在 pom.xml 中添加 bitcoinj-core 依赖:
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>
<version>0.17-alpha4</version>
</dependency>
添加日志依赖 slf4j-api 和 slf4j-simple:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.1.0-alpha1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.1.0-alpha1</version>
</dependency>
5. Wallet 类详解
钱包是加密货币的核心组件,BitcoinJ 通过 Wallet 和 WalletKitApp 类实现钱包管理。
5.1 创建钱包
创建钱包前需指定网络类型:主网(生产环境)、测试网(测试环境)或回归测试网(本地测试)。
NetworkParameters params = TestNet3Params.get();
创建 Wallet 实例:
void createWallet() throws IOException {
Wallet wallet = Wallet.createDeterministic(params, Script.ScriptType.P2PKH);
File walletFile = new File("baeldung.dat");
wallet.saveToFile(walletFile);
}
⚠️ 关键点:
- 使用 P2PKH 脚本类型(Pay-to-Pubkey-Hash 地址,比特币常用地址类型)
- 创建时自动生成地址、助记词、公私钥
- 钱包保存为 baeldung.dat 文件
5.2 获取钱包信息
创建后可获取地址、公私钥、助记词等核心信息:
Wallet loadWallet() throws IOException, UnreadableWalletException {
File walletFile = new File("baeldung.dat");
Wallet wallet = Wallet.loadFromFile(walletFile);
logger.info("地址: " + wallet.currentReceiveAddress().toString());
logger.info("助记词: " + wallet.getKeyChainSeed().getMnemonicString());
logger.info("余额: " + wallet.getBalance().toFriendlyString());
logger.info("公钥: " + wallet.findKeyFromAddress(wallet.currentReceiveAddress()).getPublicKeyAsHex());
logger.info("私钥: " + wallet.findKeyFromAddress(wallet.currentReceiveAddress()).getPrivateKeyAsHex());
return wallet;
}
5.3 恢复钱包
丢失钱包文件但保留助记词时,可通过助记词恢复钱包:
Wallet loadUsingSeed(String seedWord) throws UnreadableWalletException {
DeterministicSeed seed = new DeterministicSeed(seedWord, null, "", Utils.currentTimeSeconds());
return Wallet.fromSeed(params, seed);
}
5.4 钱包加密
❌ 安全警告:私钥和助记词泄露 = 资产被盗!使用 encrypt() 加密钱包:
// 加密钱包
wallet.encrypt("your_strong_password");
wallet.saveToFile(walletFile);
// 解密钱包
Wallet wallet = Wallet.loadFromFile(walletFile);
wallet.decrypt("your_strong_password");
5.5 连接对等网络
孤立钱包无法同步交易,需连接对等网络:
void connectWalletToPeer() throws BlockStoreException, UnreadableWalletException, IOException {
Wallet wallet = loadWallet();
BlockStore blockStore = new MemoryBlockStore(params);
BlockChain chain = new BlockChain(params, wallet, blockStore);
PeerGroup peerGroup = new PeerGroup(params, chain);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));
peerGroup.addWallet(wallet);
peerGroup.start();
peerGroup.downloadBlockChain();
}
⚠️ 性能提示:完整区块链下载资源消耗大,WalletKitApp 默认使用 SPV 模式优化此过程。
6. WalletKitApp 类详解
WalletKitApp 类简化了钱包设置流程,自动处理 BlockStore、BlockChain 和 PeerGroup 的创建。
NetworkParameters params = TestNet3Params.get();
WalletAppKit kit = new WalletAppKit(params, new File("."), "baeldungkit") {
@Override
protected void onSetupCompleted() {
logger.info("钱包创建加载成功");
logger.info("接收地址: " + wallet().currentReceiveAddress());
logger.info("助记词: " + wallet().getKeyChainSeed());
logger.info("余额: " + wallet().getBalance().toFriendlyString());
logger.info("公钥: " + wallet().findKeyFromAddress(wallet().currentReceiveAddress())
.getPublicKeyAsHex());
logger.info("私钥: " + wallet().findKeyFromAddress(wallet().currentReceiveAddress())
.getPrivateKeyAsHex());
wallet().encrypt("password");
}
};
kit.startAsync();
kit.awaitRunning();
kit.setAutoSave(true);
输出示例:
[ STARTING] INFO com.baeldung.bitcoinj.Kit - 钱包创建加载成功
[ STARTING] INFO com.baeldung.bitcoinj.Kit - 接收地址: moqVLcdRFjyXehgRAK5bJBK6rDN2vq14Wc
[ STARTING] INFO com.baeldung.bitcoinj.Kit - 助记词: DeterministicSeed{unencrypted}
[ STARTING] INFO com.baeldung.bitcoinj.Kit - 余额: 0
6.1 添加事件监听器
监听交易到账事件:
kit.wallet()
.addCoinsReceivedEventListener((wallet, tx, prevBalance, newBalance) -> {
logger.info("收到交易: " + tx.getValueSentToMe(wallet));
logger.info("新余额: " + newBalance.toFriendlyString());
});
监听转账事件:
kit.wallet()
.addCoinsSentEventListener((wallet, tx, prevBalance, newBalance) ->
logger.info("转账后余额: " + newBalance.toFriendlyString())
);
6.2 接收比特币
通过比特币测试网水龙头获取测试币:
在 BlockCypher 验证交易:
重启程序查看余额更新:
6.3 发送比特币
创建 Coin 实例指定转账金额(单位:聪):
String receiveAddress = "n1vb1YZXyMQxvEjkc53VULi5KTiRtcAA9G";
Coin value = Coin.valueOf(200); // 200 聪
final Coin amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
final Wallet.SendResult sendResult = kit.wallet()
.sendCoins(kit.peerGroup(), Address.fromString(params, receiveAddress), amountToSend);
⚠️ 注意:转账金额需扣除矿工费(REFERENCE_DEFAULT_MIN_TX_FEE)。
7. 总结
本文通过比特币测试网演示了 BitcoinJ 的核心用法,涵盖:
- 钱包创建/恢复/加密
- 交易收发
- 网络同步
- 事件监听
完整源码见 GitHub。