Web3J 是一个轻量级、高度模块化、反应式、类型安全的 Java 和 Android 库,用于处理智能合约并与以太坊网络上的客户端(节点)集成。这使您可以使用以太坊区块链,而无需为平台编写自己的集成代码的额外开销。
提供的功能
- 基于 HTTP 和 IPC 的以太坊 JSON-RPC 客户端 API 的完整实现
- 以太坊钱包支持
- 自动生成 Java 智能合约包装器,以从本机 Java 代码创建、部署、交易和调用智能合约(支持 Solidity 和 Truffle 定义格式)
- 以太坊名称服务 (ENS) 支持
- 支持 Alchemy 和 Infura,因此您不必自己运行以太坊客户端
- 安卓兼容
- 命令行工具
如何使用
1 2 3 4 5
| <dependency> <groupId>org.web3j</groupId> <artifactId>core</artifactId> <version>4.8.7</version> </dependency>
|
1 2 3 4 5 6 7 8
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { Web3j client = Web3j.build(new HttpService("https://ropsten.infura.io/v3/You Infura Project Id")); Web3ClientVersion clientVersion = client.web3ClientVersion().sendAsync().get(); System.out.println(clientVersion.getWeb3ClientVersion()); } }
|
使用 Web3J 获取以太坊账户余额
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { Web3j client = Web3j.build(new HttpService("https://ropsten.infura.io/v3/You Infura Project Id")); EthGetBalance ethGetBalance = client.ethGetBalance( "0x64f44b31ad0ed4537f94a5c084cfba8945463345", DefaultBlockParameterName.fromString(DefaultBlockParameterName.LATEST.name()) ).sendAsync().get(); System.out.println(ethGetBalance.getBalance()); } }
|
使用 Web3J 获取当前的 Gas 价格
1 2 3 4 5 6 7 8
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { Web3j client = Web3j.build(new HttpService("https://ropsten.infura.io/v3/You Infura Project Id")); EthGasPrice ethGasPrice = client.ethGasPrice().sendAsync().get(); System.out.println(ethGasPrice.getGasPrice()); } }
|
使用 Web3J 通过交易哈希获取交易详情
1 2 3 4 5 6 7 8 9 10
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { Web3j client = Web3j.build(new HttpService("https://ropsten.infura.io/v3/You Infura Project Id")); String transactionHash = "0x9030edd43f8ae6c4ed49bcbc11dd7d6f6ce2798e8bb1c5ea4f1e130780fec74a"; EthGetTransactionReceipt ethGetTransactionReceipt = client.ethGetTransactionReceipt(transactionHash).sendAsync().get(); TransactionReceipt transactionReceipt = ethGetTransactionReceipt.getTransactionReceipt().orElseThrow(RuntimeException::new); System.out.println(transactionReceipt); } }
|
使用 Web3J 订阅新的区块
Web3J 的函数式编程的特性让我们设置观察者很容易,我们可以设置订阅者,监听链上发生的一些事情,如出块,交易,日志等。
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException, ConnectException { WebSocketService webSocketService = new WebSocketService("wss://ropsten.infura.io/ws/v3/You Infura Project Id", true); webSocketService.connect(); Web3j client = Web3j.build(webSocketService); Disposable subscribe = client.replayPastBlocksFlowable(DefaultBlockParameterName.fromString("earliest"), true).subscribe(ethBlock -> { System.out.println(ethBlock.getBlock()); }); } }
|
使用 Web3J 订阅新的交易
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException, ConnectException { WebSocketService webSocketService = new WebSocketService("wss://ropsten.infura.io/ws/v3/You Infura Project Id", true); webSocketService.connect(); Web3j client = Web3j.build(webSocketService); Disposable subscribe = client.replayPastTransactionsFlowable(DefaultBlockParameterName.fromString("earliest")).subscribe(transaction -> { System.out.println(transaction); }); } }
|
使用 Web3J 订阅新的合约事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException, ConnectException { WebSocketService webSocketService = new WebSocketService("wss://ropsten.infura.io/ws/v3/You Infura Project Id", true); webSocketService.connect(); Web3j client = Web3j.build(webSocketService); Disposable subscribe = client.ethLogFlowable( new EthFilter( DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, "0x7b52aae43e962ce6a9a1b7e79f549582ae8bcff9" ) ).subscribe(event -> { System.out.println(event); }, Throwable::printStackTrace); } }
|
使用 Web3J 签名并发送交易
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException, ConnectException { Web3j client = Web3j.build(new HttpService("https://ropsten.infura.io/v3/You Infura Project Id"));
EthGetTransactionCount ethGetTransactionCount = client .ethGetTransactionCount("0x64f44b31ad0ed4537f94a5c084cfba8945463345", DefaultBlockParameterName.PENDING) .sendAsync().get(); BigInteger nonce = ethGetTransactionCount.getTransactionCount(); System.out.println(nonce);
RawTransaction etherTransaction = RawTransaction.createEtherTransaction( nonce, client.ethGasPrice().sendAsync().get().getGasPrice(), DefaultGasProvider.GAS_LIMIT, "0x64f44b31ad0ed4537f94a5c084cfba8945463345", Convert.toWei("0.001", Convert.Unit.ETHER).toBigInteger() ); System.out.println(etherTransaction);
Credentials credentials = Credentials.create("You Private Key");
byte[] signature = TransactionEncoder.signMessage(etherTransaction, credentials); String signatureHexValue = Numeric.toHexString(signature); EthSendTransaction ethSendTransaction = client.ethSendRawTransaction(signatureHexValue).sendAsync().get(); System.out.println(ethSendTransaction.getResult()); } }
|
使用 Web3J 生成合约包装类
Web3J 可以生成智能合约的包装类,方便使用纯 Java 代码与合约进行交互。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| $ web3j generate solidity -a ./contract.abi -o ./ -p com.contract.proxy _ _____ _ | | |____ (_) __ _____| |__ / /_ \ \ /\ / / _ \ '_ \ \ \ | \ V V / __/ |_) |.___/ / | \_/\_/ \___|_.__/ \____/| | _/ | |__/ by Web3Labs Generating com.contract.proxy.Contract ... Warning: Duplicate field(s) found: [FUNC_SAFETRANSFERFROM]. Please don't use names which will be the same in uppercase. File written to .
$ tree com com └── contract └── proxy └── Contract.java # 包装类
2 directories, 1 file
|
使用 Web3J 与合约进行交互
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { Web3j client = Web3j.build(new HttpService("https://ropsten.infura.io/v3/You Infura Project Id")); Credentials credentials = Credentials.create("You Private Key"); BigInteger currentGasPrice = client.ethGasPrice().sendAsync().get().getGasPrice(); Contract foundersKeyContract = Contract.load("0x7b52aae43e962ce6a9a1b7e79f549582ae8bcff9", client, credentials, new DefaultGasProvider() {
@Override public BigInteger getGasPrice() { return currentGasPrice; } }); BigInteger balance = foundersKeyContract.balanceOf("0x64f44b31ad0ed4537f94a5c084cfba8945463345").send(); System.out.println(balance); } }
|