Advertisement

关于区块链的公共医疗应用开发

阅读量:

区块链的养老保险平台应用开发

任务一:环境准备

1.编译区块链网络

目录:/root/xuperchain/ 在区块链网络目录下执行make命令,编译网络,编译成功后输出compile done!

在这里插入图片描述

启动区块链网络

在这里插入图片描述

2.创建钱包账户

创建普通钱包账户userTest,命令如下

复制代码
    bin/xchain-cli account newkeys --output data/userTest
在这里插入图片描述

切换到/root/xuperchain/output/data/userTest,查看用户地址

在这里插入图片描述

3.向钱包账户转账

复制代码
    //转账
    
     bin/xchain-cli transfer --to (粘贴的地址)--amount 1000000 --keys data/keys/ -H 127.0.0.1:37101
在这里插入图片描述

任务二:前端工程编码

1.下载前端工程并解压

复制代码
    wget http://res.zhonghui.vip/blockchain-4/blockchain-device-Part/10/front.zip
    
    unzip front.zip -d front

2.启动前端项目

安装依赖:

复制代码
    cd front
    npm install --unsafe-perm
在这里插入图片描述

启动:

复制代码
    npm run serve
在这里插入图片描述
在这里插入图片描述

3.创建数据库

创建test数据库,查看所有数据库

复制代码
    create database test;
    
    show databases;
在这里插入图片描述

4.创建数据表

进入test数据库

复制代码
    use test;

创建表

复制代码
    CREATE TABLE `pension_account` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `wallet_address` varchar(255) DEFAULT NULL COMMENT '钱包地址',
    `personal_balance` bigint(20) DEFAULT NULL COMMENT '个人账户余额',
    `overall_balance` bigint(20) DEFAULT NULL COMMENT '总账户余额',
    `is_sponsor` tinyint(1) DEFAULT NULL COMMENT '雇主是否为职工的赞助商',
    `insured_person_name` varchar(255) DEFAULT NULL COMMENT '参保人姓名',
    `insured_person_identity_card` varchar(255) DEFAULT NULL COMMENT '参保人身份证',
    `insured_person_work_unit` varchar(255) DEFAULT NULL COMMENT '参保人工作单位',
    `working_year` bigint(20) DEFAULT NULL COMMENT '工作年限',
    `salary` bigint(20) DEFAULT NULL COMMENT '薪资',
    `payment_base` bigint(20) DEFAULT NULL COMMENT '缴费基数',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='养老账户表';
在这里插入图片描述

任务三:编写后端程序

1.构建 Java 项目

打开Intellij IDEA, 点击新建项目,设置项目名为:pension,项目位置:~/Desktop,语言:Java, 构建系统:Maven,JDK: 11, 点击创建。

在这里插入图片描述

修改包路径,将[org.example]改为[src],右键选中包名,依次选中【重构】–>【重命名】,重命 名软件包,如下图所示:

在这里插入图片描述
在这里插入图片描述

2.修改Maven依赖

文件地址: /root/Desktop/pension/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.7.11</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>pension</groupId>
    <artifactId>pension</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>pension</name>
    <description>Demo project for Spring Boot</description>
    <properties>
    <java.version>11</java.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.0</version>
    </dependency>
    <dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>com.baidu.xuper</groupId>
    <artifactId>xuper-java-sdk</artifactId>
    <version>0.3.0</version>
    </dependency>
    </dependencies>
    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    </project>

编辑项目配置文件 /root/Desktop/pension/src/main/resources 目录下创建application.properties文件

复制代码
    server.port=8090
    spring.datasource.url: jdbc:mysql://localhost:3306/test
    spring.datasource.username: root
    spring.datasource.password: 123456
    spring.datasource.driver-class-name: com.mysql.cj.jdbc.Driver
    mybatis.type-aliases-package: src/entity
    mybatis.mapper-locations: classpath:/mapper/*.xml

最后将桌面上的合约和编译文件拖入/root/Desktop/pension/src/main/resources目录下,如下图 所示:

在这里插入图片描述

使用solc编译合约,进入 /root/Desktop/pension/src/main/resources目录下执行如下命令:

复制代码
    ./solc --abi --bin pensionInsurance.sol -o --output-dir
在这里插入图片描述

3.编写代码

以下路径均为后端工程 /root/Desktop/pension下的相对路径,完整的项目文件如下图所示。

在这里插入图片描述

代码一 代码文件路径:java/src/PensionApplication.java

新建PensionApplication.java文件,实现构建xuperchain客户端, 获取账户,解决跨域请求, 时间格式 化等功能。代码如下:

复制代码
    package src;
    import com.baidu.xuper.api.Account;
    import com.baidu.xuper.api.XuperClient;
    import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import
    org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustom
    izer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Collections;
    @SpringBootApplication
    public class PensionApplication {
    @Bean
    public XuperClient createXuperClient(){
    return new XuperClient("127.0.0.1:37101");
    }
    @Bean
    public Account createAccount(){
    return
    Account.getAccountFromPlainFile("/root/xuperchain/output/data/userTest");
    }
    @Bean
    public LocalDateTimeSerializer localDateTimeDeserializer() {
    return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MMdd HH:mm:ss"));
    }
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer
    jackson2ObjectMapperBuilderCustomizer() {
    return builder -> builder.serializerByType(LocalDateTime.class,
    localDateTimeDeserializer());
    }
    public static void main(String[] args) {
    SpringApplication.run(PensionApplication.class, args);
    }
    }

代码二 代码文件路径:java/src/Config.java

创建Config.java文件,配置合约名称和账户名称。代码如下

复制代码
    package src;
    public class Config {
    //每次启动需要更换
    public static String CONTRACT_NAME = "Person10100";
    public static String ACCOUNT_NAME = "4233456589011002";
    }

代码三 代码文件路径:java/src/StartTask.java

创建StartTask.java文件,部署合约并完成调用。 代码如下:

复制代码
    package src;
    import com.alibaba.fastjson.JSON;
    import com.baidu.xuper.api.Account;
    import com.baidu.xuper.api.Transaction;
    import com.baidu.xuper.api.XuperClient;
    import org.springframework.stereotype.Component;
    import javax.annotation.PostConstruct;
    import javax.annotation.Resource;
    import java.io.IOException;
    import java.math.BigInteger;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.HashMap;
    import java.util.Map;
    @Component
    public class StartTask {
    @Resource
    private XuperClient client;
    @Resource
    private Account account;
    @PostConstruct
    public void createContract() {
    //前面命令行已经给该账户转了钱
    BigInteger balance = client.getBalance(account.getAddress());
    System.out.println("balance:" + balance);
    //创建合约账户, 长度必须是16
    Transaction contractAccount = client.createContractAccount(account,
    Config.ACCOUNT_NAME);
    //转账给合约账户
    Transaction transfer = client.transfer(account, "XC" +
    Config.ACCOUNT_NAME + "@xuper", BigInteger.valueOf(100), "1");
    // 查询余额7BCD3C3BAD8152CB1A2CFBDB55D0AC7F92FF7B19
    BigInteger result = client.getBalance("XC" + Config.ACCOUNT_NAME +
    "@xuper");
    System.out.println("contract balance:" + result);
    //设置合约帐号
    account.setContractAccount("XC" + Config.ACCOUNT_NAME + "@xuper");
    try {
    // 合约编译文件
    byte[] abi =
    Files.readAllBytes(Paths.get("/root/Desktop/pension/src/main/resources/--outputdir/PensionAccount.abi"));
    byte[] bin =
    Files.readAllBytes(Paths.get("/root/Desktop/pension/src/main/resources/--outputdir/PensionAccount.bin"));
    Map<String, String> params = new HashMap<>();
    params.put("creator", "XC" + Config.ACCOUNT_NAME + "@xuper");
    Transaction tx1 = client.deployEVMContract(account, bin, abi,
    Config.CONTRACT_NAME, params);
    System.out.println("tx: " + tx1.getContractResponse().getStatus());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

代码四 代码文件路径:java/src/mapper/PensionAccountMapper.java

创建PensionAccountMapper.java文件,编写入库接口。代码如下:

复制代码
    package src.mapper;
    import src.entity.PensionAccount;
    import org.apache.ibatis.annotations.Mapper;
    import org.springframework.stereotype.Repository;
    @Mapper
    @Repository
    public interface PensionAccountMapper {
    void savePensionAccount(PensionAccount pensionInfo);
    }

代码五 代码文件路径:java/src/entity/PensionAcoount.java

创建PensionAcoount.java文件,编写养老保险账户实体类 代码如下:

复制代码
    package src.entity;
    public class PensionAccount {
    private static final long serialVersionUID = 1L;
    private String walletAddress; //钱包地址(walletAddress)
    private Long personalBalance; //个人账户余额(personalBalance)
    private Long overallBalance; //总账户余额(overallBalance)
    private Boolean isSponsor; //雇主是否为职工的赞助商(isSponsor)
    private String insuredPersonName; //参保人姓名(insuredPersonName)
    private String insuredPersonIdentityCard; //参保人身份证
    (insuredPersonIdentityCard)
    private String insuredPersonWorkUnit; //参保人工作单位
    (insuredPersonWorkUnit)
    private Long workingYear; // 工作年限(workingYear)
    private Long salary; // 薪资(salary)
    private Long paymentBase; //缴费基数(paymentBase)
    public String getWalletAddress() {
    return walletAddress;
    }
    public void setWalletAddress(String walletAddress) {
    this.walletAddress = walletAddress;
    }
    public Long getPersonalBalance() {
    return personalBalance;
    }
    public void setPersonalBalance(Long personalBalance) {
    this.personalBalance = personalBalance;
    }
    public Long getOverallBalance() {
    return overallBalance;
    }
    public void setOverallBalance(Long overallBalance) {
    this.overallBalance = overallBalance;
    }
    public Boolean getSponsor() {
    return isSponsor;
    }
    public void setSponsor(Boolean sponsor) {
    isSponsor = sponsor;
    }
    public String getInsuredPersonName() {
    return insuredPersonName;
    }
    public void setInsuredPersonName(String insuredPersonName) {
    this.insuredPersonName = insuredPersonName;
    }
    public String getInsuredPersonIdentityCard() {
    return insuredPersonIdentityCard;
    }
    public void setInsuredPersonIdentityCard(String insuredPersonIdentityCard) {
    this.insuredPersonIdentityCard = insuredPersonIdentityCard;
    }
    public String getInsuredPersonWorkUnit() {
    return insuredPersonWorkUnit;
    }
    public void setInsuredPersonWorkUnit(String insuredPersonWorkUnit) {
    this.insuredPersonWorkUnit = insuredPersonWorkUnit;
    }
    public Long getWorkingYear() {
    return workingYear;
    }
    public void setWorkingYear(Long workingYear) {
    this.workingYear = workingYear;
    }
    public Long getSalary() {
    return salary;
    }
    public void setSalary(Long salary) {
    this.salary = salary;
    }
    public Long getPaymentBase() {
    return paymentBase;
    }
    public void setPaymentBase(Long paymentBase) {
    this.paymentBase = paymentBase;
    }
    }

创建AddPensionAccountResp.java文件,代码如下:

复制代码
    package src.entity;
    public class AddPensionAccountResp {
    private String address;
    private Integer balance;
    public String getAddress() {
    return address;
    }
    public void setAddress(String address) {
    this.address = address;
    }
    public Integer getBalance() {
    return balance;
    }
    public void setBalance(Integer balance) {
    this.balance = balance;
    }
    }

代码六 代码文件路径:java/src/controller/Controller.java 创建Controller.java文件,完成接口编写。代码如下:

复制代码
    package src.controller;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.baidu.xuper.api.*;
    import com.baidu.xuper.pb.XchainOuterClass;
    import com.google.protobuf.ByteString;
    import src.Config;
    import src.entity.AddPensionAccountResp;
    import src.entity.PensionAccount;
    import src.mapper.PensionAccountMapper;
    import org.springframework.util.Base64Utils;
    import org.springframework.web.bind.annotation.*;
    import javax.annotation.Resource;
    import java.math.BigInteger;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    @RestController
    @CrossOrigin(origins="*")
    public class Controller {
    @Resource
    private XuperClient xuperClient;
    @Resource
    private Account account;
    @Resource
    private PensionAccountMapper mapper;
    @RequestMapping(value = "/getBlockInformation")
    public Map<String, Object> getBlockInformation() {
    Map<String, Object> resMap = new HashMap<>();
    try {
    Map<String, Object> data = new HashMap<>();
    XchainOuterClass.BCStatus node1 =
    xuperClient.getBlockchainStatus("xuper");
    XchainOuterClass.InternalBlock block1 = node1.getBlock();
    long height = block1.getHeight();
    System.out.println("最新区块高度:" + height);
    data.put("height", height);
    // 获取最新区块交易Hash
    List<XchainOuterClass.Transaction> transactionsList =
    block1.getTransactionsList();
    if (transactionsList.size() > 0) {
    ByteString txid = transactionsList.get(transactionsList.size() -
    1).getTxid();
    System.out.println("最新区块交易Hash:" +
    Base64Utils.encodeToString(txid.toByteArray()));
    data.put("Hash",
    Base64Utils.encodeToString(txid.toByteArray()));
    }
    resMap.put("code", 200);
    resMap.put("message", "请求成功");
    resMap.put("data", data);
    } catch (Exception e) {
    resMap.put("code", 500);
    resMap.put("message", "请求失败");
    }
    return resMap;
    }
    @RequestMapping(value = "/addPensionAccount")
    @ResponseBody
    public Map<String, Object> addPensionAccount(@RequestBody PensionAccount
    pensionAccount) {
    Map<String, Object> resMap = new HashMap<>();
    try{
    Map<String, String> addPensionAccount = new HashMap<>();
    Account account1 = Account.create();
    AddressTrans evmAddress =
    AddressTrans.xChainToEvmAddress(account1.getAddress());
    addPensionAccount.put("walletAddress",evmAddress.getAddr());
    addPensionAccount.put("insuredPersonName",pensionAccount.getInsuredPersonName()
    );
    addPensionAccount.put("insuredPersonIdentityCard",
    pensionAccount.getInsuredPersonIdentityCard());
    addPensionAccount.put("insuredPersonWorkUnit",
    pensionAccount.getInsuredPersonWorkUnit());
    addPensionAccount.put("workingYear",
    pensionAccount.getWorkingYear().toString());
    addPensionAccount.put("salary",
    pensionAccount.getSalary().toString());
    addPensionAccount.put("paymentBase",
    pensionAccount.getPaymentBase().toString());
    Transaction getFlightInfo = xuperClient.invokeEVMContract(account,
    Config.CONTRACT_NAME, "addPensionAccount", addPensionAccount, BigInteger.ZERO);
    ContractResponse contractResponse =
    getFlightInfo.getContractResponse();
    String bodyStr = contractResponse.getBodyStr();
    AddPensionAccountResp resp=buildEntity(bodyStr);
    pensionAccount.setWalletAddress(account.getAddress());
    mapper.savePensionAccount(pensionAccount);
    resMap.put("code", 200);
    resMap.put("message", "请求成功");
    resMap.put("data", resp);
    } catch (Exception e){
    resMap.put("code", 500);
    resMap.put("message", "请求失败");
    }
    return resMap;
    }
    private AddPensionAccountResp buildEntity(String bodyStr){
    AddPensionAccountResp addPensionAccountResp = new
    AddPensionAccountResp();
    JSONArray objects = JSONObject.parseArray(bodyStr);
    String address = ((JSONObject)objects.get(0)).get(0).toString();
    Integer balance=
    Integer.decode(((JSONObject)objects.get(1)).get(1).toString());
    addPensionAccountResp.setAddress(address);
    addPensionAccountResp.setBalance(balance);
    return addPensionAccountResp;
    }
    }

代码七 代码文件路径:resources/mapper/PensionAccountMapper.xml 创建PensionAccountMapper.xml文件,编写入库sql。代码如下:

复制代码
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="src.mapper.PensionAccountMapper">
    <insert id="savePensionAccount">INSERT INTO pension_account
    (wallet_address, personal_balance, overall_balance, is_sponsor,
    insured_person_name, insured_person_identity_card, insured_person_work_unit,
    working_year, salary, payment_base)
    VALUES
    (#{walletAddress}, #{personalBalance}, #{overallBalance}, #{sponsor}, #
    {insuredPersonName}, #{insuredPersonIdentityCard}, #{insuredPersonWorkUnit}, #
    {workingYear}, #{salary}, #{paymentBase})
    </insert>
    </mapper>

4.引入依赖

右侧导航栏-Maven-重新加载所有Maven项目

在这里插入图片描述

5.启动项目

目录: java/src/PensionApplication.java

在这里插入图片描述

任务四:测试

1.测试 getBlockInformation 接口

浏览器访问:http://127.0.0.1:8090/getBlockInformation

2.测试前端页面

浏览器访问:http://172.25.103.2:8080/

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~