Web3j-OpenAPI是来自 Solidity 智能合约的OpenAPI客户端 和服务器生成器。它提供了一种使用简单的 RESTful API与以太坊智能合约交互的方法。这些交互可以使用普通的 HTTP 请求或通过每个项目生成的Swagger-UI来完成。
此工作流程可以概括为以下步骤:
编写 Solidity 智能合约
使用Web3j-CLI生成对应的Web3j-OpenAPI项目
将生成的项目作为独立服务器运行
Swagger-UI使用、Java/Kotlin客户端Curl或其他方式发送 HTTP 请求。
例子¶
以下 Hello World 合同:
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.7.0;
// Modified Greeter contract. Based on example at https://www.ethereum.org/greeter.
contract Mortal {
/* Define variable owner of the type address*/
address owner;
/* this function is executed at initialization and sets the owner of the contract */
constructor () {owner = msg.sender;}
modifier onlyOwner {
require(
msg.sender == owner,
"Only owner can call this function."
);
_;
}
/* Function to recover the funds on the contract */
function kill() onlyOwner public {selfdestruct(msg.sender);}
}
contract HelloWorld is Mortal {
/* define variable greeting of the type string */
string greet;
/* this runs when the contract is executed */
constructor (string memory _greet) {
greet = _greet;
}
function newGreeting(string memory _greet) onlyOwner public {
emit Modified(greet, _greet, greet, _greet);
greet = _greet;
}
/* main function */
function greeting() public view returns (string memory) {
return greet;
}
event Modified(
string indexed oldGreetingIdx, string indexed newGreetingIdx,
string oldGreeting, string newGreeting);
}
生成以下OpenAPI规格:
{
"openapi":"3.0.1",
"info":{
"title":"Web3j OpenApi",
"contact":{
"name":"Web3 Labs",
"url":"http://web3labs.com",
"email":"hi@web3labs.com"
},
"version":"4.8.7"
},
"tags":[
{
"name":"default",
"description":"Lists existing contracts and events"
},
{
"name":"HelloWorld Methods",
"description":"List HelloWorld method's calls"
},
{
"name":"HelloWorld Events",
"description":"List HelloWorld event's calls"
}
],
"paths":{
"/Web3App/contracts/helloworld/{contractAddress}/Kill":{
"get":{
"tags":[
"HelloWorld Methods"
],
"summary":"Execute the Kill method",
"operationId":"kill",
"parameters":[
{
"name":"contractAddress",
"in":"path",
"required":true,
"schema":{
"type":"string"
}
}
],
"responses":{
"default":{
"description":"default response",
"content":{
"application/json":{
"schema":{
"$ref":"#/components/schemas/TransactionReceiptModel"
}
}
}
}
}
}
},
…
有相应的Swagger-UI:
可用的方法有:
可用的事件是:
Web3j-OpenAPI 入门¶
生成项目¶
要使用Web3j-OpenAPI生成器生成 OpenAPI 项目,您需要在机器上安装Web3j-CLI。这很容易做到(此处为 Windows 说明):
$ curl -L get.web3j.io | sh
然后,您可以运行
$ web3j openapi import --help
检查生成器可用选项。
在这种情况下,我们将使用上面的 Hello World 合约。
将该合同放在一个名为HelloWorld.solstarters 的文件中。
然后,执行以下命令:
$ web3j openapi import \
-s=HelloWorld.sol \
--package=com.tutorial \
--project-name=HelloWorldProject \
--output-dir=.
您应该会看到类似于以下内容的日志:
配置项目¶
您可以使用Web3j-cli轻松运行项目,无需指定任何配置。
如果不是,则需要指定运行时参数。例如,用于签名的private key或,用于连接的 等。wallet filenode endpoint
要查看可用选项,请运行发行版executable或JAR带有–help标志的 。您将获得以下显示:
要指定这些参数,您可以设置以下环境变量:
$ export WEB3J_ENDPOINT=<link_to_your_Ethereum_node>
$ export WEB3J_PRIVATE_KEY=<your_private_key>
$ export WEB3J_OPENAPI_HOST=localhost
$ export WEB3J_OPENAPI_PORT=9090
有关传递这些参数的更多方法,请查看下面的配置部分。
运行项目¶
我们可以直接运行项目:
$ ./gradlew run
您应该能够运行服务器并看到以下内容:
与生成的项目交互¶
可以通过多种方式进行交互:
招摇UI¶
生成SwaggerUI的位于{host}:{port}/swagger-ui并且可用于与 API 进行所有可能的交互。例如:
HTTP 请求¶
通过以下工具发送 HTTP 请求Curl:
$ curl -X POST "http://{host}:{port}/HelloWorldProject/contracts/helloworld/{contract address}/NewGreeting" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"_greet\":\"Hello Web3j-OpenAPI\"}"
客户端应用¶
也可以使用 Java/Kotlin 客户端应用程序进行交互。后者可以使用我们的客户端实现来完成。
确保将客户端依赖项添加到您的项目中。
dependencies {
implementation "org.web3j.openapi:web3j-openapi-client:4.8.7"
}
然后,您将能够与 API 交互,如下所示:
val service = ClientService("http://localhost:9090")
val helloWorldProject = ClientFactory.create(HelloWorldProjectApi::class.java, service)
println("Deploying the HelloWorld contract...")
val receipt = helloWorldProject.contracts.helloWorld.deploy(HelloWorldDeployParameters("Hello"))
println("Deployed contract address: ${receipt.contractAddress}")
val newGreetingHash = helloWorldProject.contracts
.helloWorld
.load(receipt.contractAddress)
.newGreeting(NewGreetingParameters("Hello Web3j-OpenAPI"))
.transactionHash
println("NewGreeting method execution transaction hash: $newGreetingHash")
val greeting = helloWorldProject.contracts
.helloWorld
.load(receipt.contractAddress)
.greeting()
.result
println("Greeting method result: $greeting")
生成 OpenAPI 项目的方法¶
首先,您需要在您的机器上安装Web3j-CLI 。
这很容易做到(此处为 Windows 说明):
$ curl -L get.web3j.io | sh
生成一个 Hello World 项目¶
Hello World 项目是一个基于简单 Solidity 合约的简单项目。它是使用以下方法生成的:
$ web3j openapi new
该项目可以用作开始构建您的自定义应用程序的最小项目。
使用自定义 Solidity 智能合约生成¶
要使用所需的智能合约生成项目,请使用以下命令:
$ web3j openapi import \
--solidity-path <path_to_Solidity_contracts> \
--project-name <project name> \
--package <package name>
生成可执行 JAR¶
以下命令将生成一个可以运行的可执行 JAR:
$ web3j openapi jar \
--solidity-path <path_to_Solidity_contracts>
仅生成 REST API¶
要仅生成 API,即定义的端点及其实现,请使用以下内容:
$ web3j openapi generate \
--solidity-path <path_to_Solidity_contracts> \
--with-implementations=true
此命令不会生成整个项目结构。因此,您将没有可运行的应用程序。要拥有一个,请检查上述部分。
该with-implementations标志true默认设置为。这意味着 RESTful 端点将沿着它们的实现生成。
如果您更喜欢只生成接口。将该标志设置为false:
--with-implementations=false
使用web3j-openapi-gradle-plugin生成¶
可以gradle使用web3j-openapi-gradle-plugin. 查看文档以获取更多信息。
运行项目¶
运行时参数¶
在运行服务器之前,需要设置一些参数。有多种方法可以这样做:
环境变量
配置文件
将参数直接传递给 JAR 或可执行文件。
此外,您可以使用Web3j-cli运行项目而无需担心任何这些
支持的参数¶
姓名 默认值 描述
name Generation project name 项目名称
config file ~/.web3j/web3j.openapi. 用于导入额外参数的自定义配置文件
endpoint none 与区块链交互时的目标以太坊节点端点
private key none 十六进制格式的用户私钥,前缀为0x
wallet path none 钱包文件的路径(可以是绝对的或相对的)
wallet password none 指定钱包文件的明文密码
host localhost 服务器主机(可以是 IP 地址或主机名)
port 8080 服务器端口
contract addresses none 使用预先部署的合约地址:contract1=0x123,contract2=0x1234. 您需要提供给生成器的只是 ABI。
必要的参数是:
与以太坊网络交互时目标的以太坊节点端点endpoint
Credentials : 可以是private key, 或wallet pathandwallet password
其余参数是可选的。
优先顺序¶
参数可以在不同源之间互换指定。即,您可以在默认配置文件中定义一些,而在环境变量等中定义其他一些。
但是,对于重复值,我们强制执行以下顺序:
CLI 参数
CLI 中指定的自定义配置文件
环境变量中指定的自定义配置文件
默认配置文件
环境变量
查看以下部分以获取更多信息。
CLI 参数¶
CLI 参数可以以通常的方式传递给命令。
例子¶
检查下面的启动服务器部分以选择命令。
$ <command> \
--private-key 0x1234 \
--name OpenApiProject \
--endpoint <Ethereum node endpoint> \
--host localhost \
--port 9090 \
--contract-addresses contract1=0x1234,contract2=0x123
配置文件¶
您可以将参数放在configuration file. 后者,可以是 YAML,Json或Java properties类型的文件。
配置文件可以是:
放入默认目录:~/.web3j/web3j.openapi.
在环境变量中设置:WEB3J_OPENAPI_CONFIG_FILE其中值是文件的路径。例如。
export WEB3J_OPENAPI_CONFIG_FILE=<path_to_the_config_file}
在运行 JAR 或可执行文件时设置为参数:–config-file
支持的扩展是:
yaml对于YAML配置。例子:
contractAddresses:
helloworld: "0x1234"
helloworld2: "0x1234"
credentials:
privateKey: "0x1234"
network:
endpoint: "<your_node_endpoint_address>"
project:
name: "OpenApiProject"
server:
host: "localhost"
port: 9090
json对于Json配置。例子:
{
"contractAddresses": {
"helloworld": "0x1234",
"helloworld2": "0x1234"
},
"credentials": {
"privateKey": "0x1234"
},
"network": {
"endpoint": "your node endpoint address"
},
"project": {
"name": "OpenApiProject"
},
"server": {
"host": "localhost",
"port": 9090
}
}
properties对于Java properties配置。例子:
contractAddresses=helloworld=0x1234,helloworld2=0x1234
credentials.privateKey=0x1234
network.endpoint=your node endpoint address
project.name=OpenApiProject
server.host=localhost
server.port=9090
环境变量¶
提供运行时参数的最简单方法是通过环境变量。
规则是:
将 替换-为_:private-key => private_key
大写选项的名称:private-key => PRIVATE_KEY
例子¶
$ export WEB3J_ENDPOINT=<link_to_your_Ethereum_node>
$ export WEB3J_OPENAPI_HOST=localhost
$ export WEB3J_OPENAPI_PORT=9090
$ export WEB3J_OPENAPI_NAME=Web3jOpenAPI
$ export WEB3J_OPENAPI_CONTRACT_ADDRESSES=helloworld=0x1234,helloworld2=0x12345
$ export WEB3J_OEPNAPI_CONFIG_FILE=~/myConfig.yaml
以及以下之一:
原始私钥:
$ export WEB3J_PRIVATE_KEY=0x1234
一个钱包:
$ export WEB3J_WALLET_PATH=~/myWallet.json
$ export WEB3J_WALLET_PASSWORD=myStrongPassword
启动服务器¶
可以通过以下方式启动服务器:
生成的 JAR¶
JAR可以使用以下命令生成A :
$ ./gradlew shadowJar
它会在build/libs目录下找到。
生成的JAR可以使用以下命令运行:
$ java -jar build/libs/-all.jar
检查上面的参数部分以获取支持的参数。
分发可执行文件¶
可以使用以下命令生成服务器可执行文件:
$ ./gradlew installShadowDist <parameters>
可以在其中找到build/install/-shadow/bin/
使用梯度¶
使用 gradle 运行项目。确保按照上面的说明设置了一些环境变量或配置文件。
然后,运行以下命令:
$ ./gradlew run
Web3j-OpenAPI 客户端¶
在与 Web3j-OpenAPI 服务器交互的可用方式中,有Kotlin客户端。
它很容易使用。
首先向客户端添加依赖项:
dependencies {
implementation "org.web3j.openapi:web3j-openapi-client:4.8.7"
}
然后,在客户端应用程序中:
val service = ClientService("http://localhost:9090")
val app = ClientFactory.create(<AppNameApi>::class.java, service)
// Then you have access to all the API resources
val receipt = app.contracts.contractName.deploy()
println("Deployment receipt: ${receipt.contractAddress}")
// …
处理事件¶
在 web3j-OpenAPI 中,我们使用 Server-Sent Events SSE处理事件。
简而言之,SSE 是一种单向机制,一旦客户端建立了客户端-服务器连接,服务器就可以将数据从服务器异步推送到客户端。
从 查询事件Kotlin/Java。web3j-openapi-client如上所述添加依赖项。然后,使用以下代码:
val service = ClientService("http://localhost:9090")
val app = ClientFactory.create(AppNameApi::class.java, service)
// Start listening for events
val event = app.contracts.<contract_name>.load(<contract_Address>)
.events
.<event_name>
.onEvent { println("Received event: $it") }
// Trigger an event
app.contracts
.<contract_name>
.load(<contract_Address>)
.<method_triggering_event>(<method_parameters>)
然后运行这段代码。您应该能够在屏幕上看到打印的事件。