Spring Boot 整合 Fisco Bcos(区块链)

简介

FISCO BCOS 是由国内企业主导研发、对外开源、安全可控的企业级金融联盟链底层平台,由金链盟开源工作组协作打造,并于 2017 年正式对外开源。

目前,成熟的区块链的平台不少,之所以选择 FISCO BCOS,主要是因为文档细致,容易入门。

官方地址入口

本地环境

本篇文章介绍的 Spring Boot 整合 Fisco Bcos 的案例,是在阿里云服务器上部署验证的。
我这边共有两台电脑:
电脑 1:本地的 Mac 电脑,没有区块链环境,只是用于 SpringBoot 工程的开发;
电脑 2:阿里云上的 CentOS 服务器,配置了区块链环境,合约部署、编译、SpringBoot 工程的 jar 包运行都是在该电脑上;

大家可根据自己的电脑环境,对比该案例进行开发即可。

主要流程:

--> 1、Fisco Bcos 环境搭建与验证
--> 2、创建 SpringBoot 工程并配置依赖
--> 3、编写案例代码
--> 4、生成 jar 包、部署服务器验证

1、Fisco Bcos 环境搭建与验证

Fisco Bcos 环境搭建参考的是官方的文档:
搭建第一个区块链网络
我这边测试服务器的操作系统是 CentOS,如果是其他操作系统,也是参照该文档进行配置,流程是类似的。
详细流程,大家参照文档进行配置就行了,这里主要说下关键的细节:

1.1、搭建单群组 4 节点联盟链:

我这边使用的是国密版本命令:
bash build_chain.sh -l 127.0.0.1:4 -p 30300,20200,8545 -g -G

主要原因:

我这边使用的 Fisco Bcos SDK 版本是 2.8.0,加载证书时默认会加载国密证书(应该有加载证书类型的选项配置,目前暂未找到相关 API)。
如果使用的是非国密版本命令,在 /fisco/node/127.0.0.1/sdk/ 目录下不会生成国密证书,使用该 SDK 就会报错。

1.2、检查证书

成功启动所有节点后,在 /fisco/node/127.0.0.1/sdk/ 目录下验证所有证书是否存在(gm 代表国密),如下图:

1.3、使用证书验证节点正确性

启动节点后,我们可以使用 Fisco Bcos 提供的本地控制台程序 console 对节点进行验证。
大家参照文档,先下载、配置控制台程序。
注意:为控制台程序配置节点证书(即:将 /fisco/node/127.0.0.1/sdk/ 下的证书全部复制到控制台程序的 /console/conf/ 目录下)

启动控制台,测试节点,例如:获取区块链数据高度:getBlockNumber:
如果能正常部署合约,且能获得数据高度,则区块链环境没什么问题,如下图:

2、创建 SpringBoot 工程并配置依赖

服务端区块链环境已完成验证,接下来,我们创建 SpringBoot 工程,并集成 Fisco Bcos Java 版 SDK。
Java SDK 文档

2.1、创建 SpringBoot 工程:



仅勾选 Spring Web 即可:

2.2、配置 pom.xml

注意:SpringBoot 版本不宜过高(已与官方技术人员确认),我这边试过 2.6.2+,Demo 案例调用节点时会异常闪退,当把版本降低为 2.4.2 就正常了:

配置 Fisco Bcos Java 版 SDK 依赖:

pom.xml 完整代码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.qxc</groupId>
    <artifactId>demo_bcos</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo_bcos</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-test<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>test<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.fisco-bcos.java-sdk<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>fisco-bcos-java-sdk<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.8.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
        <span class="hljs-comment">&lt;!--排除这个slf4j-log4j12--&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">exclusions</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">exclusion</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.slf4j<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>slf4j-log4j12<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">exclusion</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">exclusions</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">build</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">plugins</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">plugins</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">build</span>&gt;</span>

</project>

3、编写案例代码

3.1、配置 Fisco Bcos:

Java SDK » 配置说明
为了简单,本案例将 Fisco Bcos 的参数通过 xml 统一配置,并在代码中自动读取。
在 /src/main/resources/ 目录下创建文件 fisco-config.xml:

fisco-config.xml 完整代码:
<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"
>

<bean id="defaultConfigProperty" class="org.fisco.bcos.sdk.config.model.ConfigProperty">
<property name="cryptoMaterial">
<map>
<entry key="certPath" value="conf" />
</map>
</property>
<property name="network">
<map>
<entry key="peers">
<list>
<value>127.0.0.1:20200</value>
<value>127.0.0.1:20201</value>
</list>
</entry>
</map>
</property>
<property name="account">
<map>
<entry key="keyStoreDir" value="account" />
<entry key="accountAddress" value="" />
<entry key="accountFileFormat" value="pem" />
<entry key="password" value="" />
<entry key="accountFilePath" value="" />
</map>
</property>
<property name="threadPool">
<map>
<entry key="channelProcessorThreadSize" value="16" />
<entry key="receiptProcessorThreadSize" value="16" />
<entry key="maxBlockingQueueSize" value="102400" />
</map>
</property>
</bean>

<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"defaultConfigOption"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.fisco.bcos.sdk.config.ConfigOption"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"configProperty"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ref</span> <span class="hljs-attr">bean</span>=<span class="hljs-string">"defaultConfigProperty"</span>/&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"bcosSDK"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.fisco.bcos.sdk.BcosSDK"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"configOption"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ref</span> <span class="hljs-attr">bean</span>=<span class="hljs-string">"defaultConfigOption"</span>/&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>

</beans>

3.2、配置节点证书:

把区块链节点下的证书拷贝到 /src/main/resources/conf/ 目录下(conf 目录为 fisco-config.xml 配置的证书路径):

3.3、编写 controller

BcosController 完整代码:
package com.qxc.demo_bcos.controller;

import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.client.protocol.response.BlockNumber;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class BcosController {
@GetMapping("/test")
public String test(){
System.out.println("-----test------");
return "this is bcos demo";
}

<span class="hljs-meta">@GetMapping(<span class="hljs-string">"/block"</span>)</span>
<span class="hljs-keyword">public</span> String getBlockNumber(){
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"-----getBlockNumber getBlockNumber------"</span>);
    <span class="hljs-meta">@SuppressWarnings(<span class="hljs-string">"resource"</span>)</span>
    ApplicationContext context = new ClassPathXmlApplicationContext(<span class="hljs-string">"classpath:fisco-config.xml"</span>);
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"-----getBlockNumber ClassPathXmlApplicationContext ok------"</span>);
    BcosSDK bcosSDK = context.getBean(BcosSDK.<span class="hljs-keyword">class</span>);
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"-----getBlockNumber BcosSDK ok------"</span>);
    Client client = bcosSDK.getClient(Integer.valueOf(<span class="hljs-number">1</span>));
    System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"-----getBlockNumber client ok------"</span>);
    BlockNumber blockNumber = client.getBlockNumber();
    <span class="hljs-keyword">return</span> <span class="hljs-string">"getBlockNumber: "</span>+blockNumber.getBlockNumber().toString();

// return "";
}
}

3.4、DemoBcosApplication 默认不做修改

3.5、application.properties 什么也没配置

为了简单,端口我这边直接使用 8080,主要是个人比较懒,什么都懒得配置了,O(∩_∩)O~

4、生成 jar 包、部署服务器验证

4.1、本地先跑一把

SpringBoot 的开发是在我本地的 Mac 电脑上进行的,为了能稳妥的部署到远程 CentOS 服务器上,
先在本地跑一把,看看工程编译运行是否正常(此时不用测试区块链功能,因为我本地并没有区块链环境):


没问题,完美。

4.2、打包 jar

4.3、把 jar 包发送到远程服务器上,并运行:


案例程序已在服务器端跑起来了,回到本地 mac 电脑,远程连服务器试一下吧(IP 就不展示给大家看了哈):

至此,使用 Spring Boot 整合 Fisco Bcos 最最基本的案例已完成。

总结

Fisco Bcos 的使用还是很简单的,如果有问题大家可以直接查询官方技术文档,也欢迎留言讨论,咱们共同学习、共同进步,哈哈 ~~。

下一节:Spring Boot 整合 Fisco Bcos(部署、调用区块链合约)