6. 使用脚手架快速搭建 Java DApp
人生苦短,我用脚手架
> **注:**本文对「如何快速构建区块链应用?这款脚手架支持一键生成」一文有所参考。 > > **链接:**https://mp.weixin.qq.com/s/WUZzFwTJUtgDD3mnIlPstQ 区块链应用开发有多种模式,分别适配于不同的项目。如: - 开启一个节点前置服务,区块链应用访问节点前置服务; - 使用针对该语言的SDK,如Java SDK、Python SDK 等; - 通过脚手架自动生成项目。 本文将介绍第三种方式——通过脚手架生成项目。 这种方式适用于: - 刚上手区块链开发,但是想快速实现区块链项目的同学 - 想快速开展项目开发,不想在非业务层以外的代码上投入太多成本的同学 ## 1 FISCO BCOS 应用开发脚手架简介 一个典型的区块链应用项目后端,可以分为三块。业务逻辑部分由用户自行定义;代码部分包含了智能合约访问的功能,例如函数入参的封装、交易的构造和推送、链的访问等;资源部分则包含了合约、ABI、BIN。如下图所示: ![640wx_fmtpngtpwebpwxfrom5wx_lazy1wx_co1.png](https://img.learnblockchain.cn/attachments/2021/04/pkDF2Yte6087c01ce680e.png) 应用开发脚手架组件允许用户在写好智能合约的基础上,将智能合约转换为一个SpringBoot项目,这个项目已经涵盖了上图中蓝色和绿色的部分,用户只需要补充自己的业务逻辑即可,不必再去关心区块链访问的细节,大大缩短了开发时间。 ### 脚手架组件关键特性 **一键生成** 用户在开发完智能合约后,可以将智能合约直接拖入脚手架,只要轻量配置,就可以生成相关项目。并且,生成的项目已经包含了智能合约访问的必要逻辑。此外,该项目是SpringBoot项目,相关的配置、服务均已纳入到spring容器当中。 **高度封装** 脚手架在生成项目时,会对合约调用逻辑做高度的封装,用户可以像使用ORM框架操作数据库一样地操作智能合约。 在生成的项目中,每个合约都被单独封装到一个类中,每个函数对应合约的一个函数。其输入是java类型的输入,输出也是已解析的输出。此外,对于函数的输入参数,我们也已生成了相关的模型类,方便用户使用。 **轻量配置** 用户在将智能合约拖入脚手架后,只需做少量的涉及项目名称、组名、合约选择器等内容的配置即可。而且这些配置依据“契约优于配置”的原则设置了默认值,用户可根据自己的实际需要进行调整。 **合约可选** 在开发具有一定复杂度的智能合约时,出于易升级、松耦合的目的,开发者通常会采用一定的手段将合约功能解耦,拆散到不同的合约中去。所以,在一组智能合约中,真正供外部访问的合约只占少数,多数合约都仅作为功能性合约来支撑整体业务。 而且,在后续应用开发时,真正需要开发的服务类也占少数。为了让项目聚焦在所需要的合约上,开发者可配置合约选择器,即指定所需要处理的合约,继而脚手架只会为这些合约生成相应的代码,避免了冗余代码。 ## 2 快速实践 ### 2.1 从 Github 或者 Gitee 获得脚手架源码 ```bash git clone https://gitee.com/WeBankBlockchain/SmartDev-Scaffold.git # Gitee # git clone https://gitee.com/WeBankBlockchain/SmartDev-Scaffold.git # Github cd SmartDev-Scaffold ``` ### 2.2 编译项目 确保环境适配: | 依赖软件 | 说明 | 备注 | | -------- | --------------------- | ----------------- | | Java | >= JDK[1.8] | 最好用JDK 1.8 | | Solidity | 0.4.25 | | | Git | 下载安装包需要使用Git | | | Gradle | 大于6 小于7 | 使用gradle7会报错 | 编译: ```bash gradle build -x test ``` ![image-20210425144724949](https://tva1.sinaimg.cn/large/008i3skNly1gpycf8jsjej318m0ey782.jpg) ### 2.3 通过脚手架生成项目 进入`tools`文件夹: ```bash cd tools ``` #### 2.3.1 合约配置 本示例中,使用默认的 HelloWorld 合约。实际使用过程中,可删除`contracts` 目录下的默认合约,并将自己的业务合约拷贝到该目录下。 #### 2.3.2 项目配置 可以在`config.ini`中做项目配置,如下: ``` ### 项目名称 artifact=demo ### 组名称 group=org.example ### 所支持的合约列表,通常为空即可 selector= ``` #### 2.3.3 运行脚手架 ```bash chmod +x run.sh & bash run.sh ``` 运行成功后,`tools` 目录下会出现`demo`文件夹,这是自动生成的 SpringBoot 项目。 ![image-20210425145544315](https://tva1.sinaimg.cn/large/008i3skNly1gpycf7kadxj310i07ojsz.jpg) ### 4 准备工作 假定我们的区块链节点已经启动了(搭链可见:[TODO])。 ![image-20210425150106835](https://tva1.sinaimg.cn/large/008i3skNly1gpycfcp3awj30pm07uq41.jpg) 在进行具体业务逻辑开发前,我们还需要做如下几项工作: - 部署合约 - 证书拷贝 - 补充配置文件 #### 4.1 通过WebaseFront部署合约 **(1)启动 WeBaseFront** 此处我们通过 WeBaseFront 来进行部署。 > **简介:**WeBASE-Front是和FISCO-BCOS节点配合使用的一个子系统。此分支支持FISCO-BCOS 2.0以上版本,集成web3sdk,对接口进行了封装,可通过HTTP请求和节点进行通信。另外,具备可视化控制台,可以在控制台上开发智能合约,部署合约和发送交易,并查看交易和区块详情。还可以管理私钥,对节点健康度进行监控和统计。 > > **文档地址:**https://webasedoc.readthedocs.io/zh_CN/latest/docs/WeBASE-Front/README.html 通过如下命令启动: ```bash bash start.sh ``` ![image-20210425150749701](https://tva1.sinaimg.cn/large/008i3skNly1gpycf9f7sdj31j80astck.jpg) 然后访问: > http://localhost:5002/WeBASE-Front/#/contract **(2)创建测试账户** 首先我们创建一个测试用户。 > 合约管理 > 测试用户 > 新增用户 ![image-20210425151514097](https://tva1.sinaimg.cn/large/008i3skNly1gpycf7zq81j31n20mo762.jpg) 然后将其信息导出。 ![image-20210425151546294](https://tva1.sinaimg.cn/large/008i3skNly1gpycfag2qgj31040giq3w.jpg) 将下载的内容打开,把私钥复制出来: ![image-20210425151640658](https://tva1.sinaimg.cn/large/008i3skNly1gpycfbvo7oj312y0ogjuw.jpg) **(3)录入合约** 打开「合约管理 > 合约 IDE」,将刚才复制出来的合约代码通过合约IDE添加进来: ![image-20210425151901330](https://tva1.sinaimg.cn/large/008i3skNly1gpycfbh9eej31bc0u0ti7.jpg) **(4)保存、编译、部署** 然后我们会得到合约地址(`contractAddress`),我们把它复制出来。 现在我们有了一个链上的HelloWorld合约,并拿到了一个账户私钥和一个合约地址。 #### 4.2 复制证书文件到Conf目录下 conf目录位置: > /src/main/resources/conf 通过cp命令复制: ```bash cp ~/fisco/nodes/127.0.0.1/sdk/* src/main/resources/conf/ # 此处按节点具体位置进行调整 ``` #### 4.3 补充配置文件 要修改的地方如下所示: ```bash ### Required ### (1)此处改为节点地址+端口 system.peers=127.0.0.1:20200 ### Required system.groupId=1 ### Optional. Default will search conf,config,src/main/conf/src/main/config system.certPath=conf,config,src/main/resources/conf,src/main/resources/config ### Optional. If don't specify a random private key will be used ### (2)此处改为 4.1 中拿到的私钥 system.hexPrivateKey=e5a34796608dcc9462af7de1d282dd7e4a1b0e421b81af7a904847e2f9f7f781 ### Optional. Please fill this address if you want to use related service ### (2)此处改为 4.1 中的合约地址 system.contract.helloWorldAddress=0xf6035ce1d6b1b689e25bc2893179c00fbac2645a ### ### Springboot server config server.port=8080 server.session.timeout=60 banner.charset=UTF-8 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8 ``` #### 4.4 编译与运行 ```bash gradle build -x test ``` 进入`dist`目录运行程序: ```bash cd dist java -jar demo-exec.jar ``` 运行成功会显示程序顺利启动: ![image-20210425164817351](https://tva1.sinaimg.cn/large/008i3skNly1gpycf8zv2oj313o0ni0xj.jpg) ### 5 添加业务逻辑 在`src/main/java/org/example/demo/service`目录下新建`HelloController.java`文件。 内容为: ```java package org.example.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.example.demo.service.HelloWorldService; import org.example.demo.model.bo.HelloWorldSetInputBO; @RestController @RequestMapping("hello") public class HelloController { @Autowired private HelloWorldService service; @GetMapping("set") public String set(@RequestParam("n") String n) throws Exception{ HelloWorldSetInputBO input = new HelloWorldSetInputBO(n); return service.set(input).getTransactionReceipt().getTransactionHash(); } @GetMapping("get") public String get() throws Exception{ return service.get().getValues(); } } ``` 这个文件的作用是创建两个url,一个是`/hello/set`,设置`name`的值,一个是`/hello/get`,拿到`name`的值。 我们重新编译项目: ```bash gradle build -x test ``` 然后我们重新运行项目: ```bash cd dist java -jar demo-exec.jar ``` 再打开另一个终端(或直接打开浏览器),通过 curl 命令即可通过url与智能合约进行交互: ``` curl http://127.0.0.1:8080/hello/get curl http://127.0.0.1:8080/hello/set\?n\=happy curl http://127.0.0.1:8080/hello/get ``` ![image-20210425170022278](https://tva1.sinaimg.cn/large/008i3skNly1gpycfd6wmtj30zg09476q.jpg)
注:本文对「如何快速构建区块链应用?这款脚手架支持一键生成」一文有所参考。
链接:https://mp.weixin.qq.com/s/WUZzFwTJUtgDD3mnIlPstQ
区块链应用开发有多种模式,分别适配于不同的项目。如:
- 开启一个节点前置服务,区块链应用访问节点前置服务;
- 使用针对该语言的SDK,如Java SDK、Python SDK 等;
- 通过脚手架自动生成项目。
本文将介绍第三种方式——通过脚手架生成项目。
这种方式适用于:
- 刚上手区块链开发,但是想快速实现区块链项目的同学
- 想快速开展项目开发,不想在非业务层以外的代码上投入太多成本的同学
1 FISCO BCOS 应用开发脚手架简介
一个典型的区块链应用项目后端,可以分为三块。业务逻辑部分由用户自行定义;代码部分包含了智能合约访问的功能,例如函数入参的封装、交易的构造和推送、链的访问等;资源部分则包含了合约、ABI、BIN。如下图所示:
应用开发脚手架组件允许用户在写好智能合约的基础上,将智能合约转换为一个SpringBoot项目,这个项目已经涵盖了上图中蓝色和绿色的部分,用户只需要补充自己的业务逻辑即可,不必再去关心区块链访问的细节,大大缩短了开发时间。
脚手架组件关键特性
一键生成
用户在开发完智能合约后,可以将智能合约直接拖入脚手架,只要轻量配置,就可以生成相关项目。并且,生成的项目已经包含了智能合约访问的必要逻辑。此外,该项目是SpringBoot项目,相关的配置、服务均已纳入到spring容器当中。
高度封装
脚手架在生成项目时,会对合约调用逻辑做高度的封装,用户可以像使用ORM框架操作数据库一样地操作智能合约。
在生成的项目中,每个合约都被单独封装到一个类中,每个函数对应合约的一个函数。其输入是java类型的输入,输出也是已解析的输出。此外,对于函数的输入参数,我们也已生成了相关的模型类,方便用户使用。
轻量配置
用户在将智能合约拖入脚手架后,只需做少量的涉及项目名称、组名、合约选择器等内容的配置即可。而且这些配置依据“契约优于配置”的原则设置了默认值,用户可根据自己的实际需要进行调整。
合约可选
在开发具有一定复杂度的智能合约时,出于易升级、松耦合的目的,开发者通常会采用一定的手段将合约功能解耦,拆散到不同的合约中去。所以,在一组智能合约中,真正供外部访问的合约只占少数,多数合约都仅作为功能性合约来支撑整体业务。
而且,在后续应用开发时,真正需要开发的服务类也占少数。为了让项目聚焦在所需要的合约上,开发者可配置合约选择器,即指定所需要处理的合约,继而脚手架只会为这些合约生成相应的代码,避免了冗余代码。
2 快速实践
2.1 从 Github 或者 Gitee 获得脚手架源码
git clone https://gitee.com/WeBankBlockchain/SmartDev-Scaffold.git # Gitee
# git clone https://gitee.com/WeBankBlockchain/SmartDev-Scaffold.git # Github
cd SmartDev-Scaffold
2.2 编译项目
确保环境适配:
依赖软件 | 说明 | 备注 |
---|---|---|
Java | >= JDK[1.8] | 最好用JDK 1.8 |
Solidity | 0.4.25 | |
Git | 下载安装包需要使用Git | |
Gradle | 大于6 小于7 | 使用gradle7会报错 |
编译:
gradle build -x test
2.3 通过脚手架生成项目
进入tools
文件夹:
cd tools
2.3.1 合约配置
本示例中,使用默认的 HelloWorld 合约。实际使用过程中,可删除contracts
目录下的默认合约,并将自己的业务合约拷贝到该目录下。
2.3.2 项目配置
可以在config.ini
中做项目配置,如下:
### 项目名称
artifact=demo
### 组名称
group=org.example
### 所支持的合约列表,通常为空即可
selector=
2.3.3 运行脚手架
chmod +x run.sh & bash run.sh
运行成功后,tools
目录下会出现demo
文件夹,这是自动生成的 SpringBoot 项目。
4 准备工作
假定我们的区块链节点已经启动了(搭链可见:[TODO])。
在进行具体业务逻辑开发前,我们还需要做如下几项工作:
- 部署合约
- 证书拷贝
- 补充配置文件
4.1 通过WebaseFront部署合约
(1)启动 WeBaseFront
此处我们通过 WeBaseFront 来进行部署。
简介:WeBASE-Front是和FISCO-BCOS节点配合使用的一个子系统。此分支支持FISCO-BCOS 2.0以上版本,集成web3sdk,对接口进行了封装,可通过HTTP请求和节点进行通信。另外,具备可视化控制台,可以在控制台上开发智能合约,部署合约和发送交易,并查看交易和区块详情。还可以管理私钥,对节点健康度进行监控和统计。
文档地址:https://webasedoc.readthedocs.io/zh_CN/latest/docs/WeBASE-Front/README.html
通过如下命令启动:
bash start.sh
然后访问:
http://localhost:5002/WeBASE-Front/#/contract
(2)创建测试账户
首先我们创建一个测试用户。
合约管理 > 测试用户 > 新增用户
然后将其信息导出。
将下载的内容打开,把私钥复制出来:
(3)录入合约
打开「合约管理 > 合约 IDE」,将刚才复制出来的合约代码通过合约IDE添加进来:
(4)保存、编译、部署
然后我们会得到合约地址(contractAddress
),我们把它复制出来。
现在我们有了一个链上的HelloWorld合约,并拿到了一个账户私钥和一个合约地址。
4.2 复制证书文件到Conf目录下
conf目录位置:
/src/main/resources/conf
通过cp命令复制:
cp ~/fisco/nodes/127.0.0.1/sdk/* src/main/resources/conf/
# 此处按节点具体位置进行调整
4.3 补充配置文件
要修改的地方如下所示:
### Required
### (1)此处改为节点地址+端口
system.peers=127.0.0.1:20200
### Required
system.groupId=1
### Optional. Default will search conf,config,src/main/conf/src/main/config
system.certPath=conf,config,src/main/resources/conf,src/main/resources/config
### Optional. If don't specify a random private key will be used
### (2)此处改为 4.1 中拿到的私钥
system.hexPrivateKey=e5a34796608dcc9462af7de1d282dd7e4a1b0e421b81af7a904847e2f9f7f781
### Optional. Please fill this address if you want to use related service
### (2)此处改为 4.1 中的合约地址
system.contract.helloWorldAddress=0xf6035ce1d6b1b689e25bc2893179c00fbac2645a
### ### Springboot server config
server.port=8080
server.session.timeout=60
banner.charset=UTF-8
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
4.4 编译与运行
gradle build -x test
进入dist
目录运行程序:
cd dist
java -jar demo-exec.jar
运行成功会显示程序顺利启动:
5 添加业务逻辑
在src/main/java/org/example/demo/service
目录下新建HelloController.java
文件。
内容为:
package org.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.example.demo.service.HelloWorldService;
import org.example.demo.model.bo.HelloWorldSetInputBO;
@RestController
@RequestMapping("hello")
public class HelloController {
@Autowired
private HelloWorldService service;
@GetMapping("set")
public String set(@RequestParam("n") String n) throws Exception{
HelloWorldSetInputBO input = new HelloWorldSetInputBO(n);
return service.set(input).getTransactionReceipt().getTransactionHash();
}
@GetMapping("get")
public String get() throws Exception{
return service.get().getValues();
}
}
这个文件的作用是创建两个url,一个是/hello/set
,设置name
的值,一个是/hello/get
,拿到name
的值。
我们重新编译项目:
gradle build -x test
然后我们重新运行项目:
cd dist
java -jar demo-exec.jar
再打开另一个终端(或直接打开浏览器),通过 curl 命令即可通过url与智能合约进行交互:
curl http://127.0.0.1:8080/hello/get
curl http://127.0.0.1:8080/hello/set\?n\=happy
curl http://127.0.0.1:8080/hello/get
区块链技术网。
- 发表于 2021-04-27 15:43
- 阅读 ( 924 )
- 学分 ( 44 )
- 分类:FISCO BCOS
- 专栏:狗哥区块链精品内容集
评论