Web3j-OpenAPI使用教程

Web3 Labs的目标之一是使以太坊上的开发尽可能简单。在过去的三年中,我们看到许多团队(包括我们自己)在Web3j之上一次又一次地编写RESTful服务,以便为他们的服务器应用程序提供与以太坊的直接集成。
今年早些时候,我们决定对此做一些事情,并高兴地宣布Web3j Open API项目。这个最新的项目使您可以轻松签订智能合约并生成符合OpenAPI的服务器应用程序(通过Swagger提供完整的OpenAPI文档)。
Web3j OpenAPI生成器
Web3j-OpenAPI是用于Solidity智能合约的OpenAPI生成器。它提供了一种通过简单直观的HTTP请求与以太坊区块链进行交互的方式。这些交互可以使用简单的HTTP请求或通过每个项目生成的Swagger-UI来完成。
工作流可概括为以下步骤:
1. 编写Solidity智能合约
2. 使用Web3j-OpenAPI生成相应的OpenAPI项目
3. 将生成的项目作为独立服务器运行
4. 使用Swagger-UI或使用我们的客户端实现从客户端应用程序发送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
    );
}

我们可以使用Web3j OpenAPI创建RESTful服务来部署该应用程序并与之无缝集成。Swagger UI包含在服务中,因此您可以轻松地尝试使用它。

创建一个新的应用程序
要使用Web3j-OpenAPI生成器生成OpenAPI项目,您需要在计算机上安装Epirus-CLI(注意-Epirus CLI替代了Web3j CLI)。
使用以下命令安装Epirus-CLI
$ curl -L get.epirus.io | sh
要检查安装是否成功以及OpenAPI生成器是否正常工作,请运行以下命令:
$ epirus openapi import –help
您应该看到生成器帮助显示:

在本文中,我们将使用上面的Hello World合约。首先将上述代码复制到名为HelloWorld.sol的文件中,并将其复制到本地目录中。
然后,执行以下命令:
$ epirus openapi import \
    -s=HelloWorld.sol \
    –package=com.tutorial \
    –project-name=HelloWorldProject \
    –output-dir=. 
您应该看到类似于以下内容的输出:

这意味着OpenAPI项目已与SwaggerUI一起成功生成。确认目录中有一个名为HelloWorldProject的文件夹。
如果是这样,则您成功使用Web3j-OpenAPI生成了第一个OpenAPI项目。
下一步是运行项目。
您可以使用Epirus-CLI轻松运行项目,而无需指定任何配置。
如果不是,则需要指定运行时参数:例如用于签名的私钥或钱包文件,要连接的节点端点等。
配置环境
要检查所有可用选项,请使用–help标志运行项目:
$ cd HelloWorldProject
$ ./gradlew run –args=”–help”
您将看到以下显示:

有多种方法可以指定这些参数:
环境变量
配置文件
直接从CLI
这里我们将通过环境变量传递参数,但是您可以阅读文档中的其他选项。
为此,请运行以下命令:
$ export WEB3J_ENDPOINT=Ethereum_node>
$ export WEB3J_PRIVATE_KEY=<your_private_key>
$ export WEB3J_OPENAPI_HOST=localhost
$ export WEB3J_OPENAPI_PORT=9090
运行应用程序
按如下方式运行应用程序
$ ./gradlew run
您应该能够运行服务器并看到以下内容:

与API交互
运行项目后,将定义端点,等待请求。为了发送请求,我们将使用生成的Swagger-UI。
使用SwaggerUI
可以通过以下链接访问Swagger-UI:http://<host>:<port>/swagger-ui。
在我们的例子中,它将位于http//localhost:9090/swagger-ui。
然后,使用端点POST/HellowWorldProject/contracts/helloworld部署您的合约:

如果合约成功部署,您应该会看到一个交易收据模型:

如果没有,您应该收到一条错误消息,您可以在响应中或服务器日志中看到该错误消息。
然后,我将通过提供在上一个交易收据中收到的合约地址来调用greeting GET方法:

您应该看到以下响应:

通过Java / Kotlin进行交互
我们还可以使用Java或Kotlin客户端与OpenAPI项目进行交互。
为此,首先将Web3j-OpenApi客户端依赖项添加到您的项目中:
dependencies {
    implementation “org.web3j.openapi:web3j-openapi-client:4.7.1”
}
然后与服务交互,如下所示:
var service = new ClientService(“http://localhost:9090”);
var helloWorldProject = ClientFactory.create(
    HelloWorldProjectApi.class, service
);
System.out.println(“Deploying the HelloWorld contract…”);
var deployParams = new HelloWorldDeployParameters(“Hello”);
var receipt = helloWorldProject.getContracts()
    .getHelloWorld().deploy(deployParams);
System.out.println(“Deployed contract address: ” +
    receipt.getContractAddress());
// Load the contract from the returned transaction receipt
var helloWorld = helloWorldProject.getContracts()
    .getHelloWorld().load(receipt.getContractAddress());
// Change the greeting message
var newReceipt = helloWorld.newGreeting(
    new NewGreetingParameters(“Hello Web3j-OpenAPI”)
);
System.out.println(“NewGreeting transaction hash: ” +
    newReceipt.getTransactionHash());
// Check that the smart contract has been updated
var greeting = helloWorld.greeting().getResult();
System.out.println(“Greeting method result: ” + greeting);
根据您使用的网络,部署可能需要一些时间。
处理事件
在Web3j-OpenAPI中,我们使用服务器发送事件(SSE)处理事件。
简而言之,SSE是一种单向机制,一旦客户端与客户端建立连接,服务器就可以将数据从服务器异步推送到客户端。
要从Kotlin/Java查询事件,请按照上面的步骤添加Web3j-OpenAPI-client依赖项。然后使用以下代码:
var countdownLatch = new CountDownLatch(1);
// Start listening for events
helloWorld.getEvents().getModified().onEvent(e -> {
    System.out.println(“Received event: ” +
        modifiedEvent.getNewGreeting());
    countdownLatch.countDown();
});
helloWorld.newGreeting(new NewGreetingParameters(
    “This will trigger a modified event”));
countdownLatch.await(); // Waits for the event
然后运行此代码。您应该可以在屏幕上看到事件打印。

结论
在这里,演示了为智能合约启动API端点是多么容易。考虑到现在可以轻松地生成它们,我们希望您可以开始考虑用于以太坊集成的api,而不是迄今为止一直是标准的讨厌的集成代码。