java類庫web3j開發以太坊智慧合約快速入門

NO IMAGE

web3j簡介

web3j是一個輕量級、高度模組化、響應式、型別安全的Java和Android類庫提供豐富API,用於處理以太坊智慧合約及與以太坊網路上的客戶端(節點)進行整合。

可以通過它進行以太坊區塊鏈的開發,而無需為你的java應用平臺編寫整合程式碼。

快速啟動

想要快速啟動的話,有一個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

傳送請求

傳送同步請求

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

需要注意: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 EventsWeb3jRx的介面。

交易

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:parityorg.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包放置在響應中。

原文請訪問:web3js開發以太坊智慧合約快速入門

如果對以太坊開發有興趣,安利兩個教程:

1.適合區塊鏈新手的以太坊DApp開發:以太坊dapp入門實戰
2.用區塊鏈、星際檔案系統(IPFS)、Node.js和MongoDB來構建以太坊DApp電商平臺:以太坊開發電商平臺