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\n",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\n",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\n", event.getTransactionID());
        System.out.format("valid: %b\n", 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();
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM