web3j 是一个轻量级、高度模块化、响应式、类型安全的 Java 和 Android 类库提供丰富 API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成。
可以通过它进行以太坊区块链的开发,而无需为你的 java 应用平台编写集成代码。
想要快速启动的话,有一个Web3j demo 示例项目可用,演示了通过 Web3j 开发以太坊的许多核心特征,其中包括:
首先将最新版本的 web3j 安装到项目中。
Java 8:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.4.0</version>
</dependency>
Android:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.3.1-android</version>
</dependency>
Java 8:
compile ('org.web3j:core:3.4.0')
Android:
compile ('org.web3j:core:3.3.1-android')
需要启动一个以太坊客户端,当然如果你已经启动了就不需要再次启动。
如果是geth的话这么启动:
$ geth --rpcapi personal,db,eth,net,web3 --rpc --rinkeby
如果是Parity启动:
$ parity --chain testnet
如果使用Infura客户端提供的免费的云端服务,这么启动:
Web3j web3 = Web3j.build(new HttpService("https://morden.infura.io/your-token"));
如果想进一步的了解 infura,请参阅Using Infura with web3j。
在网络上如何获得以太币的相关文档可以看这个:testnet section of the docs。
当不需要 Web3j 实例时,需要调用shutdown
方法来释放它所使用的资源。
web3.shutdown()
发送同步请求
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().send();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
** 使用 CompletableFuture (Future on Android) 发送异步请求**
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().sendAsync().get();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
*使用 RxJava 的 Observable
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
web3.web3ClientVersion().observable().subscribe(x -> {
String clientVersion = x.getWeb3ClientVersion();
...
});
注意 Android 使用方式
Web3j web3 = Web3jFactory.build(new HttpService()); // defaults to http://localhost:8545/
...
Web3j 还支持通过文件套接字快速运行进程间通信( IPC ),支持客户端在相同的主机上同时运行 Web3j。在创建服务时,使用相关的IPCService
就可以实现而不需要通过HTTPService
。
// OS X/Linux/Unix:
Web3j web3 = Web3j.build(new UnixIpcService("/path/to/socketfile"));
...
// Windows
Web3j web3 = Web3j.build(new WindowsIpcService("/path/to/namedpipefile"));
...
需要注意:IPC 通信在 web3j-android 中不可用。
Web3j 可以自动打包智能合同代码,以便在不脱离 JVM 的情况下进行以太坊智能合同部署和交互。
要打包代码,需要先编译智能合同:
$ solc <contract>.sol --bin --abi --optimize -o <output-dir>/
然后用web3j 的命令行工具打包代码:
web3j solidity generate /path/to/<smart-contract>.bin /path/to/<smart-contract>.abi -o /path/to/src/main/java -p com.your.organisation.name
接下来就可以新建和部署智能合约了:
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile");
YourSmartContract contract = YourSmartContract.deploy(
<web3j>, <credentials>,
GAS_PRICE, GAS_LIMIT,
<param1>, ..., <paramN>).send(); // constructor params
或者使用一个现有的智能合约:
YourSmartContract contract = YourSmartContract.load(
"0x<address>|<ensName>", <web3j>, <credentials>, GAS_PRICE, GAS_LIMIT);
然后就可以进行智能合约的交互了:
TransactionReceipt transactionReceipt = contract.someMethod(
<param1>,
...).send();
调用智能合约:
Type result = contract.someMethod(<param1>, ...).send();
更多关于打包的资料可以看这里:Solidity smart contract wrappers
web3j 的响应式函数可以使观察者通过事件去通知消息订阅者变得很简单,并能够记录在区块链中。接收所有新的区块并把它们添加到区块链中:
Subscription subscription = web3j.blockObservable(false).subscribe(block -> {
...
});
接收所有新的交易并把它们添加到区块链中:
Subscription subscription = web3j.transactionObservable().subscribe(tx -> {
...
});
接收所有已经提交到网络中等待处理的交易。(他们被统一的分配到一个区块之前。)
Subscription subscription = web3j.pendingTransactionObservable().subscribe(tx -> {
...
});
或者你重置所有的区块到最新的位置,那么当有新建区块的时候会通知你。
Subscription subscription = catchUpToLatestAndSubscribeToNewBlocksObservable(
<startBlockNumber>, <fullTxObjects>)
.subscribe(block -> {
...
});
主题过滤也被支持:
EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST,
DefaultBlockParameterName.LATEST, <contract-address>)
.addSingleTopic(...)|.addOptionalTopics(..., ...)|...;
web3j.ethLogObservable(filter).subscribe(log -> {
...
});
当不再需要时,订阅也应该被取消:
subscription.unsubscribe();
**注意:Infura 中不支持 filters。 **
需要了解更多有关过滤器和事件的信息可以查看Filters and Events和Web3jRx的接口。
Web3j 支持使用以太坊钱包文件(推荐的)和用于发送事务的以太坊客户端管理命令。
使用以太钱包文件发送以太币给其他人:
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile");
TransactionReceipt transactionReceipt = Transfer.sendFunds(
web3, credentials, "0x<address>|<ensName>",
BigDecimal.valueOf(1.0), Convert.Unit.ETHER)
.send();
或者你希望建立你自己定制的交易:
Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/
Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile");
// get the next available nonce
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
address, DefaultBlockParameterName.LATEST).send();
BigInteger nonce = ethGetTransactionCount.getTransactionCount();
// create our transaction
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
nonce, <gas price>, <gas limit>, <toAddress>, <value>);
// sign & send our transaction
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
// ...
使用 Web3j 的Transfer进行以太币交易要简单得多。
使用以太坊客户端的管理命令(如果你的钱包密钥已经在客户端存储):
Admin web3j = Admin.build(new HttpService()); // defaults to http://localhost:8545/
PersonalUnlockAccount personalUnlockAccount = web3j.personalUnlockAccount("0x000...", "a password").sendAsync().get();
if (personalUnlockAccount.accountUnlocked()) {
// send a transaction
}
如果你想使用 Parity ’ s Personal 或者 Trace 功能, 或者 Geth ’ s Personal 客户端 APIs,可以使用org.web3j:parity
和org.web3j:geth
模块。
web3j 的 jar 包为每一个版本都提供命令行工具。命令行工具允许你直接通过一些命令使用 web3j 的一些功能:
请参阅文档以获得命令行相关的进一步的信息。
java8 bulid:
在 java 8 的 Android 版本:
Response.getResult()
获取字符串类型的数量结果。includeRawResponse
参数将原生的 JSON 包放置在响应中。原文请访问:web3js开发以太坊智能合约快速入门
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.