fabric-sdk-java 简单示例

    fabric Java SDK是Fabric区块链官方提供的用于Java应用开发的SDK,其链接如下:https://github.com/hyperledger/fabric-sdk-java

 fabric-geteway 也是Java SDK的一种,提供了更加便捷的API,官网地址为:https://github.com/hyperledger/fabric-gateway-java

fabric-gateway的使用:

1、导入maven

<dependency>
  <groupId>org.hyperledger.fabric</groupId>
  <artifactId>fabric-gateway-java</artifactId>
  <version>2.0.0</version>
</dependency>

2、将链上的crypto-config文件复制到resource

3、编写 connection.json,其中参数根据实际情况修改

{
    "name": "basic-network",
    "version": "1.0.0",
    "dependencies": {
    },
    "client": {
        "organization": "Org1",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "300"
                },
                "orderer": "300"
            }
        }
    },
    "channels": {
        "mychannel": {
            "orderers": [
                "orderer.example.com"
            ],
            "peers": {
                "peer0.org1.example.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "ledgerQuery": true,
                    "eventSource": true
                },
                "peer0.org2.example.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "ledgerQuery": true,
                    "eventSource": true
                }
            }
        }
    },
    "organizations": {
        "Org1": {
            "mspid": "Org1MSP",
            "peers": [
                "peer0.org1.example.com"
            ],
            "certificateAuthorities": [
                "ca-org1"
            ],
            "adminPrivateKeyPEM": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/383afd7e044f36903e4149d28398cc38e489739998ece0fc36b19de0dc986523_sk"
            },
            "signedCertPEM": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"
            }
        },
        "Org2": {
            "mspid": "Org2MSP",
            "peers": [
                "peer0.org2.example.com"
            ],
            "certificateAuthorities": [
                "ca-org2"
            ],
            "adminPrivateKeyPEM": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore/3d30d033c6084a9478478e4e355ba49b51fdc2f55cc0c04e6792a017f274227a_sk"
            },
            "signedCertPEM": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts/Admin@org2.example.com-cert.pem"
            }
        }
    },
    "orderers": {
        "orderer.example.com": {
            "url": "grpcs://192.168.10.128:7050",
            "mspid": "OrdererMSP",
            "grpcOptions": {
                "ssl-target-name-override": "orderer.example.com",
                "hostnameOverride": "orderer.example.com"
            },
            "tlsCACerts": {
                "path": "src/main/resources/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"
            },
            "adminPrivateKeyPEM": {
                "path": "src/main/resources/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/msp/keystore/11c4ce44268e8f217e077f87cd1fc58c94e1f664bdfd6297f1455d2ec1fb0646_sk"
            },
            "signedCertPEM": {
                "path": "src/main/resources/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/msp/signcerts/Admin@example.com-cert.pem"
            }
        }
    },
    "peers": {
        "peer0.org1.example.com": {
            "url": "grpcs://192.168.10.128:7051",
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org1.example.com",
                "hostnameOverride": "peer0.org1.example.com",
                "request-timeout": 120001
            },
            "tlsCACerts": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
            }
        },
        "peer0.org2.example.com": {
            "url": "grpcs://192.168.10.128:9051",
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org2.example.com",
                "hostnameOverride": "peer0.org2.example.com",
                "request-timeout": 120001
            },
            "tlsCACerts": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
            }
        }
    },
    "certificateAuthorities": {
        "ca-org1": {
            "url": "https://192.168.10.128:7054",
            "grpcOptions": {
                "verify": true
            },
            "tlsCACerts": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"
            },
            "registrar": [
                {
                    "enrollId": "admin",
                    "enrollSecret": "adminpw"
                }
            ]
        },
        "ca-org2": {
            "url": "https://192.168.10.128:8054",
            "grpcOptions": {
                "verify": true
            },
            "tlsCACerts": {
                "path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem"
            },
            "registrar": [
                {
                    "enrollId": "admin",
                    "enrollSecret": "adminpw"
                }
            ]
        }
    }
}

3、fabric.config.properties ,其中的通道名称,链码名称以及私钥路径根据实际情况

# 网络配置文件路径
networkConfigPath = src/main/resources/connection.json
# 用户证书路径
certificatePath = src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem
# 用户私钥路径
privateKeyPath = src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/59157e7b19fe2eacad4baca256296e93022c51e5bc0102eec4e0b23f54db85f8_sk

# 通道名字
channelName = mychannel

# 链码名字
contractName = mylocks

资源下的文件结构如下:

4、sdk的调用,代码编写:

package com.example.fabric.demo.test;

import org.hyperledger.fabric.gateway.*;
import org.hyperledger.fabric.sdk.Peer;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.EnumSet;
import java.util.Properties;

/**
 * @Description:
 * @author: caib
 * @Date: 2021/07/15/11:27
 */
public class SdkDemo {

    public static void main(String[] args) {
        try {
            //获取相应参数
            Properties properties = new Properties();
            InputStream inputStream = SdkDemo.class.getResourceAsStream("/fabric.config.properties");
            properties.load(inputStream);

            String networkConfigPath = properties.getProperty("networkConfigPath");
            String channelName = properties.getProperty("channelName");
            String contractName = properties.getProperty("contractName");
            //使用org1中的user1初始化一个网关wallet账户用于连接网络
            String certificatePath = properties.getProperty("certificatePath");
            X509Certificate certificate = readX509Certificate(Paths.get(certificatePath));

            String privateKeyPath = properties.getProperty("privateKeyPath");
            PrivateKey privateKey = getPrivateKey(Paths.get(privateKeyPath));

            Wallet wallet = Wallets.newInMemoryWallet();
            wallet.put("user1", Identities.newX509Identity("Org1MSP",certificate,privateKey));

            //根据connection.json 获取Fabric网络连接对象
            Gateway.Builder builder = Gateway.createBuilder()
                    .identity(wallet, "user1")
                    .networkConfig(Paths.get(networkConfigPath));
            //连接网关
            Gateway gateway = builder.connect();
            //获取通道
            Network network = gateway.getNetwork(channelName);
            //获取合约对象
            Contract contract = network.getContract(contractName);
            //查询现有资产
            //注意更换调用链码的具体函数
            byte[] queryAllAssets = contract.evaluateTransaction("queryAllLocks");
            System.out.println("所有资产:"+new String(queryAllAssets, StandardCharsets.UTF_8));

            // 增加新的资产
            byte[] invokeResult = contract.createTransaction("initLock")
                    .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)))
                    .submit("L00A", "TEST001", "");
            System.out.println(new String(invokeResult, StandardCharsets.UTF_8));

            //查询更新后的资产
            byte[] queryAllAssetsAfter = contract.evaluateTransaction("queryAllLocks");
            System.out.println("更新资产:"+new String(queryAllAssetsAfter, StandardCharsets.UTF_8));

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static X509Certificate readX509Certificate(final Path certificatePath) throws IOException, CertificateException {
        try (Reader certificateReader = Files.newBufferedReader(certificatePath, StandardCharsets.UTF_8)) {
            return Identities.readX509Certificate(certificateReader);
        }
    }

    private static PrivateKey getPrivateKey(final Path privateKeyPath) throws IOException, InvalidKeyException, IOException {
        try (Reader privateKeyReader = Files.newBufferedReader(privateKeyPath, StandardCharsets.UTF_8)) {
            return Identities.readPrivateKey(privateKeyReader);
        }
    }
}

Fabric-sdk-java

以下需用到crypto-config的资源

1、引入依赖,如果以及引入了gateway的依赖,此步骤可省略

<dependency>
<groupId>org.hyperledger.fabric-sdk-java</groupId>
<artifactId>fabric-sdk-java</artifactId>
<version>1.4.7</version>
</dependency>

2、编写LocalUser,实现User接口

/**
 * @Description:
 * @author: caib
 * @Date: 2021/07/15/14:11
 */
public class LocalUser implements User {             //实现User接口
    private String name;
    private String mspId;
    private Enrollment enrollment;

    LocalUser(String name, String mspId ,String keyFile, String certFile ) throws Exception {
        this.name = name;
        this.mspId = mspId;
        this.enrollment = loadFromPemFile(keyFile,certFile);
    }

    private Enrollment loadFromPemFile(String keyFile, String certFile) throws Exception {
        //载入私钥PEM文本
        byte[] keyPem = Files.readAllBytes(Paths.get(keyFile));
        //载入证书PEM文本
        byte[] certPem = Files.readAllBytes(Paths.get(certFile));
        //载入密码学套件
        CryptoPrimitives suite = new CryptoPrimitives();
        //将PEM文本转换为私钥对象
        PrivateKey privateKey = suite.bytesToPrivateKey(keyPem);
        //创建并返回X509Enrollment对象
        return new X509Enrollment(privateKey,new String(certPem));
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Set<String> getRoles() {
        return null;
    }

    @Override
    public String getMspId() {
        return mspId;
    }

    @Override
    public Enrollment getEnrollment() {
        return enrollment;
    }

    @Override
    public String getAccount() {
        return null;
    }

    @Override
    public String getAffiliation() {
        return null;
    }
}

3、sdk调用

/**
 * @Description:
 * @author: caib
 * @Date: 2021/07/15/15:51
 */
public class Chaincode {

    private static final String Crypto_Config_Path = "D:\ideaProjects\fabric-sdk-demo\src\main\resources\crypto-config\";

    private static final String CA_Pemfile = Crypto_Config_Path+"peerOrganizations\org1.example.com\ca\ca.org1.example.com-cert.pem";

    private String adminKeyFile = Crypto_Config_Path+"peerOrganizations\" +
            "org1.example.com\users\Admin@org1.example.com\msp\keystore\383afd7e044f36903e4149d28398cc38e489739998ece0fc36b19de0dc986523_sk";
    private String adminCertFile = Crypto_Config_Path+"peerOrganizations\org1.example.com\users\Admin@org1.example.com\" +
            "msp\signcerts\Admin@org1.example.com-cert.pem";

    private HFClient client;
    private Channel channel;

    HFClient InitClient() throws  Exception{
        this.client = HFClient.createNewInstance();
        client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());
        client.setUserContext(new LocalUser("admin", "Org1MSP", adminKeyFile, adminCertFile));
        return client;
    }


    void CreateChannelIns(String channelName) throws  Exception{
        this.channel = client.newChannel(channelName);
        Properties proper;
        proper = loadTLSFile("peerOrganizations\org1.example.com\peers\peer0.org1.example.com\msp\tlscacerts\tlsca.org1.example.com-cert.pem", "peer0.org1.example.com");
        Peer peer = client.newPeer("peer0.org1.example.com","grpcs://192.168.10.128:7051", proper);
        channel.addPeer(peer);
        proper = loadTLSFile("ordererOrganizations\example.com\orderers\orderer.example.com\msp\tlscacerts\tlsca.example.com-cert.pem", "orderer.example.com");
        Orderer orderer = client.newOrderer("orderer1.example.com","grpcs://192.168.10.128:7050", proper);
        channel.addOrderer(orderer);
        channel.initialize();
    }

    /**
     * 为Fabric网络中节点配置TLS根证书
     *
     * @param rootTLSCert 根证书路径
     * @param hostName    节点域名
     * @return
     * @throws IOException
     */
    private static Properties loadTLSFile(String rootTLSCert, String hostName) throws IOException {
        Properties properties = new Properties();
        properties.put("pemBytes", Files.readAllBytes(Paths.get( Crypto_Config_Path + rootTLSCert)));
        properties.setProperty("sslProvider", "openSSL");
        properties.setProperty("negotiationType", "TLS");
        properties.setProperty("trustServerCertificate", "true");
        properties.setProperty("hostnameOverride", hostName);
        return properties;
    }

    void Query() throws Exception{
        QueryByChaincodeRequest req = this.client.newQueryProposalRequest();
        ChaincodeID cid = ChaincodeID.newBuilder().setName("mylocks").build();
        req.setChaincodeID(cid);
        req.setFcn("queryAllUsers");
        req.setArgs("a");
        ProposalResponse[] rsp = this.channel.queryByChaincode(req).toArray(new ProposalResponse[0]);
        System.out.format("rsp message => %s
",rsp[0].getProposalResponse().getResponse().getPayload().toStringUtf8());
    }

    void Query(String chainCodeName, String funcName , String... args) throws Exception{
        QueryByChaincodeRequest req = this.client.newQueryProposalRequest();
        ChaincodeID cid = ChaincodeID.newBuilder().setName(chainCodeName).build();
        req.setChaincodeID(cid);
        req.setFcn(funcName);
        req.setArgs(args);
//        req.setChaincodeEndorsementPolicy();
        ProposalResponse[] rsp = this.channel.queryByChaincode(req).toArray(new ProposalResponse[0]);
        System.out.format("rsp message => %s
",rsp[0].getProposalResponse().getResponse().getPayload().toStringUtf8());
    }

    void Invode () throws Exception {
        QueryByChaincodeRequest req = this.client.newQueryProposalRequest();
        ChaincodeID cid = ChaincodeID.newBuilder().setName("mylocks").build();
        //提交链码交易
        TransactionProposalRequest req2 = client.newTransactionProposalRequest();
        req2.setChaincodeID(cid);
        req2.setFcn("inc");
        req2.setArgs("10");
        Collection<ProposalResponse> rsp2 = channel.sendTransactionProposal(req2);
        BlockEvent.TransactionEvent event = channel.sendTransaction(rsp2).get();
        System.out.format("txid: %s
", event.getTransactionID());
        System.out.format("valid: %b
", event.isValid());
    }

}

4、main方法执行验证

    public static void main( String[] args ) {
        Chaincode c = new Chaincode();
        try {
            c.InitClient();
            c.CreateChannelIns("mychannel");
            c.Query();
            c.Invode();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
原文地址:https://www.cnblogs.com/luyilan/p/15016703.html