如何從智能合約中生成Java Wrapper
在本文中,我們將了解如何直接從智能合約生成Java Wrapper類以與Java中的智能合約進(jìn)行交互。
從智能合約生成Java Wrapper類有不同的方法:
1. Web3j命令行工具和solc
2. Web3j命令行工具和Truffle構(gòu)建生成的工件
3. web3j-maven-plugin
4. web3j-gradle-plugin
為了演示如何使用上述方法,本教程使用以下智能合約將文檔公證到以太坊區(qū)塊鏈上的注冊表中。
DocumentRegistry.sol
pragma solidity ^0.5.6;
/**
* @dev Smart Contract responsible to notarize documents on the Ethereum Blockchain
*/
contract DocumentRegistry {
struct Document {
address signer; // Notary
uint date; // Date of notarization
bytes32 hash; // Document Hash
}
/**
* @dev Storage space used to record all documents notarized with metadata
*/
mapping(bytes32 =》 Document) registry;
/**
* @dev Notarize a document identified by its 32 bytes hash by recording the hash, the sender and date in the registry
* @dev Emit an event Notarized in case of success
* @param _documentHash Document hash
*/
funcTIon notarizeDocument(bytes32 _documentHash) external returns (bool) {
registry[_documentHash].signer = msg.sender;
registry[_documentHash].date = now;
registry[_documentHash].hash = _documentHash;
emit Notarized(msg.sender, _documentHash);
return true;
}
/**
* @dev Verify a document idenTIfied by its hash was noterized in the registry.
* @param _documentHash Document hash
* @return bool if document was noterized previsouly in the registry
*/
funcTIon isNotarized(bytes32 _documentHash) external view returns (bool) {
return registry[_documentHash].hash == _documentHash;
}
/**
* @dev DefiniTIon of the event triggered when a document is successfully notarized in the registry
*/
event Notarized(address indexed _signer, bytes32 _documentHash);
}
web3j命令行工具和solc
第一種方法使用solc生成Smart合約ABI和bytecode,并將這兩個文件作為輸入提供給web3j-cli以生成Wrapper。
1、安裝solc并驗證版本
安裝solc并運(yùn)行以下命令以確保solc版本大于或等于0.5.6(智能合約中指定的版本)。
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.5.9+commit.c68bc34e.Linux.g++
2、安裝Web3J CLI
要安裝web3j cli,請從項目存儲庫的“發(fā)布”頁面的“下載”部分下下載zipfile/tarball,或通過homebrew為MacOS用戶或通過aur為Arch Linux用戶下載zipfile/tarball。
brew tap web3j/web3j
brew install web3j
web3j
要通過zipfile運(yùn)行,解壓縮并運(yùn)行二進(jìn)制文件,您可能還需要將二進(jìn)制文件添加到PATH中:
$ unzip web3j-4.3.0.zip
creating: web3j-4.3.0/lib/
inflating: web3j-4.3.0/lib/core-1.0.2-all.jar
creating: web3j-4.3.0/bin/
inflating: web3j-4.3.0/bin/web3j
inflating: web3j-4.3.0/bin/web3j.bat
$ 。/web3j-《version》/bin/web3j
_ _____ _ _
| | |____ (_) (_)
__ _____| |__ / /_ _ ___
/ / / _ ‘_ | | | / _
V V / __/ |_) |.___/ / | _ | || (_) |
\_/\_/ \___|_.__/ \____/| |(_)|_| \___/
_/ |
|__/
Usage: web3j version|wallet|solidity 。..
3、使用solc編譯智能合約
給定我們的Solidity文件DocumentRegistry.sol,solc 《sol》 --bin --abi --optimize -o 《output》命令編譯智能合約并在同一目錄中生成兩個新文件:
$ solc DocumentRegistry.sol --bin --abi --optimize -o 。/
Compiler run successful. Artifact(s) can be found in directory 。/.
$ ls -l
total 12
-rw-rw-r-- 1 gjeanmart gjeanmart 565 Jun 24 13:42 DocumentRegistry.abi
-rw-rw-r-- 1 gjeanmart gjeanmart 676 Jun 24 13:42 DocumentRegistry.bin
-rw-rw-r-- 1 gjeanmart gjeanmart 1488 Jun 24 13:40 DocumentRegistry.sol
DocumentRegistry.bin:二進(jìn)制文件,智能合約的字節(jié)碼
DocumentRegistry.abi:智能合約的ABI(應(yīng)用程序二進(jìn)制接口),它以JSON格式定義接口。
4、使用web3j-cli生成包裝器
使用ABI和bytecode(在步驟3中生成)和web3j-cli(在步驟2中安裝),我們現(xiàn)在可以使用以下命令生成我們的智能合約的Java Wrapper:
web3j solidity generate -a=《abiFile》 -b=《binFile》 -o=《destinationFileDir》 -p=《packageName》
示例:
$ web3j solidity generate -a DocumentRegistry.abi
-b DocumentRegistry.bin -o 。
-p me.gjeanmart.tutorials.javaethereum.wrapper
_ _____ _ _
| | |____ (_) (_)
__ _____| |__ / /_ _ ___
/ / / _ ’_ | | | / _
V V / __/ |_) |.___/ / | _ | || (_) |
\_/\_/ \___|_.__/ \____/| |(_)|_| \___/
_/ |
|__/
Generating me.gjeanmart.tutorials.javaethereum.wrapper.DocumentRegistry 。.. File written to 。
因此,您應(yīng)該看到生成到文件夾/.java中的Java Wrapper文件,您可以將其復(fù)制到項目的src / main / java /文件夾中。
。/me/gjeanmart/tutorials/javaethereum/wrapper/DocumentRegistry.java
Web3j命令行工具和Truffle artefacts
Truffle是最著名的框架之一,可幫助您使用以太坊開發(fā)、測試和部署。 我們可以使用Truffle使用Web3j命令行工具生成的artefacts來創(chuàng)建wrapper類。
1、安裝Truffle
Truffle可作為npm wrapper提供。
$ npm install truffle -g
- Fetching solc version list from solc-bin. Attempt #1
+ truffle@5.0.24
added 27 packages from 439 contributors in 11.636s
$ truffle version
Truffle v5.0.24 (core: 5.0.24)
Solidity v0.5.0 (solc-js)
Node v10.15.3
Web3.js v1.0.0-beta.37
2、初始化新的Truffle項目
要初始化Truffle項目,請在新文件夾中使用truffle init命令。該命令創(chuàng)建文件夾contract /,migration /和test /,以及文件truffle-config.js。
$ mkdir truffle
$ cd truffle
$ truffle init
? Preparing to download
? Downloading
? Cleaning up temporary files
? Setting up box
Unbox successful. Sweet!
Commands:
Compile: truffle compile
Migrate: truffle migrate
Test contracts: truffle test
$ ls -l
total 20
drwxrwxr-x 2 gjeanmart gjeanmart 4096 Jun 24 14:25 contracts
drwxrwxr-x 2 gjeanmart gjeanmart 4096 Jun 24 14:25 migrations
drwxrwxr-x 2 gjeanmart gjeanmart 4096 Jun 24 14:25 test
-rw-rw-r-- 1 gjeanmart gjeanmart 4233 Jun 24 14:25 truffle-config.js
3、將合同添加到文件夾合約中
將智能合約源documentregistry.sol復(fù)制到文件夾contracts中。
4、編譯合約
使用命令truffle compile編譯智能合約,此命令生成一個新的文件夾build/contracts/,其中包含每個編譯的智能合約的truffle artefact。
$ truffle compile
Compiling your contracts.。.
===========================
》 Compiling 。/contracts/DocumentRegistry.sol
》 Compiling 。/contracts/Migrations.sol
》 Artifacts written to /home/gjeanmart/workspace/tutorials/java-ethereum-wrapper/truffle/build/contracts
》 Compiled successfully using:
- solc: 0.5.8+commit.23d335f2.Emscripten.clang
$ ls -l build/contracts/
total 136
-rw-rw-r-- 1 gjeanmart gjeanmart 79721 Jun 24 14:33 DocumentRegistry.json
-rw-rw-r-- 1 gjeanmart gjeanmart 54043 Jun 24 14:33 Migrations.json
5、從Truffle Artefact生成智能合約Java Wrapper
最后,web3j-cli提供了一種方法,可以使用以下命令直接從truffle編譯的Truffle artefact結(jié)果生成Wrapper:
$ web3j truffle generate 。/build/contracts/DocumentRegistry.json -o 。 -p me.gjeanmart.tutorials.javaethereum.wrapper
_ _____ _ _
| | |____ (_) (_)
__ _____| |__ / /_ _ ___
/ / / _ ‘_ | | | / _
V V / __/ |_) |.___/ / | _ | || (_) |
\_/\_/ \___|_.__/ \____/| |(_)|_| \___/
_/ |
|__/
Generating me.gjeanmart.tutorials.javaethereum.wrapper.DocumentRegistry 。.. File written to 。
因此,您應(yīng)該看到生成到《packagefolders》 /。java_文件夾中的Java Wrapper文件,您可以將其復(fù)制到項目的src / main / java /文件夾中。
。/me/gjeanmart/tutorials/javaethereum/wrapper/DocumentRegistry.java
注意:使用Truffle,您可以做的比本文中顯示的更多,例如部署腳本(遷移)、多網(wǎng)絡(luò)配置、測試、調(diào)試。
web3j-maven-plugin
下一個解決方案比前兩個解決方案更優(yōu)雅,因為我們不必安裝webj-cli并將文件復(fù)制到源文件夾。我們可以使用Maven和web3j-maven-plugin直接在Java項目中使用此方法。以下步驟假定您已創(chuàng)建Maven項目。
1、先決條件
安裝solc并運(yùn)行以下命令以確保solc版本大于或等于0.5.6(智能合約中指定的版本)。
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.5.9+commit.c68bc34e.Linux.g++
2、將智能合約復(fù)制到文件夾src / main / resources中
將Smart Contract源DocumentRegistry.sol復(fù)制到Maven項目的src / main / resources文件夾中。
3、配置Maven以在generate-sources階段生成Wrapper
在此步驟中,我們配置兩個Maven插件:
web3j - Maven的插件
第一個插件與前兩個方法相同,但與Maven集成。首先,我們將插件配置為在進(jìn)入項目的generate-sources階段時自動執(zhí)行。
其次我們配置插件參數(shù):
· packageName:要應(yīng)用于生成的Wrapper類的包名稱
· sourceDestination:目標(biāo)文件夾,用于移動生成的Wrapper類
· soliditySourceFiles:在何處查找Smart Contract源文件
建立輔助性Maven的插件
第二個插件將sourceDestination文件夾添加到類路徑中,以便我們可以導(dǎo)入生成的Wrapper類
pom.xml
《build》
《plugins》
《plugin》
《groupId》org.web3j《/groupId》
《artifactId》web3j-maven-plugin《/artifactId》
《version》4.2.0《/version》
《executions》
《execution》
《id》generate-sources-web3j《/id》
《phase》generate-sources《/phase》
《goals》
《goal》generate-sources《/goal》
《/goals》
《configuration》
《packageName》me.gjeanmart.tutorials.javaethereum.contracts.generated《/packageName》
《sourceDestination》${basedir}/target/generated-sources/contracts《/sourceDestination》
《soliditySourceFiles》
《directory》${basedir}/src/main/resources《/directory》
《includes》
《include》**/*.sol《/include》
《/includes》
《/soliditySourceFiles》
《/configuration》
《/execution》
《/executions》
《/plugin》
《plugin》
《groupId》org.codehaus.mojo《/groupId》
《artifactId》build-helper-maven-plugin《/artifactId》
《executions》
《execution》
《id》add-source《/id》
《phase》generate-sources《/phase》
《goals》
《goal》add-source《/goal》
《/goals》
《configuration》
《sources》
《source》${basedir}/target/generated-sources/contracts《/source》
《/sources》
《/configuration》
《/execution》
《/executions》
《/plugin》
《/plugins》
《/build》
4、運(yùn)行Maven生成源
最后,使用mvn clean package(包括generate-sources階段)構(gòu)建Maven項目。因此,我們可以看到Java Wrapper已生成到/target/generated-sources/contracts/me/gjeanmart/tutorials/javaethereum/contracts/generated/DocumentRegistry.java并自動添加到類路徑中。
Web3J Gradle插件
最后一個方法與之前使用Maven的方法類似,但使用的是Gradle。
1、先決條件
安裝solc并運(yùn)行以下命令以確保solc版本大于或等于0.5.6(智能合約中指定的版本)。
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.5.9+commit.c68bc34e.Linux.g++
2、將智能合約放入文件夾src / main / solidity
將Smart Contract源DocumentRegistry.sol復(fù)制到Gradle項目的src / main / solidity文件夾中。
3、配置Gradle以在構(gòu)建期間生成Wrapper首先將web3j-gradle插件導(dǎo)入build.gradle文件。
plugins {
id ’org.web3j‘ version ’4.3.0‘
}
然后我們可以配置插件來為生成的wrapper類指定包名稱和目標(biāo)文件夾:
web3j {
generatedPackageName = ’me.gjeanmart.tutorials.javaethereum.contracts.generated‘
generatedFilesBaseDir = “$buildDir/contracts”
}
要使用系統(tǒng)安裝的solc版本而不是與插件捆綁的版本,請將以下行添加到build.gradle:
solidity {
executable = “solc”
}
build.gradle
/*
* This file was generated by the Gradle ’init‘ task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* user guide available at https://docs.gradle.org/5.0/userguide/java_library_plugin.html
*/
plugins {
// Apply the java-library plugin to add support for Java Library
id ’java-library‘
id ’org.web3j‘ version ’4.3.0‘
}
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api ’org.apache.commons:commons-math3:3.6.1‘
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation ’com.google.guava:guava:26.0-jre‘
implementation ’org.web3j:core:4.3.0‘
// Use JUnit test framework
testImplementation ’junit:junit:4.12‘
}
web3j {
generatedPackageName = ’me.gjeanmart.tutorials.javaethereum.contracts.generated‘
generatedFilesBaseDir = “$buildDir/contracts”
}
solidity {
executable = “solc”
}
4、執(zhí)行g(shù)radle構(gòu)建
在最后一步中,我們使用。/gradlew tasks執(zhí)行構(gòu)建--all并驗證我們生成的wrapper類是否已生成。