web3j開發以太坊智能合約快速入門(特別適合java和android開發者)
web3j是一個輕量級、高度模塊化、響應式、類型安全的Java和Android類庫提供豐富API,用於處理以太坊智能合約及與以太坊網絡上的客戶端(節點)進行集成。
可以通過它進行以太坊區塊鏈的開發,而無需為你的應用平臺編寫集成代碼。
可以快速啟動dmeo示例
想要快速啟動的話,有一個Web3j demo示例項目可用,演示了通過Web3j開發以太坊的許多核心特征,其中包括:
- 連接到以太網網絡上的節點
- 加載一個以太坊錢包文件
- 將以太幣從一個地址發送到另一個地址
- 向網絡部署智能合約
- 從部署的智能合約中讀取值
- 更新部署的智能合約中的值
- 查看由智能合約記錄的事件
web3j開發入門
首先將最新版本的web3j安裝到項目中。
Maven
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>
Gradle
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/
...
IPC
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中不可用。
通過java打包以太坊智能合約
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
Filters
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的一些功能:
- 錢包創建
- 錢包密碼管理
- 資金從錢包轉移到另一個
- solidity編寫的智能合同功能打包
請參閱文檔以獲得命令行相關的進一步的信息。
其他的細節
java8 bulid:
- Web3j提供對所有響應類型的安全訪問。可選的或null響應java 8都支持。
- 異步請求包在一個java 8的CompletableFutures。Web3j提供了圍繞所有異步請求的打包工具,以確保在執行期間可以捕獲任何異常,而不只是丟棄。由於在完全檢查中會有很多缺少支持的異常情況,這些異常通常被確定為未檢測到的異常,導致檢測過程出現問題。有關詳細信息,請參見 Async.run()及其關聯 test。
在java 8的Android版本:
- 包數量作為 BigIntegers返回。對於簡單的結果,可以通過
Response.getResult()
獲取字符串類型的數量結果。 - 還可以通過在 HttpService和IpcService類中存在的
includeRawResponse
參數將原生的JSON包放置在響應中。
安利個 Web3j教程,主要介紹java和android app通過web3j進行區塊鏈以太坊開發,適合java程序員。本文的web3j官方原文請看這裏:web3j。
web3j開發以太坊智能合約快速入門(特別適合java和android開發者)