以太坊作为全球第二大区块链平台,不仅仅是一种加密货币,更是一个强大的去中心化应用(DApp)开发平台,它允许开发者构建和部署智能合约,创建各种复杂的去中心化金融(DeFi)、非同质化代币(NFT)、游戏等应用,虽然Solidity是以太坊智能合约最主流的编程语言,但对于Java开发者而言,使用Java与以太坊交互同样便捷且强大,本文将带你走进Java以太坊开发的世界,从环境搭建到与以太坊网络交互,再到部署和调用智能合约,一步步开启你的DApp开发之旅。
在开始之前,你需要准备以下环境:
JAVA_HOME环境变量配置正确。Web3j是一个轻量级的、响应式的Java库,用于与以太坊客户端(如Geth, Parity)进行交互,它提供了丰富的API,支持:
在IDE中创建一个新的Maven项目。


在pom.xml文件中添加Web3j依赖:
<dependencies>
<!-- Web3j Core -->
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>4.9.8</version> <!-- 请使用最新版本 -->
</dependency>
<!-- 其他可选依赖,如用于单元测试的JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies> 点击“Reload Maven Project”使依赖生效。
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
import java.io.IOException;
public class EthereumConnection {
public static void main(String[] args) {
// 替换为你的Infura节点URL或本地节点URL
String nodeUrl = "https://sepolia.infura.io/v3/YOUR_INFURA_PROJECT_ID";
// 创建Web3j实例
Web3j web3j = Web3j.build(new HttpService(nodeUrl));
try {
// 检查连接是否成功
String clientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
System.out.println("成功连接到以太坊节点,客户端版本: " clientVersion);
// 关闭连接
web3j.shutdown();
} catch (IOException e) {
System.err.println("连接以太坊节点失败: " e.getMessage());
e.printStackTrace();
}
}
}
运行上述代码,如果成功打印出客户端版本,则表示连接成功。

假设你有一个测试账户地址,可以使用Web3j获取其ETH余额。
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Unit;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
public class AccountBalance {
public static void main(String[] args) {
String nodeUrl = "https://sepolia.infura.io/v3/YOUR_INFURA_PROJECT_ID";
Web3j web3j = Web3j.build(new HttpService(nodeUrl));
// 替换为你要查询的以太坊地址
String address = "0xYourTestAddressHere";
try {
// 获取账户余额,单位是Wei (1 ETH = 10^18 Wei)
BigInteger balanceWei = web3j.ethGetBalance(address, org.web3j.protocol.core.DefaultBlockParameterName.LATEST)
.send()
.getBalance();
// 将Wei转换为ETH
BigDecimal balanceEth = Convert.fromWei(new BigDecimal(balanceWei), Unit.ETH);
System.out.println("地址: " address);
System.out.println("余额: " balanceEth.toPlainString() " ETH");
web3j.shutdown();
} catch (IOException e) {
System.err.println("获取账户余额失败: " e.getMessage());
e.printStackTrace();
}
}
}
你需要一个简单的Solidity智能合约,一个简单的存储和获取数字的合约SimpleStorage.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}
步骤1:编译智能合约
假设你已经编译得到了ABI(一个JSON数组)和Bytecode(一个十六进制字符串)。
步骤2:使用Web3j部署合约
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.Utf8String;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Contract;
import org.web3j.tx.ManagedTransaction;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
public class DeployContract {
public static void main(String[] args) {
String nodeUrl = "https://sepolia.infura.io/v3/YOUR_INFURA_PROJECT_ID";
Web3j web3j = Web3j.build(new HttpService(nodeUrl));
// 替换为你的部署账户私钥(仅用于测试,生产环境请妥善保管私钥!)
String privateKey = "YOUR_PRIVATE_KEY_HERE";
// 替换为你的合约部署账户地址
String deployerAddress = "0xYourDeployerAddressHere";
// 合约ABI (这里简化,实际应从编译结果获取完整的JSON字符串)
String abi = "[{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"