Fabric Java SDK 1.4简明教程
在超级账本Fabric区块链中,应用通过节点的RPC协议接口访问链码。Java应用可以使用官方提供的Fabric-sdk-java开发包来实现对链码的访问,java开发包封装了Fabric区块链的GRPC链码访问协议,有利于开发人员聚焦于业务逻辑。本文将通过编写一个最简单的可以访问Fabric链码的Java应用,来帮助你快速上手Fabric区块链的Java应用开发。
如果希望快速掌握Fabric区块链的链码及应用开发,建议访问汇智网的在线互动课程:
基本原理
在Fabric区块链中,应用通过节点的RPC协议接口访问链码:
类似于Shim API对链码通信协议的封装,Fabric Java SDK提供了 对节点RPC协议
接口的封装,其入口类为HFClient,对链码的查询和交易操作则 封装在Channel类中:
由于Fabric是许可制区块链,因此应用也需要持有证书和私钥以表征自己的身份,HFClient实例 依赖于User接口的实现对象
来访问一个特定身份的证书和私钥,因此在访问 链码之前,我们需要首先定义一个简单的User接口实现类。
实现User接口
HFClient
实例访问Fabric网络的身份使用User
接口实现对象来表征,因此我们需要定义一个简单的
User接口实现类LocalUser
:
容易理解,一个用户的身份是由它的证书来标识的,同时交易还需要证书对应的私钥,因此LocalUser
的核心逻辑就是利用指定的证书和私钥PEM文件满足User接口的要求。
首先按照User接口的要求完成类LocalUser
的骨架:
import org.hyperledger.fabric.sdk.User; import org.hyperledger.fabric.sdk.security.CryptoPrimitives; public class LocalUser implements User{ //实现User接口 private String name; private String mspId; private Enrollment enrollment; LocalUser(String name,String mspId){ this.name = name; this.mspId = mspId; } private Enrollment loadFromPemFile(String keyFile,String certFile){ /*见下文说明*/ } @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; } }
在Fabric Java SDK中,Enrollment
接口用来提供对用户的私钥和证书的访问, 并且预置了一个适合
X509证书的实现类X509Enrollment
,因此我们可以从本地 MSP目录中的PEM文件中载入用户私钥和签名证书:
private Enrollment loadFromPemFile(String keyFile,String certFile) throws Exception{ byte[] keyPem = Files.readAllBytes(Paths.get(keyFile)); //载入私钥PEM文本 byte[] certPem = Files.readAllBytes(Paths.get(certFile)); //载入证书PEM文本 CryptoPrimitives suite = new CryptoPrimitives(); //载入密码学套件 PrivateKey privateKey = suite.bytesToPrivateKey(keyPem); //将PEM文本转换为私钥对象 return new X509Enrollment(privateKey,new String(certPem)); //创建并返回X509Enrollment对象 }
访问链码
有了User接口实现类,接下来只要创建一个HFClient实例,然后获取通道对象,
就可以查询链码,或者提交链码交易了。
完整的实现代码如下:
package com.hubwiz.demo; import org.hyperledger.fabric.sdk.User; import org.hyperledger.fabric.sdk.HFClient; import org.hyperledger.fabric.sdk.Channel; import org.hyperledger.fabric.sdk.Peer; import org.hyperledger.fabric.sdk.Orderer; import org.hyperledger.fabric.sdk.security.CryptoSuite; import org.hyperledger.fabric.sdk.ChaincodeID; import org.hyperledger.fabric.sdk.QueryByChaincodeRequest; import org.hyperledger.fabric.sdk.ProposalResponse; import org.hyperledger.fabric.sdk.TransactionProposalRequest; import org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent; import java.util.Collection; import java.util.concurrent.CompletableFuture; public class App{ public static void main(String[] args) throws Exception{ System.out.println("counter app"); //创建User实例 String keyFile = "../solo-network/msp/keystore/user-key.pem"; String certFile = "../solo-network/msp/signcerts/user-cert.pem"; LocalUser user = new LocalUser("admin","SampleOrg",keyFile,certFile); //创建HFClient实例 HFClient client = HFClient.createNewInstance(); client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite()); client.setUserContext(user); //创建通道实例 Channel channel = client.newChannel("ch1"); Peer peer = client.newPeer("peer1`","grpc://127.0.0.1:7051"); channel.addPeer(peer); Orderer orderer = client.newOrderer("orderer1","grpc://127.0.0.1:7050"); channel.addOrderer(orderer); channel.initialize(); //查询链码 QueryByChaincodeRequest req = client.newQueryProposalRequest(); ChaincodeID cid = ChaincodeID.newBuilder().setName("counter-cc").build(); req.setChaincodeID(cid); req.setFcn("value"); ProposalResponse[] rsp = channel.queryByChaincode(req).toArray(new ProposalResponse[0]); System.out.format("rsp message => %s\n",rsp[0].getProposalResponse().getResponse().getPayload().toStringUtf8()); //提交链码交易 TransactionProposalRequest req2 = client.newTransactionProposalRequest(); req2.setChaincodeID(cid); req2.setFcn("inc"); req2.setArgs("10"); Collection<ProposalResponse> rsp2 = channel.sendTransactionProposal(req2); TransactionEvent event = channel.sendTransaction(rsp2).get(); System.out.format("txid: %s\n", event.getTransactionID()); System.out.format("valid: %b\n", event.isValid()); } }
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
好程序员web前端培训分享javascript关联数组用法总结
好程序员web前端培训分享javascript关联数组用法总结,有需要的朋友可以参考下。 Hash关联数组定义代码如下// 定义空数组myhash = { }// 直接定义数组myhash = {"key1":"val1","key2":"val2" }// 用Array 定义数组myhash = new Array();myhash["key1"] = "val1";myhash["key2"] = "val2"; 向Hash关联数组添加键值代码如下// 添加一个新键 newkey ,键值为 newvalmyhash[”newkey”] = “newval”; 删除Hash关联数组已有键值代码如下// 删除一个键 newkey ,同时,该键值对应的 newval 也就消失了。delete myhash[”newkey”]; 遍历Hash关联数组代码如下 复制代码// 遍历整个hash 数组for (key in myhash) {val = myhash[key];} Hash关联数组简易使用示例代码如下 例如://这里主要是说明 对于关联数组的遍历,首先定义一个数组:代码如下var...
- 下一篇
Metamask为什么取不到账号?
当你使用Metamask测试以太坊DApp时,如果出现莫名其妙的问题,检查一下web3.eth.accounts是否可以获取到账户,如果不能获取的话,那么最大的可能是你使用了新版的Metamask,并且默认启用了隐私模式。 有两种办法来让你的DApp可以正常访问Metamask管理的账户:关闭隐私模式,或者修改JavaScript代码使其兼容Metamask的隐私模式。 一、关闭隐私模式 在metamask中首先进入设置,然后点击security & privacy,在隐私模式菜单,选择关闭隐私模式即可: 二、兼容隐私模式 在2018年11月,Metamask刚引入隐私模式时,该选项默认是关闭的。但是在最新的版本中,已经默认开启了隐私模式。要求每个用户都手动关闭隐私模式是不现实的,因此更好的方案是修改我们的JavaScript代码来兼容隐私模式: window.addEventListener('load', async () => { // Modern dapp browsers... if (window.ethereum) { window.web3 = new ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- 2048小游戏-低调大师作品
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Mario游戏-低调大师作品
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker使用Oracle官方镜像安装(12C,18C,19C)