Hyperledger Fabric使用Java自定义智能合约

Hyperledger Fabric使用Java自定义智能合约,第1张

文章目录 Hyperledger Fabric使用Java自定义智能合约一、前提二、我的主要文件目录三、开始啦1、启动测试网络2、创建通道3、配置环境变量4、合约代码5、打包合约源代码6、安装链码7、查看已安装的合约清单8、审批合约9、合约提交检查10、向通道提交合约11、测试啦 四、到最后了

Hyperledger Fabric使用Java自定义智能合约 一、前提

首先要搭建好fabric测试网络

搭建方法:进去看看吧
https://blog.csdn.net/weixin_51799151/article/details/123315317?spm=1001.2014.3001.5502

二、我的主要文件目录

三、开始啦 1、启动测试网络

进入 test-network 目录下,./network.sh up

启动成功之后会生成一个 orderer节点 和两个 peer节点

2、创建通道
./network.sh createChannel [-c 通道名]

不写通道名 默认为 mychannel

3、配置环境变量
export FABRIC_PATH=/fabric/scripts/fabric-samples
export FABRIC_CFG_PATH=${FABRIC_PATH}/config/
export MSP_PATH=${FABRIC_PATH}/test-network/organizations
export CORE_PEER_TLS_ENABLED=true
export PATH=${FABRIC_PATH}/bin:$PATH

FABRIC_PATH 根据自己的实际路径修改

4、合约代码

配置远程仓库和javasdk和各种插件


<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.0modelVersion>

    <groupId>com.atmae.fabricgroupId>
    <artifactId>smart-contractartifactId>
    <name>smart-contractname>
    <version>1.0-SNAPSHOTversion>
    <description>fabric智能合约description>
    <properties>
        <java.version>1.8java.version>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <fabric-chaincode-java.version>2.4.1fabric-chaincode-java.version>
        <fastjson.version>1.2.79fastjson.version>
        <logback.version>1.2.0logback.version>
        <slf4j.version>1.7.5slf4j.version>
    properties>
    <repositories>
        <repository>
            <id>centralid>
            <url>http://maven.aliyun.com/nexus/content/groups/public/url>
            <releases>
                <enabled>trueenabled>
            releases>
            <snapshots>
                <enabled>falseenabled>
            snapshots>
        repository>
        <repository>
            <id>jitpack.ioid>
            <url>https://www.jitpack.iourl>
        repository>
        <repository>
            <id>artifactoryid>
            <url>https://hyperledger.jfrog.io/hyperledger/fabric-mavenurl>
        repository>
    repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>centralid>
            <name>Maven China Mirrorname>
            <url>http://maven.aliyun.com/nexus/content/groups/public/url>
            <releases>
                <enabled>trueenabled>
            releases>
            <snapshots>
                <enabled>falseenabled>
            snapshots>
        pluginRepository>
    pluginRepositories>
    <dependencies>
        <dependency>
            <groupId>org.hyperledger.fabric-chaincode-javagroupId>
            <artifactId>fabric-chaincode-shimartifactId>
            <version>${fabric-chaincode-java.version}version>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>${fastjson.version}version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>RELEASEversion>
            <scope>compilescope>
        dependency>
    dependencies>

    <build>
        <sourceDirectory>src/main/javasourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-pluginartifactId>
                <version>3.1version>
                <configuration>
                    <source>${java.version}source>
                    <target>${java.version}target>
                configuration>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-shade-pluginartifactId>
                <version>3.1.0version>
                <executions>
                    <execution>
                        <phase>packagephase>
                        <goals>
                            <goal>shadegoal>
                        goals>
                        <configuration>
                            <finalName>chaincodefinalName>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>org.hyperledger.fabric.contract.ContractRoutermainClass>
                                transformer>
                            transformers>
                            <filters>
                                <filter>
                                    
                                    <artifact>*:*artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SFexclude>
                                        <exclude>META-INF/*.DSAexclude>
                                        <exclude>META-INF/*.RSAexclude>
                                    excludes>
                                filter>
                            filters>
                        configuration>
                    execution>
                executions>
            plugin>
        plugins>
    build>
project>

合约数据对象:使用@DataType 注解标识,字段使用 @Property 注解标识

package com.atmae.fabric.entity;

import org.hyperledger.fabric.contract.annotation.DataType;
import org.hyperledger.fabric.contract.annotation.Property;

import java.util.Objects;

/**
 * @Author: Mae
 * @Date: 2022/4/18
 * @Time: 12:27
 * @Description: 用户信息
 */
@DataType
public class User{

    @Property
    private final Long id;

    @Property
    private  Double money;

    public Long getId() {
        return id;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public User(Long id, Double money) {
        this.id = id;
        this.money = money;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        User user = (User) o;
        return Objects.equals(id, user.id) && Objects.equals(money, user.money);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, money);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", money=" + money +
                '}';
    }
}
package com.atmae.fabric;

import com.alibaba.fastjson.JSON;
import com.atmae.fabric.entity.InsureDeal;
import com.atmae.fabric.entity.User;
import org.hyperledger.fabric.contract.Context;
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.annotation.Contact;
import org.hyperledger.fabric.contract.annotation.Default;
import org.hyperledger.fabric.contract.annotation.Transaction;
import org.hyperledger.fabric.shim.ChaincodeException;
import org.hyperledger.fabric.shim.ChaincodeStub;

/**
 * @Author: Mae
 * @Date: 2022/4/18
 * @Time: 10:33
 * @Description: 保险合约
 */
@Contact(name = "insure")
@Default
public class InsureChaincode implements ContractInterface {

    /**
     * 利率
     */
    private final Double LV = 0.8d;

    public InsureChaincode() {
    }

    /**
     * 增加一个用户
     *
     * @param cxt
     * @param user
     * @return
     */
    @Transaction(intent = Transaction.TYPE.SUBMIT)
    public String addUser(final Context cxt, final User user) {
        ChaincodeStub stub = cxt.getStub();
        String personJson = JSON.toJSONString(user);
        stub.putStringState(String.valueOf(user.getId()), personJson);
        return stub.getTxId();
    }

    /**
     * 查询某个用户
     */
    @Transaction(intent = Transaction.TYPE.EVALUATE)
    public User getUser(final Context ctx, final String userId) {
        ChaincodeStub stub = ctx.getStub();
        String userJSON = stub.getStringState(userId);
        if (userJSON == null || userJSON.isEmpty()) {
            String errorMessage = "对不起,当前用户不存在";
            throw new ChaincodeException(errorMessage);
        }
        return JSON.parseObject(userJSON, User.class);
    }

合约逻辑:
合约类使用 @Contract@Default 注解标识并实现 ContractInterface 接口

合约方法使用 @Transaction 注解标识

Transaction.TYPE.SUBMIT 为 「写入交易」
Transaction.TYPE.EVALUATE 为 「查询」
5、打包合约源代码

我的合约源代码放在chaincode目录下

peer lifecycle chaincode package insure.tar.gz --path ../chaincode/insure --lang java --label insure

查看:

6、安装链码

在指定 peer 节点上安装链码。
peer0.org1:

设置环境:

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${MSP_PATH}/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${MSP_PATH}/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

安装链码:

peer lifecycle chaincode install insure.tar.gz


看的蓝色就特别开心 😃😃

peer0.org2:
设置环境:

export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${MSP_PATH}/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${MSP_PATH}/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

安装链码:

peer lifecycle chaincode install insure.tar.gz

7、查看已安装的合约清单
peer lifecycle chaincode queryinstalled

记住(复制就行了呗):package-id

8、审批合约

org1:

设置环境:

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${MSP_PATH}/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${MSP_PATH}/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

审批合约:

peer lifecycle chaincode approveformyorg \
  -o localhost:7050 \
  --ordererTLSHostnameOverride orderer.example.com \
  --tls\
  --cafile ${MSP_PATH}/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --channelID mychannel \
  --name insure\
  --version 1.0 \
  --package-id insure:4c8dce2c7f746d26293ca8f27a3ccdec3b4b38091f873f40f8ac9508c02029bc \
  --sequence 1

别忘了!修改package-id!

org2:
设置环境:

export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${MSP_PATH}/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${MSP_PATH}/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

审批合约:

peer lifecycle chaincode approveformyorg \
  -o localhost:7050 \
  --ordererTLSHostnameOverride orderer.example.com \
  --tls \
  --cafile ${MSP_PATH}/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --channelID mychannel \
  --name insure \
  --version 1.0 \
  --package-id insure:4c8dce2c7f746d26293ca8f27a3ccdec3b4b38091f873f40f8ac9508c02029bc \
  --sequence 1

别忘了!修改package-id!

9、合约提交检查
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name insure --version 1.0 --sequence 1 --output json

都说true说明成功

10、向通道提交合约
peer lifecycle chaincode commit \
  -o localhost:7050 \
  --ordererTLSHostnameOverride orderer.example.com \
  --tls \
  --cafile ${MSP_PATH}/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --channelID mychannel \
  --name insure \
  --peerAddresses localhost:7051 \
  --tlsRootCertFiles ${MSP_PATH}/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
  --peerAddresses localhost:9051 \
  --tlsRootCertFiles ${MSP_PATH}/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
  --version 1.0 \
  --sequence 1

查看通道上已经提交的合约清单:

peer lifecycle chaincode querycommitted --channelID mychannel --name insure --output json

11、测试啦

invoke参数较多,我们建一个脚本命令
vim invoke.sh

peer chaincode invoke -o localhost:7050 \
  --ordererTLSHostnameOverride orderer.example.com \
  --tls \
  --cafile ${MSP_PATH}/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  -C mychannel \
  -n insure \
  --peerAddresses localhost:7051 \
  --tlsRootCertFiles ${MSP_PATH}/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
  --peerAddresses localhost:9051 \
  --tlsRootCertFiles ${MSP_PATH}/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
  -c ${1}

添加数据,查询数据:
连接其中一个节点,设置环境:

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${MSP_PATH}/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${MSP_PATH}/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

增、查

sh invoke.sh '{"function":"addUser","Args":[1,200]}'
peer chaincode query -C mychannel -n insure -c '{"Args":["getUser", 1]}'
四、到最后了

👆👆👆👆👆👆👆 最后,希望大家都能够测试成功!!!👆👆👆👆👆👆

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/925214.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存