Spring Boot Integrated Block Chain-Block Chain Service Development Example

This example mainly adds enterprise information into the block chain, and then implements the query of the source of enterprise information. It has functions such as adding, querying, modifying, deleting, viewing history and so on.

1. Prepare a bsn-springboot project

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.6.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.yuyun</groupId>
    <artifactId>springboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot</name>
    <description>springboot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. Introducing jar packages

Download: https://yuyunyaohui.lanzoul.com/iwnMXxuxm2f Password: hk9i

Create a new lib directory under the project to put the jar package in

Then pom.xml file introduced into the jar package

<dependency>
    <groupId>com.example.javacc</groupId>
    <artifactId>bsn-sdk-java</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>system</scope>
    <systemPath>${pom.basedir}/lib/bsn-sdk-java-jar-with-dependencies.jar</systemPath>
</dependency>

3. Block Chain Configuration

Method 1: Create a new config.json file

Create a new config directory in the resources directory, and then create a new config in it. JSON file in the following format:

{
  "userPrivateKey": "",
  "bsnPublicKey": "",
  "appCode": "",
  "userCode": "",
  "nodeApi": "",
  "mspPath": ""
}

Content, Open Block Chain Offline Services I Participate in

Click Download Secret Key to download the unzipped file. There are two files in the userAppCert directory, one is the private key and the other is the public key, which corresponds to the config. userPrivateKey and bsnPublicKey in JSON

Copy all the contents of the two files into it, for example:

{
  "userPrivateKey": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgVbS8svrC3sdFgIFW\nUoLfczfjCjq0z7fGTSFfqMkjssChRANCAARXn4a1tA3PB8+wx9UgU0GDfGBG7BXZ\nENL5GN3vYXqpcbCtvxAtINSK02KcQ1a6jAASy79T0ax9KfQDjzGVFN9K\n-----END PRIVATE KEY-----",
  "bsnPublicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEV5+GtbQNzwfPsMfVIFNBg3xgRuwV\n2RDS+Rjd72F6qXGwrb8QLSDUitNinENWuowAEsu/U9GsfSn0A48xlRTfSg==\n-----END PUBLIC KEY-----",
  "appCode": "app008809d6356825a4c249be16572723c6225",
  "userCode": "USER0001202112061433104102226",
  "nodeApi": "http://52.83.209.158:17502",
  "mspPath": ""
}

Method 2: Put two files in the userAppCert directory directly into the resources directory

4. Initialize config method

If the block chain configuration takes method one, the code to initialize the config is as follows:

public void initConfig() {
    String filePath = "config/config.json";
    Config config = Config.buildByConfigJson(filePath);
    config.initConfig(config);
}

If method two is used, the code to initialize config is as follows:

public void initConfig() throws IOException {
    Config config = new Config();
    config.setAppCode("app008809d6356825a4c249be16572723c6225");
    config.setUserCode("USER0001202112061433104102226");
    config.setApi("http://52.83.209.158:17502");
    config.setPrk(Common.readFile("cert/private_key.pem"));
    config.setPuk(Common.readFile("cert/public_key.pem"));
    config.setMspDir("");
    config.initConfig(config);
}

This example uses method one

5. Specific implementation

Create a new Service Layer code as follows:

package com.yuyun.service;

import com.yuyun.dto.BsnHistoryDTO;
import com.yuyun.dto.CompanyDTO;

import java.io.IOException;
import java.util.List;

/**
 * @author hyh
 */
public interface FabricBsnService {

    /**
     * Save (add or modify)
     *
     * @param key  Key Value
     * @param body content
     * @return Success true
     * @return Boolean
     */
    Boolean save(String key, String body);

    /**
     * query
     *
     * @param key Key Value
     * @return Result
     */
    CompanyDTO query(String key);

    /**
     * History Query
     *
     * @param key Key Value
     * @return Decrypted results
     * @throws IOException abnormal
     */
    List<BsnHistoryDTO> getHistory(String key) throws IOException;

    /**
     * delete
     *
     * @param key Key Value
     * @return Success true
     * @return Boolean
     */
    Boolean delete(String key);
}

Implementation of New Service Class

package com.yuyun.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsnbase.sdk.client.fabric.FabricClient;
import com.bsnbase.sdk.entity.config.Config;
import com.bsnbase.sdk.entity.req.fabric.ReqKeyEscrow;
import com.bsnbase.sdk.entity.res.fabric.ResKeyEscrow;
import com.yuyun.dto.BsnHistoryDTO;
import com.yuyun.dto.CompanyDTO;
import com.yuyun.service.FabricBsnService;
import com.yuyun.utils.Base64Utils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author hyh
 */
@Log4j2
@Service
public class FabricBsnServiceImpl implements FabricBsnService {

    /**
     * Initialize config
     */
    public void initConfig() {
        String filePath = "config/config.json";
        Config config = Config.buildByConfigJson(filePath);
        config.initConfig(config);
    }

    public String reqChainCode(String key, String funcName, String body) {
        try {
            initConfig();
            ReqKeyEscrow keyEscrow = new ReqKeyEscrow();

            String[] args;
            if (StringUtils.isNotBlank(body)) {
                args = new String[]{key, body};
            } else {
                args = new String[]{key};
            }

            keyEscrow.setArgs(args);
            keyEscrow.setFuncName(funcName);
            //Chain code deployment name, which can be found in the service information I participate in
            keyEscrow.setChainCode("cc_app0001");

            keyEscrow.setTransientData(new HashMap<>());
            ResKeyEscrow resKeyEscrow = FabricClient.reqChainCode(keyEscrow);
            if (200 == resKeyEscrow.getCcRes().getCcCode()) {
                String str = resKeyEscrow.getCcRes().getCcData();
                if ("null".equals(str)) {
                    return null;
                }
                return str;
            }
        } catch (Exception e) {
            throw new RuntimeException("Block chain access failed:" + e.getMessage());
        }
        return null;
    }

    @Override
    public Boolean save(String key, String body) {
        log.info("key: " + key);
        String s = reqChainCode(key, "Set", body);
        return StringUtils.isNotBlank(s);
    }

    @Override
    public CompanyDTO query(String key) {
        String queryStr = reqChainCode(key, "Query", null);
        if (StringUtils.isBlank(queryStr)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(queryStr);

        return jsonObject.toJavaObject(CompanyDTO.class);
    }

    @Override
    public List<BsnHistoryDTO> getHistory(String key) throws IOException {
        String historyStr = reqChainCode(key, "History", null);
        if (StringUtils.isBlank(historyStr)) {
            return new ArrayList<>();
        }
        JSONArray jsonArray = JSONArray.parseArray(historyStr);

        List<BsnHistoryDTO> bsnHistoryDTOList = jsonArray.toJavaList(BsnHistoryDTO.class);
        for (BsnHistoryDTO b : bsnHistoryDTOList) {
            if (null != b) {
                String value = Base64Utils.Base64Decode(b.getValue().getBytes());
                if (StringUtils.isNotBlank(value)) {
                    JSONObject jsonObject = JSONObject.parseObject(value);
                    CompanyDTO companyDTO = jsonObject.toJavaObject(CompanyDTO.class);
                    b.setCompanyDTO(companyDTO);
                }
                b.setValue("");
            }
        }

        return bsnHistoryDTOList;
    }

    @Override
    public Boolean delete(String key) {
        String s = reqChainCode(key, "Delete", null);
        return "success".equals(s);
    }
}

New Controller Layer

package com.yuyun.controller;

import com.yuyun.dto.BsnHistoryDTO;
import com.yuyun.dto.CompanyDTO;
import com.yuyun.service.FabricBsnService;
import com.yuyun.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;

/**
 * @author hyh
 */
@RestController
@RequestMapping("fabricBsn")
@Api(tags = "Block Chain")
public class FabricBsnController {

    @Autowired
    private FabricBsnService fabricBsnService;

    @GetMapping("history/{key}")
    @ApiOperation("History")
    public Result<List<BsnHistoryDTO>> history(@PathVariable("key") String key) throws IOException {
        List<BsnHistoryDTO> bsnHistoryDTOList = fabricBsnService.getHistory(key);

        return new Result<List<BsnHistoryDTO>>().success(bsnHistoryDTOList);
    }

    @GetMapping("query/{key}")
    @ApiOperation("information")
    public Result<CompanyDTO> get(@PathVariable("key") String key) {

        CompanyDTO data = fabricBsnService.query(key);

        return new Result<CompanyDTO>().success(data);
    }

    @DeleteMapping("{key}")
    @ApiOperation("delete")
    public Result<Object> delete(@PathVariable("key") String key) {

        return new Result<>().ok(fabricBsnService.delete(key));
    }
}

Method of calling block chain in enterprise management

First introduced, then called

@Autowiredprivate FabricBsnService fabricBsnService;
  • New information

    fabricBsnService.save("company_" + companyDTO.getId(), JSON.toJSONString(companyDTO));
    
  • Modify Information

    fabricBsnService.save("company_" + companyDTO.getId(), JSON.toJSONString(companyDTO));
    
  • Delete Information

    fabricBsnService.delete("company_" + id);
    

6. Operation effect

(1) Add enterprise information

(2) View enterprise information

(3) View block chain information

(4) Modify enterprise information

(5) View block chain information again

(6) Delete enterprise information

(7) View block chain information for the third time

You can see that the information has been deleted

(8) View block chain history

The results are as follows, all information history is inside

{
  "code": 0,
  "msg": "success",
  "data": [
    {
      "key": "company_1473572863141011458",
      "txId": "55dab6883d0f0d29b45175a5d98b3816b24be39af35f5fb012b165019769db23",
      "isDelete": "true",
      "time": "2021-12-22T00:42:03.498+00:00",
      "value": "",
      "companyDTO": null
    },
    {
      "key": "company_1473572863141011458",
      "txId": "9b8a0509eb37546cec7e50d0f854eea8030caf67904221b695bba0ea00742396",
      "isDelete": "false",
      "time": "2021-12-22T00:40:21.797+00:00",
      "value": "",
      "companyDTO": {
        "id": 1473572863141011458,
        "companyName": "Enterprise Name 1",
        "description": "Enterprise Description 2",
        "businessLicense": "Test Business License 3",
        "address": "Test Address 4",
        "status": null,
        "remarks": "Note 5",
        "createDate": null,
        "updateDate": null
      }
    },
    {
      "key": "company_1473572863141011458",
      "txId": "c1deb5b1911509347878d67af6c1e28b45ac37a1916f0d4c32e917d937a5b1a8",
      "isDelete": "false",
      "time": "2021-12-22T00:35:25.207+00:00",
      "value": "",
      "companyDTO": {
        "id": 1473572863141011458,
        "companyName": "Enterprise Name",
        "description": "Enterprise Description",
        "businessLicense": "Test business license",
        "address": "Test Address",
        "status": null,
        "remarks": "Remarks",
        "createDate": null,
        "updateDate": null
      }
    }
  ]
}

demo: https://gitee.com/hyh17808770899/spring-boot/tree/master/springboot-bsn

Keywords: Java Blockchain Spring Boot

Added by elentz on Tue, 28 Dec 2021 05:16:35 +0200