文章目录
五、使用应用开发脚手架SmartDev快速开始一个应用
一、实验概述
前节实验中,我们完成了智能合约的开发,但完整的区块链应用开发,除了智能合约开发外,后台开发也不可或缺。
后台开发又包括项目建立、引入依赖、配置代码编写、模型类编写、服务类编写、业务逻辑编写等步骤。这些步骤相对繁琐,影响了开发的效率。例如,我们要为每个合约函数去编写交易构造与推送的代码;甚至,要为每个合约函数的入参编写相应模型类。
分析上述过程,以上步骤存在一定的规律性,可通过脚手架的方式降低重复的工作量,帮助开发者快速、敏捷地开发智能合约应用。FISCO BCOS提供了智能合约脚手架SmartDev,用于一键式生成DAPP应用开发工程,从而降低应用开发的难度。用户将自己的合约导入脚手架,即可生成对应的应用开发模板工程,包含了对应的POJO类、服务类等,用户可基于此直接开发dapp web项目。
本实验将使用智能合约脚手架SmartDev,一键式生成DAPP应用开发工程,从而降低应用开发的难度。主要包括SmartDev的下载及配置、运行以及DAPP的开发过程。
二、实验目标
- 了解SmartDev应用开发脚手架工作原理;
- 掌握SmartDev的下载及配置方法;
- 掌握脚手架的运行方法。
- 掌握使用脚手架进行DAPP开发的过程。
三、实验环境及建议
- 熟悉Java开发语言;
- 了解一定的前后端的基础知识;
- 前置依赖,在使用本组件前,请确认已安装相关依赖软件,清单如下:
依赖软件 | 说明 | 备注 |
---|---|---|
Java | >= JDK[1.8] | 64bit |
Solidity | 0.4.25.1 0.5.2.0 0.6.10.0 0.8.11.0 | |
Git | 下载安装包需要使用Gi | |
Gradle | 大于6 小于7 | 使用gradle7会报错 |
Maven | 与Gradle任选其一 | 如果要生成maven工程则需要 |
四、实验步骤
4.1 下载脚手架
根据实验环境要求,在使用脚手架前,需要下载依赖工具gradle,版本最好选用v6.3;
cd ~/fisco/ && wget https://services.gradle.org/distributions/gradle-6.3-bin.zip
解压到当前文件夹;
unzip -d ./ gradle-6.3-bin.zip
配置环境变量;
vi /etc/profile
点击i进入插入模式,在文件末尾写入以下内容:
export PATH=$PATH:/root/fisco/gradle-6.3/bin
保存退出,输入以下命令,使配置生效。
source /etc/profile && gradle -v
然后从github下载脚手架SmartDev-Scaffold
:
cd ~/fisco/ && curl -LO https://github.com/WeBankBlockchain/SmartDev-Scaffold/releases/download/V1.0.1/SmartDev-Scaffold-V1_0_1.zip
下载成功后,手动或用命令行解压压缩包:
unzip SmartDev-Scaffold-V1_0_1.zip
注解
如果因为网络问题导致长时间无法下载,请尝试:git clone https://gitee.com/WeBankBlockchain/SmartDev-Scaffold.git
进入目录:
cd SmartDev-Scaffold/tools/
tree ./
没有tree
命令使用yum install tree -y
安装
tools目录包含了执行环境,其结构为:
├── tools
│ ├── contracts
│ ├──|── HelloWorld.sol
│ ├── config.ini
│ ├── run.sh
│ ├── run.bat
其中:
- contracts目录用于存放solidity合约文件,脚手架后续会读取该目录下的合约以生成对应的业务工程。请删除该目录下的默认合约,并将自己的业务合约拷贝到该目录下。
- config.ini是启动相关配置。
- run.sh和run.bat分别是unix和windows下的启动脚本。
4.2 配置脚手架
合约配置
本实验以默认合约HelloWorld.sol
为例,进行介绍。
注:在实际的开发过程中,请删除contracts目录下的默认合约HelloWorld.sol
,并将自己的业务合约拷贝到该目录下。
生成配置
可以在config.ini中做生成配置如下。在实际情况开发中,根据需要对名称进行适当修改
cd ~/fisco/SmartDev-Scaffold/tools && vi config.ini
# 指定项目的名称
artifact=demo
# 组名称
group=org.example
### 所支持的合约列表,默认为空表示选择所有合约
selector=
# solidity编译器版本,可选0.4.25.1, 0.5.2.0, 0.6.10.0, 0.8.11.0
compiler=0.4.25.1
# 工程生成类型,可以设置为gradle或maven
type=gradle
# gradle版本,支持5.6.1、gradle 6各版本。暂不支持gradle7。如果您选择了maven项目,系统会自动忽略此选项
gradleVersion=6.3
说明:关于selector,如果需要只为指定合约进行编译输出,可以输入所需要的合约列表,按逗号分隔(本实验忽略)。例如下述代码中,只为AccountController,RoleController这两个合约:
selector=AccountController,RoleController
4.3 运行脚手架
赋予脚本run.sh可执行权限,然后启动脚本,按照上述配置生成SpringBoot项目;
chmod +x run.sh && bash run.sh
运行成功后,会在tools目录下得到一个基于SpringBoot的项目工程:
├─contracts
├─run.sh
├─run.bat
└─demo # 和前面config.ini中定义项目名一致
其中生成项目的具体内容如下(以gradle项目为例)
cd ~/fisco/SmartDev-Scaffold/tools/demo/ && tree ./
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── settings.gradle
└── src
├── main
│ ├── contracts
│ │ └── HelloWorld.sol
│ ├── java
│ │ └── org
│ │ └── example
│ │ └── demo
│ │ ├── Application.java
│ │ ├── config
│ │ │ ├── BcosConfig.java
│ │ │ ├── ContractConfig.java
│ │ │ ├── SdkBeanConfig.java
│ │ │ └── SystemConfig.java
│ │ ├── constants
│ │ │ └── ContractConstants.java
│ │ ├── model
│ │ │ ├── bo
│ │ │ │ └── HelloWorldSetInputBO.java
│ │ │ └── CommonResponse.java
│ │ └── service
│ │ └── HelloWorldService.java
│ └── resources
│ ├── abi
│ │ └── HelloWorld.abi
│ ├── application.properties
│ ├── bin
│ │ ├── ecc
│ │ │ └── HelloWorld.bin
│ │ └── sm
│ │ └── HelloWorld.bin
│ └── conf
└── test
└── java
└── org
└── example
└── demo
└── Demos.java
其中:
- config目录包含Bean配置类
- service目录中包含了智能合约访问的Service类,一个类对应一个合约
- bo目录包含了合约函数输入参数的封装POJO类
- src/main/resource/conf目录用于存放证书信息
- Demos.java包含了私钥生成、部署合约等示例代码
如果生成了maven项目,则不会有gradle相关内容,而会包含pom、mvnw、mvnw.cmd等文件。
4.4 DAPP开发
这里介绍DAPP开发过程,以前面生成的demo项目工程为例。
4.4.1 部署合约
使用控制台或Webase IDE部署HelloWorld合约,本实验以控制台为例;
进入到~/fisco/目录下,先启动bcos链所有节点,再启动控制台;
cd ~/fisco/
bash nodes/127.0.0.1/start_all.sh
cp -n console/conf/config-example.toml console/conf/config.toml
cp -r nodes/127.0.0.1/sdk/* console/conf/
bash console/start.sh
实际开发中需要将待部署合约HelloWorld.sol
拷贝到控制台目录下contracts/solidity/
,因控制台默认已包含合约HelloWorld.sol
,所以本实验此步骤省略。
在控制台中输入以下命令,部署合约;
在控制台输入以下指令部署成功则返回合约地址,示例如下,以实际步骤的为准
[group:1]> deploy HelloWorld
transaction hash: 0x01f334001a3bab4aec59451eb45adf969351ef056cf7addf32c4d76db0ceb180
contract address: 0x72b67af62a14a1222471b08d99cc31acd56285fe
currentAccount: 0xea5ae216dd34f5b4bb6e67043c1b38e0aa5aac2d
记录合约地址和用户账户,以备后续步骤使用。控制台中输入q退出控制台。
4.4.2 证书拷贝
将bcos节点中配置文件拷贝到生成工程的conf目录或src/main/resources/conf目录下。
cp -r ~/fisco/nodes/127.0.0.1/sdk/* ~/fisco/SmartDev-Scaffold/tools/demo/src/main/resources/conf/
4.4.3 配置连接节点
请修改application.properties,该文件包含如下信息,根据实际情况填入合约地址:
cd ~/fisco/SmartDev-Scaffold/tools/demo/src/main/resources/ && vi application.properties
### Java sdk configuration
cryptoMaterial.certPath=conf
network.peers[0]=127.0.0.1:20200
network.peers[1]=127.0.0.1:20201
### System configuration
system.groupId=1
system.privateKey=
### Contract configuration
contract.helloWorldAddress=0x72b67af62a14a1222471b08d99cc31acd56285fe # 根据实际情况填写
### Springboot configuration
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
其中:
- java sdk configuration配置部分与javasdk配置一致。
- 其中需要用户将network.peers[0]=127.0.0.1:20200更换成实际的链节点监听地址。
- System configuration包含群组、私钥等配置。
- system.hexPrivateKey是16进制的私钥明文。如果为空,会采用上述java sdk配置对应的私钥,若上述sdk也未配置,则随机生成一个
- Contract confguration包含合约配置,用户需要更换成前面部署过的合约地址。
4.4.4 补全业务
一个完整的DAPP应包含至少三层架构,本示例补全一个Controller。在org.example.demo下新建controller目录,然后在该目录下新建一个HelloController类,如下:
cd ~/fisco/SmartDev-Scaffold/tools/demo/src/main/java/org/example/demo/
mkdir controller
vi controller/HelloController.java
或者在IDEA编辑器中完成以上步骤。
在HelloController类中写入以下内容:
package org.example.demo.controller;
import org.example.demo.model.bo.HelloWorldSetInputBO;
import org.example.demo.service.HelloWorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@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();
}
}
4.4.5 运行jar包
本实验使用Gradle生成的项目,则执行以下命令生成Jar包(生成时间较长,因网速而异):
gradle bootJar
较慢时,可在build.gradle文件中添加国内镜像:
repositories { maven{ url'http://maven.aliyun.com/nexus/content/groups/public/'} }
cd ~/fisco/SmartDev-Scaffold/tools/demo/
gradle bootJar
如果您生成的是maven项目,则执行:
cd ~/fisco/SmartDev-Scaffold/tools/demo/
mvn package
cd target
执行完成后,在当前目录下生成dist目录,目录中生成有demo-exec.jar包,输入以下命令执行此jar包:
cd ~/fisco/SmartDev-Scaffold/tools/demo/dist/
java -jar demo-exec.jar
随后,可在浏览器内输入:
http://127.0.0.1:8080/hello/set?n=hello
返回示例:
0xb66179f2e5d8edefa638fcaf234061260583a32cfef5dae63f74998827afc9d0
http://127.0.0.1:8080/hello/get
返回示例:
["hello"]
五、练习任务
- 结合前端知识,为上述DAPP设计一个前端界面,并配合后端项目成功运行。
- 请使用上一节实验中设计的存证合约替换本实验中的示例合约"HelloWorld.sol",并尝试生成SpringBoot项目。