zoukankan      html  css  js  c++  java
  • 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();
            }
        }
  • 相关阅读:
    OSError: [Errno 13] Permission denied: '/Library/Python/2.7/site-packages/django'
    mac 安装pip
    同学公司倒闭了
    web开发中的字体选择(同事分享)
    svg 学习笔记
    用highchaarts做股票分时图
    highcharts,highStock 中文图表配置
    为什么使用 npm Scripts 构建项目
    JS 浮点型计算的精度问题 推荐的js 库 推荐的类库 Numeral.js 和 accounting.js
    HTML代码转换为JavaScript字符串
  • 原文地址:https://www.cnblogs.com/luyilan/p/15016703.html
Copyright © 2011-2022 走看看