怎么搭建hyperledgerr fabric 币怎么来

Hyperledger详解
这篇文章介绍了Hyperledger技术的原理、构架和协议。1.1 Fabric介绍Fabric是数字事件(交易)的账簿,这个账簿由多个参与者共享,每个参与者都在系统中拥有权益。账簿只有在所有参与者达成共识的情况下才能够更新,并且信息一旦记录就永远不能修改。每个记录的事件都可以基于参与者的共识证明使用密码学进行验证。交易是安全、私有和保密的。每个参与者使用身份证明向网络成员服务(membership service)注册以获取系统的访问权限。参与者使用不可追踪的导出证书生成交易,可以在网络中完全匿名。交易的内容使用由密钥导出的复杂函数进行加密,确保只有指定的参与者才能够看到内容,以保护商业交易的机密性。账簿的全部或者部分可以审计以满足监管要求。在参与者合作的情况下,审计人员可以获取有限时间的证书来查看账簿和交易详情,从而对运营情况进行准确的评估。Fabric是的实现,比特币可以作为一种简单的应用在Fabric基础上构建。Fabric采用了模块化的构架,允许不同的组件在实现协议的基础上即插即用。可以使用强大的容器技术来运行主流编程语言以进行智能合约的开发。使用熟悉的和已验证的技术是fabric构架的宗旨。1.2 使用Fabic的原因早期的区块链技术能够实现一些功能,但是缺乏对特定行业需求的完整支持。为了满足现代市场的要求,fabric面向行业需求进行设计以适应多种行业特定的应用场景,并且在诸如伸缩性设计等方面比这个领域的先驱更进一步。Fabric使用了新的方法实现了授权网络、在多个区块链网络上的私有性和保密性。2.1 Fabric构架Fabric的构架由成员服务(Membership)、区块链服务(Blockchain)和链码服务(Chaincode)三个主要类别构成。这些类别仅仅是Fabric的逻辑结构,并不是在物理上将组件划分成不同的进程、地址空间或者虚拟机。&2.1.1 成员服务成员服务负责管理用户标识、隐私、以及网络的保密性和可审计性。在无权限的区块链中,参与者不需要授权,并且所有节点可以平等地提交交易或者将交易累积成区块,也就是说没有角色的区别。成员服务将公钥基础设施(PKI)和去中心化共识机制的基本元素进行整合,从而将无权限区块链转化为有权限区块链。在有权限区块链中,参与者需要注册以获取长期身份凭据(登记证书),并且可以根据身份类型进行区分。在用户的情况下,交易证书管理者(TCA)可以发行假名凭据。这种凭据(即交易证书)被用来进行授权提交的交易。交易证书在区块链上保存,并且允许授权的审计者对交易进行归类,否则这些交易将无法关联。2.1.2 区块链服务区块链服务通过使用基于HTTP2的P2P协议管理分布式账簿。区块链上的数据结构经过了高度优化以提供最有效的Hash算法来保存世界状态(world state)的副本。在部署中可以使用和配置不同的共识算法,包括PBFT, Raft, PoW, PoS等。2.1.3 链码服务链码服务为链码(chaincode)在验证节点上执行提供了一个安全和轻量级的沙盒。沙盒环境是一个锁定和安全容器,带有一组经过签名的基础磁盘映像,包含了安全操作系统和支持Go、Java和Node.js的链码语言、运行时和SDK,其他语言可以根据需要被启用。2.1.4 事件验证节点和链码可以在区块链网络上发送事件,应用程序可以监听这些事件并作出响应。已经存在一组预先定义好的事件,并且链码也可以生成自定义的事件。事件可以被一个或者多个事件适配器处理,适配器可以使用Web Hook或者Kafka进一步将事件进行传递。2.1.5 应用程序接口(API)Fabric的主要编程接口是REST API,以及基于Swagger2.0的变体。这些API可以让应用程序注册用户、查询区块链、以及发送交易。有一组API专门设计给链码用来与底层平台交互以执行交易和查询交易结果。2.1.6 命令行接口(CLI)CLI包括REST API的一组子集来帮助开发者快速测试链码和查询交易状态。CLI由Go语言实现,并且支持多种操作系统。2.2 拓扑结构Fabric的部署可以包括成员服务、多个验证节点(peer)和非验证节点、以及一个或者多个应用。所有这些组件构成了一个区块链。可以存在多个区块链,每个区块链都可以有自己的运行参数和安全需求。2.2.1 单个验证节点从功能上将,非验证节点是验证节点的子集,也就是说每个非验证节点上的功能也可以在验证节点上实现,因此最简单的区块链网络可以仅有一个验证节点构成。这种配置最适合作为开发环境,单个验证节点可以在“编辑-编译-调试”周期中快速启动。单个验证节点不需要共识机制,因此默认的共识机制插件为noops,在这种情况下交易是立即执行的,这样开发者可以在开发过程中的到立即反馈。2.2.2 多个验证节点用于生产环境或者测试环境的区块链网络一般由多个验证节点和非验证节点构成。非验证节点可以承担一部分从验证节点剥离的工作量,比如处理API请求和处理事件。&所有验证节点构成了一个全连接的网络,即每个验证节点都与其他的验证节点连接。非验证节点连接到邻近的允许连接的验证节点。非验证节点是可选的,因为应用程序可以直接与验证节点进行通讯。2.2.3 多链每个由验证节点和非验证节点组成的网络构成了一个区块链。多个区块链可以被创建用来满足不同的需求,好比多个Web网站可以满足不同的目的。Fabric的点对点通讯是基于gRPC构建的,实现了基于流的双向消息通讯。gRPC使用了谷歌公司的Protocol Buffers对数据结构进行串行化来实现节点之间的数据传输。Protocol buffers是一种语言中立、平台中立、并且可扩展的数据结构串行化技术。数据结构、消息和服务都是用proto3语言描述。3.1 消息节点之间传输的消息是由Message这个proto结构封装的,有四种不同的类型:发现(Discovery)、交易(Transaction)、同步(Synchronization)和共识(Consensus)。每种类型都可以在其内嵌的payload字段中定义更多的子类型。message Message {& & enum Type {& & & & UNDEFINED = 0;& & & & DISC_HELLO = 1;& & & & DISC_DISCONNECT = 2;& & & & DISC_GET_PEERS = 3;& & & & DISC_PEERS = 4;& & & & DISC_NEWMSG = 5;& & & & CHAIN_STATUS = 6;& & & & CHAIN_TRANSACTION = 7;& & & & CHAIN_GET_TRANSACTIONS = 8;& & & & CHAIN_QUERY = 9;& & & & SYNC_GET_BLOCKS = 11;& & & & SYNC_BLOCKS = 12;& & & & SYNC_BLOCK_ADDED = 13;& & & & SYNC_STATE_GET_SNAPSHOT = 14;& & & & SYNC_STATE_SNAPSHOT = 15;& & & & SYNC_STATE_GET_DELTAS = 16;& & & & SYNC_STATE_DELTAS = 17;& & & & RESPONSE = 20;& & & & CONSENSUS = 21;& & }& & Type type = 1;& & bytes payload = 2;& & google.protobuf.Timestamp timestamp = 3;}payload字段是一个包含其他对象(Transaction或者Response)的不透明字节数组,例如,当type是CHAIN_TRANSACTION时,payload是Transaction对象。3.1.1 发现消息在节点启动之后,如果CORE_PEER_DISCOVERY_ROOTNODE字段存在则运行发现协议。CORE_PEER_DISCOVERY_ROOTNODE是另外一个网路上节点(任意节点)的IP地址,这个节点可以作为发现网络上其他所有节点的起点。协议序列从DISC_HELLO开始,其payload为HelloMessage对象:message HelloMessage {& & PeerEndpoint peerEndpoint = 1;& & uint64 blockNumber = 2;}message PeerEndpoint {& & PeerID ID = 1;& & string address = 2;& & enum Type {& & & & UNDEFINED = 0;& & & & VALIDATOR = 1;& & & & NON_VALIDATOR = 2;& & }& & Type type = 3;& & bytes pkiID = 4;}message PeerID {& & string name = 1;}PeerId是节点启动的时候被赋予的名字,也可以在配置文件中定义。PeerEndpoint用来描述验证节点或者非验证节点pkiID是节点的密码学IDaddress是节点的IP地址和端口(ip:port)blockNumber是节点上区块链的当前高度如果通过DISC_HELLO获取的区块高度超过了当前节点的区块链高度,则节点立即启动同步协议将节点状态更新到网络当前最新状态。DISC_HELLO之后,节点周期性地发送DISC_GET_PEERS以发现新加入到网络的其他节点。作为对DISC_GET_PEERS消息的响应,收到消息的节点发送'DISC_PEERS'消息,该消息中的payload字段包含了一组PeerEndpoint。其他发现消息目前未使用。3.1.2 交易消息存在3种交易类型:部署(Deploy)、调用(Invoke)和查询(Query)。部署交易将指定的链码安装到区块链网络,而调用和查询交易则是调用已经部署到区块链上的链码函数。还有一种创建型(Create)交易用于将已经部署到区块链上的链码实例化并载入内存,但目前该交易类型未实现。3.1.2.1 交易数据结构message Transaction {& & enum Type {& & & & UNDEFINED = 0;& & & & CHAINCODE_DEPLOY = 1;& & & & CHAINCODE_INVOKE = 2;& & & & CHAINCODE_QUERY = 3;& & & & CHAINCODE_TERMINATE = 4;& & }& & Type type = 1;& & string uuid = 5;& & bytes chaincodeID = 2;& & bytes payloadHash = 3;& & ConfidentialityLevel confidentialityLevel = 7;& & bytes nonce = 8;& & bytes cert = 9;& & bytes signature = 10;& & bytes metadata = 4;& & google.protobuf.Timestamp timestamp = 6;}message TransactionPayload {& & bytes payload = 1;}enum ConfidentialityLevel {& & PUBLIC = 0;& & CONFIDENTIAL = 1;}3.1.3 同步消息当节点通过发现协议发现自己比区块链网络落后或者不一致,则马上开启同步协议。节点广播SYNC_GET_BLOCKS、SYNC_STATE_GET_SNAPSHOT或者SYNC_STATE_GET_DELTAS,相应地接收SYNC_BLOCKS、SYNC_STATE_SNAPSHOT或者SYNC_STATE_DELTAS。已安装的共识机制插件决定同步协议如何执行,每种消息针对不同的情况:SYNC_GET_BLOCKS在消息的payload字段中请求一组连续范围的区块,这种范围使用SyncBlockRange表示:message SyncBlockRange {& & uint64 start = 1;& & uint64 end = 2;}接收到SYNC_GET_BLOCKS的节点响应SYNC_BLOCKS消息,在其payload字段中包含了SyncBlocks:message SyncBlocks {& & SyncBlockRange range = 1;& & repeated Block blocks = 2;}3.1.4 共识消息共识机制用于处理交易,因此CONSENSUS消息由内部的共识框架在接收到CHAIN_TRANSACTION消息后发送。共识框架将CHAIN_TRANSACTION转化为CONSENSUS,然后向所有验证节点进行广播。共识插件接收到消息后,根据自身算法对消息进行处理。3.2 账簿账簿(ledger)由区块链(blockchain)和世界状态(world state)这两个部分组成。区块链是一组链接起来的区块,用来在账簿中记录交易。世界状态是键值数据库,在链码执行过程中用来存储状态。3.2.1 区块链3.2.1.1 区块区块链被定义为一组连接在一起的区块,因为每个区块都包含链中前一个区块的Hash。区块中另外2个重要信息是交易列表,以及区块中所有交易执行完成后的世界状态的Hash值。message Block {& version = 1;& google.protobuf.Timestamp timestamp = 2;& bytes transactionsHash = 3;& bytes stateHash = 4;& bytes previousBlockHash = 5;& bytes consensusMetadata = 6;& NonHashData nonHashData = 7;}message BlockTransactions {& repeated Transaction transactions = 1;}transactionsHash是区块内交易列表merkle根的hash值stateHash是世界状态merkle根的hash值previousBlockHash是前一个区块的hash值BlockTransactions.transactions是交易消息的数组,交易列表由于大小的关系并不直接包含在区块内部。3.2.2 世界状态节点中的世界状态是所有已部署的链码的状态集合,实际上是键值对{chaincodeID, ckey}的集合。
上一篇:下一篇:
已有0人参与讨论
你可能喜欢搭建Hyperledger fabric的开发环境
概述目前Hyperledge fabric的开发环境是使用一个运行在Vagrant里的Ubuntu映像,并在里边依次运行若干Docker容器。 从概念上说,就是在一个主机上启动了一个虚拟机,然后在其上依次启动Docker容器。Host -& VM -& Docker这个模型允许开发者利用他们自己喜欢的操作系统和编辑器来开发,与此同时呢,又可以让系统运行在一个与开发团队一致的受控环境中。注:你的主机不能运行在虚拟机中。如果你尝试运行在虚拟机中,会得到一个条启动错误信息(VT-x不可用)。准备项Git clientGo - 1.6 or laterVagrant - 1.7.4 or laterVirtualBox - 5.0 or later在BIOS中打开虚拟化(Virtualization)选项注:Note: 虚拟化(Virtualization)选项一般在BIOS的CPU或安全设置中。步骤设置GOPATH环境变量请确保你正确设置了你主机上的GOPATH环境变量. 正确设置了之后,你就能够在主机和虚拟机上构建代码了。Windows用户请注意如果你是Windows用户,在运行任何 git clone 命令之前,先运行下面的命令:git config --get core.autocrlf如果 core.autocrlf 为 true, 你必须把它设为 false 来运行下面的命令:git config --global core.autocrlf false如果你把 core.autocrlf 设为 true 的话,命令 vagrant up 就会失败并提示 ./setup.sh: /bin/bash^M: bad interpreter: No such file or directory克隆Peer工程在Github的Web界面中创建一个fabric的副本。 接下来,在适当的目录中克隆你的fabric副本。cd $GOPATH/srcmkdir -/hyperledger/hyperledgergit clone //fabric.git使用Vagrant引导并配置虚拟机cd $GOPATH//hyperledger/fabric/devenvvagrant up注意 #1: 如果你需要通过HTTP代理服务器上网,你需要更多的配置才能确保虚拟机完成构建。你可以使用 vagrant-proxyconf 插件。 用命令vagrant plugin install vagrant-proxyconf 完成安装,然后在你执行 vagrant up 之前设置VAGRANT_HTTP_PROXY和VAGRANT_HTTPS_PROXY这两个系统环境变量。详见: /tmatilai/vagrant-proxyconf/注意 #2: 第一次执行 vagrant up 这个命令时会需要相当长的时间(可能30分钟以上),可能在过程中它可能像是死掉了,但是在你没有得到错误提示之前别管它。完成后,你就能在同一个目录执行下边的命令SSH到你的新虚拟机上了。vagrant ssh当你登录进去之后,你可以发现peer工程就在 $GOPATH//hyperledger/fabric 下(/hyperledger).注意: 任何时间在你主机上的fabric目录($GOPATH//hyperledger/fabric)中执行 git clone 命令来更新任何工程,与此同时虚拟机的fabric目录也会被同步更新。
上一篇:下一篇:
最新的fabric代码:
bccsp/pkcs11/pkcs11.go
vendor//miekg/pkcs11.go
文件名相同,包名也相同,不会有问题?
我make peer的时候报错:
bccsp/pkcs11/pkcs11.go:92: undefined: pkcs11.SessionHandle
bccsp/pkcs11/pkcs11.go:118: undefined: pkcs11.SessionHandle
有人遇到过么?
rangeroversport
请问这里在vagrant-proxyconf部分有什么合适的代理么,Github上的代理似乎并不可用,尝试了很多次了还是失败,非常感谢
#区块链##学院# 【搭建Hyperledger fabric的开发环境】(文/质本网络)目前Hyperledge fabric的开发环境是使用一个运行在Vagrant里的Ubuntu映像,并在里边依次运行若干Docker容器。 从概念上说,就是在一个主机上启动了一个虚拟机,然后在其上依次启动Docker容器……http://t.cn/RqWmWU1
rangeroversport
最新的fabric代码:
bccsp/pkcs11/pkcs11.go
vendor//miekg/pkcs11.go
文件名相同,包名也相同,不会有问题?
我make peer的时候报错:
bccsp/pkcs11/pkcs11.go:92: undefined: pkcs11.SessionHandle
bccsp/pkcs11/pkcs11.go:118: undefined: pkcs11.SessionHandle
有人遇到过么?
#区块链##学院# 【搭建Hyperledger fabric的开发环境】(文/质本网络)目前Hyperledge fabric的开发环境是使用一个运行在Vagrant里的Ubuntu映像,并在里边依次运行若干Docker容器。 从概念上说,就是在一个主机上启动了一个虚拟机,然后在其上依次启动Docker容器……http://t.cn/RqWmWU1
请问这里在vagrant-proxyconf部分有什么合适的代理么,Github上的代理似乎并不可用,尝试了很多次了还是失败,非常感谢
已有4人参与讨论
你可能喜欢
你可能喜欢Hyperledger架构解读:Hyperledger Fabric1.0架构概览 - 山寨币开发
&&&&&&&&&&Hyperledger架构解读:Hyperledger Fabric1.0架构概览
我们的服务/Brand
+我们的服务理念设计
钱包开发,win和linux,手机钱包,矿池,区块浏览器,官网,标识为新生电子货币打造强势品牌!
+助力发展互联网金融快捷支付
助力中小企业的发展,实现免支付政税、增值税、企业所得税,为企业形象及品牌建立一个新的发展路径!
+山寨币维护与区块更新
开发新币的细分区块,数据链的分叉问题,我们每周为用户做好更新源数据支持,保证钱包的完整性!
+做币包装品牌规划设计
精准的推广目光,定位于币核心用途、符合企业线上 线下合作,帮助用户在互联网金融中脱颖而出!
/Logo Design
做币开发联系我们/catanct
邮编:511083
网站:www.qqya.cc
博客:.cn/u/
公司:惠州优尼网络(Uuin)比特币开发公司IBM HyperLedger fabric 详解
在我看来,比特币就是现实中的V字仇杀队,当然现实是更残酷的世界政府,这场博弈关乎着人类文明、政治、社会属性、经济和人权。&IBM HyperLeger 又叫 fabric,你可以把它想象成一个由全社会来共同维护的一个超级账本,没有中心机构拥揽权力,你的每一笔交易都是全网公开且安全的,信用由全社会共同见证。它与Bitcoin的关系就是,你可以利用fabric构建出一个叫Bitcoin的应用来帮助你change the world。&愿景是那么的牛X,貌似正合我们想改变世界的胃口,但是在残酷的现实和世界面前我们永远是天真幼稚的,blockchain需要一步一步脚印来构建它的宏伟蓝图,起码目前是没有将它用于工业生产和国家经济的案例的。&fabric源于IBM,初衷为了服务于工业生产,IBM将44,000行代码开源,是了不起的贡献,让我们可以有机会如此近的去探究的原理,但毕竟IBM是从自身利益和客户利益出发的,并不是毫无目的的去做这项公益事业,我们在看fabric的同时要有一种审慎的思维:区块链不一定非得这样,它跟比特币最本质的非技术区别在哪里。我们先来大致了解一下fabric的关键术语(因为一些词汇用英文更准确,我就不硬翻译了)。1. TerminologyTransaction& 它一条request,用来在ledger上执行一个function,这个function是用chaincode来实现的Transactor& 发出transaction的实体,比如它可能是一个客户端应用Ledger &Legder可以理解为一串经过加密的block链条,每一个block包含着transactions和当前world state等信息World State& world state是一组变量的集合,包含着transactions的执行结果Chaincode& 这是一段应用层面的代码(又叫smart contract,智能合约),它存储在ledger上,作为transaction的一部分。也就是说chaincode来运行transaction,然后运行结果可能会修改world stateValidating Peer& 参与者之一,它是一种在网络里负责执行一致性协议、确认交易和维护账本的计算机节点Nonvalidating Peer &它相当于一个代理节点,用来连接transactor和邻近的VP(Validating Peer)节点。一个NVP节点不会去执行transactions但是回去验证它们。同时它也会承担起事件流server和提供REST services的角色Permissioned Ledger &这是一个要求每一个实体和节点都要成为网络成员的blockchain网络,所有匿名节点都不被允许连接Privacy &用来保护和隐蔽chain transactors的身份,当网络成员要检查交易时,如果没有特权的话,是无法追踪到交易的transactorConfidentiality &这个特性使得交易内容不是对所有人可见,只开放给利益相关者Auditability &将blockchain用于商业用途需要遵守规则,方便监管者调查交易记录2. Architecture架构核心逻辑有三条:Membership、Blockchain和Chaincode。2.1 Membership Services这项服务用来管理节点身份、隐私、confidentiality 和 auditability。在一个 non-permissioned的区块链网络里,参与者不要求授权,所有的节点被视作一样,都可以去submit一个transaction,去把这些交易存到区块(blocks)中。那Membership Service是要将一个 non-permissioned的区块链网络变成一个permissioned的区块链网络,凭借着Public Key Infrastructure (PKI)、去中心和一致性。2.2 Blockchain ServicesBlockchain services使用建立在HTTP/2上的P2P协议来管理分布式账本。提供最有效的哈希算法来维护world state的副本。采取可插拔的方式来根据具体需求来设置共识协议,比如PBFT,Raft,PoW和PoS等等。2.3 Chaincode ServicesChaincode services 会提供一种安全且轻量级的沙盒运行模式,来在VP节点上执行chaincode逻辑。这里使用Container环境,里面的base镜像都是经过签名验证的安全镜像,包括OS层和开发chaincode的语言、runtime和SDK层,目前支持Go、Jave和Nodejs开发语言。2.4 Events在blockchain网络里,VP节点和chaincode会发送events来触发一些监听动作。比如chaincode是用户代码,它可以产生用户事件。2.5 API 和 CLI提供REST API,允许注册用户、查询blockchain和发送transactions。一些针对chaincode的API,可以用来执行transactions和查询交易结果。对于开发者,可以通过CLI快速去测试chaincode,或者去查询交易状态。3. Topology分布式网络的拓扑结构是非常值得研究的。在这个世界里散布着众多参与者,不同角色,不同利益体,各种各样的情况处理象征着分布式网络里的规则和法律,无规则不成方圆。在区块链网络里,有Membership service,有VP节点,NVP节点,一个或多个应用,它们形成一个chain,然后会有多个chain,每一个chain都有各自的安全要求和操作需求。3.1 单个VP节点网络最简单的网络就是只包含一个VP节点,因此就省去了共识部分。3.2 多个VP节点网络多个VP和NVP参与的网络才是有价值和实际意义的。NVP节点分担VP节点的工作压力,承担处理API请求和events的工作。而对于VP节点,VP节点间会组成一个网状网络来传播信息。一个NVP节点如果被允许的话可以与邻近的一个VP节点相连。NVP节点是可以省略的,如果Application可以直接和VP节点通讯。3.3 Multichain还会存在一个网络里多条chain的情况,各个chain的意图不一样。4. Protocolfabric是用gRPC来做P2P通讯的,是一个双向流消息传递。使用 Protocol Buffer来序列化要传递的数据结构。4.1 Messagemessage分四种:Discovery,Transaction,Synchronization 和 Consensus。每一种信息下还会包含更多的子信息,由payload指出。payload是一个不透明的字节数组,它包含着一些对象,比如 Transaction 或者 Response。例如,如果 type 是 CHAIN_TRANSACTION,那么 payload 就是一个 Transaction的对象。message Message {& &enum Type {& & & & UNDEFINED = 0;& & & & DISC_HELLO = 1;& & & & DISC_DISCONNECT = 2;& & & & DISC_GET_PEERS = 3;& & & & DISC_PEERS = 4;& & & & DISC_NEWMSG = 5;& & & & CHAIN_STATUS = 6;& & & & CHAIN_TRANSACTION = 7;& & & & CHAIN_GET_TRANSACTIONS = 8;& & & & CHAIN_QUERY = 9;& & & & SYNC_GET_BLOCKS = 11;& & & & SYNC_BLOCKS = 12;& & & & SYNC_BLOCK_ADDED = 13;& & & & SYNC_STATE_GET_SNAPSHOT = 14;& & & & SYNC_STATE_SNAPSHOT = 15;& & & & SYNC_STATE_GET_DELTAS = 16;& & & & SYNC_STATE_DELTAS = 17;& & & & RESPONSE = 20;& & & & CONSENSUS = 21;& & }& & Type type = 1;& & bytes payload = 2;& & google.protobuf.Timestamp timestamp = 3;}4.1.1 Discovery Messages一个新启动的节点,如果CORE_PEER_DISCOVERY_ROOTNODE(ROOTNODE是指网络中其它任意一个节点的IP)被指定了,它就会开始运行discovery协议。而ROOTNODE就作为最一开始的发现节点,然后通过ROOTNODE节点进而发现全网中所有的节点。discovery协议信息是DISC_HELLO,它的payload是一个HelloMessage对象,同时包含信息发送节点的信息:message HelloMessage {& PeerEndpoint peerEndpoint = 1;& uint64 blockNumber = 2;}message PeerEndpoint {& & PeerID ID = 1;& & string address = 2;& & enum Type {& & & UNDEFINED = 0;& & & VALIDATOR = 1;& & & NON_VALIDATOR = 2;& & }& & Type type = 3;& & bytes pkiID = 4;}message PeerID {& & string name = 1;}如果一个节点接收到DISC_HELLO信息,发现里面的block height高于自己目前的block height,它会立即发送一个同步协议来与全网同步自己的状态(mark:但是在源码层面似乎并没有实现同步这个逻辑)。在这个刚加入节点完成DISC_HELLO这轮消息传递后,接下来回周期性的发送DISC_GET_PEERS来发现其它加入网络中的节点。为了回复DISC_GET_PEERS,一个节点会发送DISC_PEERS。4.1.2 Synchronization MessagesSynchronization 协议是接着上面所说的discovery协议开始的,当一个节点发现它的block的状态跟其它节点不一致时,就会触发同步。该节点会广播(broadcast)三种信息:SYNC_GET_BLOCKS , SYNC_STATE_GET_SNAPSHOT 或者&SYNC_STATE_GET_DELTAS,同时对应接收到三种信息:SYNC_BLOCKS , SYNC_STATE_SNAPSHOT 或者 SYNC_STATE_DELTAS。目前fabric嵌入的共识算法是pbft。SYNC_GET_BLOCKS 会请求一系列连续的block,发送的数据结构中payload将是一个SyncBlockRange对象。message SyncBlockRange {& & uint64 correlationId = 1;& & uint64 start = 2;& & uint64 end = 3;}接收的节点会回复SYNC_BLOCKS,它的payload是一个SyncBlocks对象:message SyncBlocks {& & SyncBlockRange range = 1;& & repeated Block blocks = 2;}start和end表示起始和结束的block。例如start=3, end=5,代表了block 3,4,5;start=5, end=3,代表了block 5,4,3。SYNC_STATE_GET_SNAPSHOT 会请求当前world state的一个snapshot,该信息的payload是一个SyncStateSnapshotRequest对象:message SyncStateSnapshotRequest {& & uint64 correlationId = 1;}correlationId是发出请求的peer用来追踪对应的该信息的回复。收到该消息的peer会回复SYNC_STATE_SNAPSHOT,它的payload是一个SyncStateSnapshot对象:message SyncStateSnapshot {& & bytes delta = 1;& & uint64 sequence = 2;& & uint64 blockNumber = 3;& & SyncStateSnapshotRequest request = 4;}SYNC_STATE_GET_DELTAS 默认Ledger会包含500个transition deltas。delta(j)表示block(i)和block(j)之间的状态转变(i = j -1)。4.1.3 Consensus MessagesConsensus framework会将接收到的CHAIN_TRANSACTION转变成CONSENSUS,然后广播给所有的VP节点。4.1.4 Transaction Messages在fabric中的交易有三种:Deploy, Invoke 和 Query。Deploy将指定的chaincode安装到chain上,Invoke和Query会调用已经部署好的chaincode的函数。4.2 LedgerLedger主要包含两块:blockchain和world state。blockchain就是一系列连在一起的block,用来记录历史交易。world state是一个key-value数据库,当交易执行后,chaincode会将state存在里面。4.2.1 Blockchainblockchain是指由一些block连成的list,每一个block都包含上一个block的hash。一个block还会包含一些交易列表以及执行所有这些交易后world state的一个hash。message Block {& version = 1;& google.protobuf.Timestamp timestamp = 2;& bytes transactionsHash = 3;& bytes stateHash = 4;& bytes previousBlockHash = 5;& bytes consensusMetadata = 6;& NonHashData nonHashData = 7;}message BlockTransactions {& repeated Transaction transactions = 1;}那上一个block的hash是如何计算的呢:用 protocol buffer 序列化block的信息用 SHA3 SHAKE256 算法将序列化后的block信息哈希成一个512字节的输出上面的数据结构中有一个 transactionHash, 它是transaction merkle tree的根节点(用默克尔树来描述这些交易)。4.2.2 World State一个peer的world state是所有部署的chaincodes的状态(state)的集合。一个chaincode的状态由键值对(key-value)的集合来描述。我们期望网络里的节点拥有一致的world state,所以会通过计算world state的 crypto-hash 来进行比较,但是将会消耗比较昂贵的算力,为此我们需要设计一个高效率的计算方法。比如引入Bucket-tree来实现world state的组织。world state中的key的表示为{chaincodeID, ckey},我们可以这样来描述key, key = chaincodeID+nil+cKey。world state的key-value会存到一个hash表中,这个hash表有预先定义好数量(numBuckets)的buckets组成。一个 hash function 会来定义哪个桶包含哪个key。这些buckets都将作为merkle-tree的叶子节点,编号最小的bucket作为这个merkle-tree最左面的叶子节点。倒数第二层的构建,从左开始每maxGroupingAtEachLevel(预先定义好数量)这么多的叶子节点为一组聚在一起,形成N组,每一组都会插入一个节点作为所包含叶子节点的父节点,这样就形成了倒数第二层。要注意的是,最末层的父节点(就是刚刚描述的插入的节点)可能会有少于maxGroupingAtEachLevel的孩子节点。按照这样的方法不断构建更高一层,直到根节点被构建出来。举一个例子,{numBuckets=10009 and maxGroupingAtEachLevel=10},它形成的tree的每一次包含的节点数目如下:4.3 Consensus Frameworkconsensus framework包含了三个package:consensus、controller和helper。municator用来发送消息给其他的VP节点consensus.Executor用于交易的启动、执行和回滚,还有preview、commitcontroller指定被VP节点使用的consensus pluginhelper用来帮助consensus plugin与stack交互,例如维护message handler目前有两个consensus plugin:pbft和noops。&pbft是 微软论文PBFT共识算法的一个实现。&noops 用于开发和测试,它没有共识机制,但是会处理所有consensus message,所以如果要开发自己的consensus plugin,从它开始吧。4.3.1 Executor 接口在源码中我们会经常看 executor 相关的代码,这个借口下的方法可以做到:&开始批量交易、执行交易、提交与回滚交易4.3.2 Ledger 接口type Ledger interface {& & ReadOnlyLedger& & UtilLedger& & WritableLedger}ReadOnlyLedger接口用来查询 ledger 的本地备份,不做修改,函数有:1、GetBlockchainSize() (uint64, error),这个函数在源码里常见,返回了ledger的长度2、GetBlock(id uint64) (block *pb.Block, err error)3、GetCurrentStateHash() (stateHash []byte, err error),返回 ledger 当前状态的hash4.3.3 helper 包helper包可以帮助VP节点建立与其他peer之间的通信和消息处理,helper.HandleMessage,这个函数会处理四种消息类型,pb.Message_CONSENSUS&pb.Message_CHAIN_TRANSACTION&pb.Message_CHAIN_QUERY&others4.4 Chaincodechaincode是一段应用级的代码,交易逻辑就在里面,fabric是用Docker容器来运行chaincode的。一旦chaincode容器被启动,它就会通过gRPC与启动这个chaincode的VP(Validating Peer)节点连接。上面4.1提到的四种消息中有一种叫transaction message,包含Deploy, Invoke 和 Query。指的就是与chaincode相关的交易信息。chaincode需要实现三个函数,Init,Invoke 和 Query。Init是构造函数,它只在部署交易时被执行,Query函数用来读取状态。Invoke来进行交易的发生。chaincode容器被部署时,会向对应的peer进行注册,注册之后,VP节点就会通知chaincode容器调用Init函数。其实peer跟chaincode容器之间是隔着一个shim层的,chaincode容器的shim层会接收来自peer的信息,根据信息调用chaincode相应的函数,如Invoke。5. What we can do5.1 Asset Management 资产管理这是一个在fabric上实现的一个chaincode demo,用来模拟数字资产的管理。chaincode一共有四个函数:init(user), assign(asset, user), transfer(asset, user), query(asset)。在chaincode被部署时,init(user)就会被自动调用。设想一下,&1. Alice是这个chaincode的部署者;&2. Alice想要将管理员这个角色分配给Bob;&3. 之后Alice会获得Bob的一个TCert,我们叫这个证书BobCert;&4. Alice构建一条deploy交易,并将交易的元数据设置到BobCert;&5. Alice将这个交易提交到fabric网络中。这样Bob就会被赋予管理员角色,这就是init函数要做的。接下来看一下assign:1、Bob成为了chaincode的管理员2、Bob想要将资产‘Picasso’分配给Charlie3、Bob会获得Charlie的一个TCert,我们叫这个证书CharlieCert4、Bob构建一个invoke交易,来调用assign这个函数,参数是 (‘Picasso’, Base64(DER(CharlieCert)))5、Bob提交这个交易到fabric网络中transfer函数:&1. Charlie成为了资产‘Picasso’的拥有者了&2. Charlie想要将‘Picasso’的所有权转交给Dave&3. Charlie获得Dave的一个TCert,我们叫这个证书为DaveCert&4. Charlie构建一个invoke交易,来调用transfer函数,参数为(‘Picasso’, Base64(DER(DaveCert)))&5. Charlie提交交易到fabric网络中query函数用来查询资产的拥有者。完成整套逻辑,需要我们写的chaincode的代码只有三百行。像在transfer的实现中,我们需要首先判断这个发起人的身份,确保只有资产所有者才能转移自己的资产,然后全网公证资产的转移,任何一方都无法篡改和抵赖。6. Defect其实fabric还存在着诸多的缺陷,毕竟目前还是一个襁褓中的婴儿。&例如memberserice与现有CA系统的集成,数据库部分也欠缺。&其实这里有一个开放性的命题,大家不妨一起想想,可以在博客下面的评论中留言,或许会碰撞出一些火花:VP(validating peer)节点是网络的实质性参与者,可以提出交易,并就交易达成一致,然后执行交易,但在fabric中有一个节点叫NVP(not-validating peer)节点,它只与某一个VP节点相连,不能参与交易执行和一致性达成,只能为它所连的VP节点分担API处理部分和事件部分的压力,但可以去查询网络产生的ledger,有人说这样的设计可以有助于监管者加入进来,监管者只需查询生成的ledger,而不需参与交易,也有人说NVP节点引入是为了降低VP节点的计算压力,将一些外围的操作让NVP节点来做。7. ContributionImplement SYNC_BLOCK_ADDED handler我的一个同事实现了SYNC_BLOCK_ADDED消息的handler,这样在noops共识模式下,当一个block被加到(mined/added)ledger时,NVP节点就可以处理这条消息了,并将最新加入的block存在它自己的ledger中。SYNC_BLOCK_ADDED message 对应的callback是beforeBlockAdded(core/peer/handler.go),官方代码如下:func (d *Handler) beforeBlockAdded(e *fsm.Event) {& & peerLogger.Debugf("Received message: %s", e.Event)& & msg, ok := e.Args[0].(*pb.Message)& & if !ok {& & & & e.Cancel(fmt.Errorf("Received unexpected message type"))& & & & return& & }& & // Add the block and any delta state to the ledger& & _ = msg}这里并没有去获取和处理block的信息,我们需要加入如下:if ValidatorEnabled() {& & &e.Cancel(fmt.Errorf("VP shouldn't receive SYNC_BLOCK_ADDED"))& & &return&}& & // Add the block and any delta state to the ledger- & _ = msg&blockState := &pb.BlockState{}&err := proto.Unmarshal(msg.Payload, blockState)&if err != nil {& & &e.Cancel(fmt.Errorf("Error unmarshalling BlockState: %s", err))& & &return&}&coord := d.Coordinator&blockHeight := coord.GetBlockchainSize()&if blockHeight &= 0 {& & &e.Cancel(fmt.Errorf("No genesis block is made"))& & &return&}&curBlock, err := coord.GetBlockByNumber(blockHeight -1)&if err != nil {& & &e.Cancel(fmt.Errorf("Error fetching block #%d, %s", blockHeight -1, err))& & &return&}&hash, err := curBlock.GetHash()&if err != nil {& & &e.Cancel(fmt.Errorf("Error hashing latest block"))& & &return&}&pare(hash, blockState.Block.PreviousBlockHash) != 0 {& & &e.Cancel(fmt.Errorf("PreviousBlockHash of received block doesnot match hash of current block"))& & &return&}&coord.PutBlock(blockHeight, blockState.Block)&delta := &statemgmt.StateDelta{}&if err := delta.Unmarshal(blockState.StateDelta); nil != err {& & &e.Cancel(fmt.Errorf("Received a corrupt state delta"))& & &return&}&coord.ApplyStateDelta(msg, delta)&mitStateDelta(msg) != nil {& & &e.Cancel(fmt.Errorf("Played state forward, hashes matched, but failed to commit, invalidated state"))& & &return&}&f("Blockchain height grows into %d", coord.GetBlockchainSize())Enable statetransfer for HELLO message我们还发现当一个NVP节点刚加入网络时,它会发送一个DISC_HELLO message,随后从其他节点接收一个包含那个节点的blockchain信息的DISC_HELLO message,不过官方代码并没有给出NVP依据这些返回信息同步自己状态的实现。NVP正在网络中实施自己的状态同步时,一个新的block被mine,NVP却不能把这个新的block加入到自己的chain中。所以目前就出现了一个棘手的情况:当新的NVP节点刚加入网络时,通过HELLO message获取其他节点的blockchain信息开始同步自己的状态,这肯定需要一定的时间来完成,但与此同时,网络里的交易还在继续,新的block会被不断的mined,虽然NVP能接收到SYNC_BLOCK_ADDED,并拥有处理它的handler,但是这时候却不能将新的block信息加入到自己的chain中,因为hash不匹配,毕竟NVP节点并没有完成一开始的同步。
上一篇:下一篇:
已有0人参与讨论
你可能喜欢

我要回帖

更多关于 怎么搭建hyperledger 的文章

 

随机推荐