hex java sdk,fabric1.4.x java-sdk使用

参考链接

sdk-github 可以看看里面的例子,不过封装的好深,我对java也不是很熟,看起来有点费劲。里面很多都是写在配置里,或者在一些类里封装的。

代码

先上代码

参考上面的帖子,需要要实现一个User的类,来实例化一个user对象。

LocalUser

public class LocalUser implements User {

private boolean TLS_ENABLE = true;

private String name;

private String mspID;

private Enrollment enrollment;

LocalUser(String name, String mspID){

this.name = name;

this.mspID = mspID;

}

LocalUser(String name, String mspID, String keyFile, String certFile) throws Exception{

this(name, mspID);

this.enrollment = loadFromPemFile(keyFile, certFile);

if (TLS_ENABLE == true) {

}

}

private Enrollment loadFromPemFile(String keyFile,String certFile) throws Exception{

byte[] sk = Files.readAllBytes(Paths.get(keyFile)); //载入私钥

byte[] certPem = Files.readAllBytes(Paths.get(certFile)); //载入证书PEM文本

CryptoPrimitives suite = new CryptoPrimitives(); //载入密码学套件

PrivateKey privateKey = suite.bytesToPrivateKey(sk); //将PEM文本转换为私钥对象

return new X509Enrollment(privateKey,new String(certPem)); //创建并返回X509Enrollment对象

}

@Override

public String getName(){return name;}

@Override

public String getMspId(){return mspID;}

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

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

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

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

static String getPEMStringFromPrivateKey(PrivateKey privateKey) throws IOException {

StringWriter pemStrWriter = new StringWriter();

PEMWriter pemWriter = new PEMWriter(pemStrWriter);

pemWriter.writeObject(privateKey);

pemWriter.close();

return pemStrWriter.toString();

}

}

我把关键逻辑都封装在 ChainCode.java了

public class ChainCode {

private static final String Crypto_Config_Path = "D:\\prj\\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\\d1bc2f6f9dd1fdc6a90c32f203983870e7189131ca90493281f97bfe87ddcaa8_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() throws Exception{

this.channel = client.newChannel("contractchannel");

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.169.0.86:7051", proper);

channel.addPeer(peer);

proper = loadTLSFile("ordererOrganizations\\example.com\\orderers\\orderer1.example.com\\msp\\tlscacerts\\tlsca.example.com-cert.pem", "orderer1.example.com");

Orderer orderer = client.newOrderer("orderer1.example.com","grpcs://192.169.0.86: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("contract").build();

req.setChaincodeID(cid);

req.setFcn("query");

req.setArgs("a");

// 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());

}

}

public class App

{

public static void main( String[] args ) {

ChainCode c = new ChainCode();

try {

c.InitClient();

c.CreateChannelIns();

c.Query();

}catch (Exception e){

e.printStackTrace();

}

}

}

注意事项

网络环境

fabric 1.4.2

java-fabric-sdk 2.0.0 release

未开启fabric-ca服务

开启TLS

踩坑

HFClient

因为开启了tls,我刚开始看javasdk里面的ene2endit这个示例,以为要用HFCAClient这个类初始化,后面又搜了一圈,发现不用。第一个坑点。只需要HFClient。

User证书

580eb20d0a74

用户证书结构

初始化User的时候,传入Admin的私钥,和证书pem。为什么要admin的?这个应该跟policy配置有关,在configtx.yaml中,具体我还没研究过。回头再看

开启TLS必须配置 peer和orderer证书

580eb20d0a74

peer证书结构

这么多证书看着有点乱。我还没完全理解各个证书的关系和作用。

大概区分一下 msp是用来鉴权的,直白的说就是确定你是不是你,主要用来确认身份用的。

tls是加密通讯的证书,跟区块链的身份鉴权是两个东西,别混淆了(我暂时是这么理解的)。

需注意tls/ca.crt 跟

msp/tlscacerts/tlsca.org1.xxx.com-cert.pem 内容是一样的。

用于tls通讯的根证书。所以在传入根证书的时候,两个任意一个都可以。

properties.put("pemBytes", Files.readAllBytes(Paths.get( Crypto_Config_Path + rootTLSCert)));

properties.put("pemFile", Paths.get( Crypto_Config_Path + rootTLSCert));

上面的代码,二选一都可以,不一定要传入字符串。

报错处理

org.hyperledger.fabric.sdk.exception.ProposalException:

org.hyperledger.fabric.sdk.exception.TransactionException:

org.hyperledger.fabric.sdk.exception.ProposalException:

getConfigBlock for channel contractchannel failed with peer peer0.org1.example.com. Status FAILURE, details:

Channel Channel{id: 1, name: contractchannel} Sending proposal with transaction:

d795243d5dc706d8d7b2baafe7cdcf66343cd83d93aeb23c3363124724ea54de to Peer{ id: 2, name: peer0.org1.example.com, channelName:

contractchannel, url: grpc://192.169.0.86:7051} failed because of:

gRPC failure=Status{code=INTERNAL, description=http2 exception, cause=io.netty.handler.codec.http2.Http2Exception:

First received frame was not SETTINGS. Hex dump for first 5 bytes: 1503010002

百度谷歌了一圈,确认不了是什么问题,但是隐约觉得是tls的配置问题。

查看peer0的日志,发现了问题所在。

docker logs 23ef8ad2f248 -t --since="2020-04-01" --tail=50

查看peer0最后50条日志。

2020-04-01T03:41:03.038774384Z 2020-04-01 03:41:03.038 UTC [core.comm]

ServerHandshake ->

ERRO 10f8 TLS handshake failed with error tls: first record does not look like a TLS handshake

{"server": "PeerServer", "remote address": "192.169.0.145:62931"}

不是TLS握手,说明tls有问题。

其实是个很小的问题,特别容易忽略,在看别人代码的时候,我就注意到有个地方很奇怪。

Peer peer = client.newPeer("peer0.org1.example","grpcs://192.169.0.86:7051", proper);

注意url,必须写grpcs,而不是grpc!

之前我就注意到,有点例子里面写的是grpc,有的写的是grpcs。加上s,完美解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值