├── README.md └── app.java /README.md: -------------------------------------------------------------------------------- 1 | 课程地址:[http://xc.hubwiz.com/course/5c9b89f54898e59b7b63430a](http://xc.hubwiz.com/course/5c9b89f54898e59b7b63430a?affid=0328github) 2 | 3 | 4 | Hyperledger是一个旨在推动区块链跨行业应用的开源项目,由Linux基金会在2015年12月主导发起该项目,成员包括金融、银行、物联网、供应链、制造和科技等多个行业的领头羊,托管了众多面向企业的区块链开源框架和工具。 5 | 6 | ![](http://blog.hubwiz.com/2019/03/23/fabric-blockchain/hyperledger-2.png) 7 | 8 | ### Hyperledger及Fabric项目概述 9 | 10 | Hyperledger Fabric(后文简称Fabric)是其中发展最好的一个企业级区块链平台,最初由Digital Asset和IBM贡献,目前已经应用于沃尔玛的食物溯源链(Foodtrust)和马士基的物流跟踪链(TradeLens)中,代表了当下企业级区块链应用的最高水平。可以认为Fabric是一种联盟链(Consortium Blockchain)平台,它适合构建跨越多个企业边界的去中心化应用。 11 | 12 | 由于Fabric项目的目标是应用于相对可信的企业联盟环境,因此其设计思路与比特币、以太坊等公链平台有明显的差异。Fabric借鉴了区块链的数据结构,但引入了相当多的身份验证与权限控制机制,以及数据隐私保护机制,以适应企业级应用的要求。同时由于企业联盟环境要比完全开放的公链环境可控,因此Fabric没有强调其共识体系对拜占庭容错的实现,允许使用 非拜占庭容错算法建立共识,从而可以达到相当实用的交易吞吐量。 13 | 14 | ### Fabric的定位与特点 15 | 16 | 毫无疑问,Fabric是受到比特币的启发而诞生的,因此它借鉴了比特币、以太坊这些公链中的一些核心特性,例如采用不可篡改的区块链结构来保存数据、采用非对称加密技术来进行身份识别 与认证、支持智能合约等等。 17 | 18 | 但是Fabric定位于企业级的分布式账本技术(DLT - Distributed Ledger Technology)平台,它的主要目的是为跨越多个企业边界的活动提供不可篡改的分布式记账平台。例如在食物溯源应用中,为了让消费者可以了解到所购买食物是否安全,就必须将从农场到加工商、分销商、 零售商乃至监管机构等各个环节的检验与放行信息记录到区块链上,以保证溯源信息的透明与可信。 19 | 20 | ![](http://blog.hubwiz.com/2019/03/23/fabric-blockchain/foodtrack-2.png) 21 | 22 | 因此Fabric是一种联盟链(Consortium Blockchain),它适合在多个企业间实现分布式记账,这一定位使Fabric的实现与以太坊这样的公链有了明显的差异: 23 | 24 | #### 分布式账本 vs. 区块链 25 | 26 | 分布式账本是比区块链更加宽泛的概念,可以认为区块链只是分布式账本的一种实现技术,其他的分布式账本实现还包括哈希图等。 27 | 28 | #### 去中心化 vs. 分布式 29 | 30 | Fabric淡化了去中心化(Decentralized),而以分布式(Distributed)代替,这一思路带来了系统设计与实现上的巨大影响。例如,在Fabric中,采用中心化的CA机制来发放证书,只有持有有效证书的节点和用户才可以访问区块链上的账本数据。因此Fabric是许可制/Permissioned的区块链,这与不需要许可/Permissionless的以太坊这样的公链形成了鲜明的对比。 31 | 32 | #### 拜占庭容错 vs. 崩溃容错 33 | 34 | 由于采用许可机制,Fabric也淡化了对不可信(Trustless)环境下共识达成的依赖性,而假设联盟链中的企业有可能是值得信赖的,因此并不依赖于工作量证明这样的拜占庭容错算法,虽然Fabric模块化的设计可以支持引入不同的共识算法实现,但目前的产品化方案是Kafka共识,它显然是不能对抗拜占庭错误的,不过对不可信环境支持的淡化处理有利于提高交易的吞吐量,这对于企 业级应用也是有益的。 35 | 36 | #### 数据隐私保护 37 | 38 | 在另一方面,Fabric强化了隐私保护能力。例如,Fabric支持在同一套企业网络上建立多个不同的通道/Channel,每一个通道都有自己的区块链和访问控制,彼此互不影响,这有利于复用基础设施,例如不同企业间的销售部门可以建立一个通道来分享市场数据,而这些企业间的 研发部门可以建立另一个通道来分享技术数据。 39 | 40 | Fabric并不是唯一的联盟链解决方案,但目前可以说是最复杂的企业联盟链实现,这种复杂性源于设计者对应用场景的假设和推演,以及对Fabric广泛适用性的考量,这是我们在学习过程中需要换位思考的一点。 41 | 42 | ### 课程内容概述 43 | 44 | 本课程适合nodejs开发人员快速掌握超级账本Fabric区块链的设计思路、 核心概念、网络搭建、链码及应用开发等知识点,课程主要内容简述如下: 45 | 46 | #### 第一章、课程概述 47 | 48 | 简介Fabric项目来源、定位特点、适用场景以及其与公链平台的重要区别。 49 | 50 | #### 第二章、初识Fabric 51 | 52 | 创建一个最小CA,搭建一个最小Farbic网络,开发一个最小Fabric链码,实现一个最小Fabric应用,从零开始学习并掌握Farbic中的核心概念、设计思路、实用工具与开发模型。 53 | 54 | #### 第三章、身份与权限管理机制 55 | 56 | 深入学习Fabric中的身份验证机制与权限管理机制,理解证书、成员服务提供器、 策略、访问控制清单等核心概念并掌握其创建、部署和使用方法。 57 | 58 | #### 第四章、通道配置与更新 59 | 60 | 深入学习Fabric的通道配置初始化与更新流程、相关数据结构以及配置工具的操作方法。 61 | 62 | #### 第五章、链码应用开发进阶 63 | 64 | 学习理解链码运行机制、掌握状态历史跟踪、富查询、通道事件监听等链码与应用 开发进阶知识。 65 | 66 | 67 | ### 课程详细目录: 68 | 69 | #### 1.课程概述 70 | - 1.1 Hyperledger及Fabric项目概述 71 | - 1.2 Fabric的定位与特点 72 | - 1.3 课程内容概述 73 | #### 2.初识Fabric 74 | - 2.1 Fabric架构概述 75 | - 2.2 身份标识与验证机制 76 | - 2.3 使用OpenSSL构建小型CA 77 | - 2.4 MSP:成员服务提供器 78 | - 2.5 启动最小Fabric网络 79 | - 2.6 通道初始化与节点加入 80 | - 2.7 开发计数器链码 81 | - 2.8 链码方法的路由 82 | - 2.9 链码的安装与激活 83 | - 2.10 在应用中访问链码 84 | - 2.11 User接口实现类 85 | - 2.12 通道访问参数设置 86 | - 2.13 链码查询 87 | - 2.14 链码交易 88 | - 2.15 使用WIZ开发工具箱 89 | #### 3.身份与权限管理机制 90 | - 3.1 非对称密码学 91 | - 3.2 PKI体系与MSP机制 92 | - 3.3 使用cryptogen配置本地MSP 93 | - 3.4 从个体身份到安全主体 94 | - 3.5 通道MSP配置 95 | - 3.6 通道资源访问策略 96 | - 3.7 策略的DSL描述语言 97 | - 3.8 通道访问控制清单 98 | - 3.9 通道链码背书策略 99 | #### 4.通道配置与更新 100 | - 4.1 系统通道的启动与配置块获取 101 | - 4.2 标准通道的启动与配置块获取 102 | - 4.3 深入通道配置区块 103 | - 4.4 通道配置更新交易 104 | - 4.5 通道配置更新流水线 105 | #### 5.链码与应用开发进阶 106 | - 5.1 链码运行机制概述 107 | - 5.2 跟踪状态变迁历史 108 | - 5.3 使用复合键 109 | - 5.4 使用CouchDB状态库 110 | - 5.5 监听通道事件 111 | - 5.6 使用连接配置文件 112 | 113 | 课程地址:[http://xc.hubwiz.com/course/5c9b89f54898e59b7b63430a](http://xc.hubwiz.com/course/5c9b89f54898e59b7b63430a?affid=0328github) 114 | -------------------------------------------------------------------------------- /app.java: -------------------------------------------------------------------------------- 1 | package com.hubwiz.demo; 2 | 3 | import org.hyperledger.fabric.sdk.User; 4 | import org.hyperledger.fabric.sdk.HFClient; 5 | import org.hyperledger.fabric.sdk.Channel; 6 | import org.hyperledger.fabric.sdk.Peer; 7 | import org.hyperledger.fabric.sdk.Orderer; 8 | import org.hyperledger.fabric.sdk.security.CryptoSuite; 9 | import org.hyperledger.fabric.sdk.ChaincodeID; 10 | import org.hyperledger.fabric.sdk.QueryByChaincodeRequest; 11 | import org.hyperledger.fabric.sdk.ProposalResponse; 12 | import org.hyperledger.fabric.sdk.TransactionProposalRequest; 13 | import org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent; 14 | 15 | import java.util.Collection; 16 | import java.util.concurrent.CompletableFuture; 17 | import java.io.File; 18 | import java.lang.System; 19 | 20 | public class App{ 21 | private User user; 22 | private HFClient client; 23 | private Channel channel; 24 | 25 | public User loadUser(String name,String mspId) throws Exception{ 26 | String mspDir = "../network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/"; 27 | 28 | File keystore = new File(mspDir + "keystore"); 29 | File[] keyFiles = keystore.listFiles(); 30 | if(keyFiles.length == 0 ) throw new Exception("no key found"); 31 | String keyFileName = mspDir + "keystore/" + keyFiles[0].getName(); 32 | 33 | File certstore = new File(mspDir + "signcerts"); 34 | File[] certFiles = certstore.listFiles(); 35 | if(certFiles.length == 0 ) throw new Exception("no cert found"); 36 | String certFileName = mspDir + "signcerts/" + certFiles[0].getName(); 37 | 38 | this.user = new LocalUser(name,mspId,keyFileName,certFileName); 39 | return this.user; 40 | } 41 | 42 | public void initChannel() throws Exception{ 43 | if(this.user == null) throw new Exception("user not loaded"); 44 | 45 | HFClient client = HFClient.createNewInstance(); 46 | client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite()); 47 | client.setUserContext(this.user); 48 | 49 | Channel channel = client.newChannel("ch1"); 50 | Peer peer = client.newPeer("peer1`","grpc://127.0.0.1:7051"); 51 | channel.addPeer(peer); 52 | Orderer orderer = client.newOrderer("orderer1","grpc://127.0.0.1:7050"); 53 | channel.addOrderer(orderer); 54 | channel.initialize(); 55 | 56 | this.channel = channel; 57 | this.client = client; 58 | } 59 | 60 | public void query(String ccname,String fcn,String...args) throws Exception{ 61 | System.out.format("query %s %s...\n",ccname,fcn); 62 | 63 | QueryByChaincodeRequest req = this.client.newQueryProposalRequest(); 64 | ChaincodeID cid = ChaincodeID.newBuilder().setName(ccname).build(); 65 | req.setChaincodeID(cid); 66 | req.setFcn(fcn); 67 | req.setArgs(args); 68 | 69 | Collection rspc = channel.queryByChaincode(req); 70 | 71 | for(ProposalResponse rsp: rspc){ 72 | System.out.format("status: %d \n",rsp.getStatus().getStatus()); 73 | System.out.format("message: %s\n",rsp.getMessage()); 74 | System.out.format("payload: %s\n",rsp.getProposalResponse().getResponse().getPayload().toStringUtf8()); 75 | } 76 | } 77 | 78 | public void invoke(String ccname,String fcn,String... args) throws Exception{ 79 | System.out.format("invoke %s %s...\n",ccname,fcn); 80 | 81 | TransactionProposalRequest req = this.client.newTransactionProposalRequest(); 82 | ChaincodeID cid = ChaincodeID.newBuilder().setName(ccname).build(); 83 | req.setChaincodeID(cid); 84 | req.setFcn(fcn); 85 | req.setArgs(args); 86 | 87 | Collection rspc = channel.sendTransactionProposal(req); 88 | TransactionEvent event = channel.sendTransaction(rspc).get(); 89 | 90 | System.out.format("txid: %s\n", event.getTransactionID()); 91 | System.out.format("valid: %b\n", event.isValid()); 92 | } 93 | 94 | public void start() throws Exception{ 95 | loadUser("admin","Org1MSP"); 96 | initChannel(); 97 | 98 | query("wizcc","test"); 99 | invoke("wizcc","test"); 100 | } 101 | 102 | public static void main(String[] args) throws Exception{ 103 | System.out.println("wiz dapp"); 104 | new App().start(); 105 | } 106 | } 107 | --------------------------------------------------------------------------------