资讯详情

HyperLedger Fabric的协议规范

本文件是区块链行业的协议规范。它不会详细解释实现细节,而是描述系统与应用程序之间的界面和关系。

本规范的目标读者包括:

  • 符合这一标准的区块链制造商希望实现
  • 想扩展 fabric 工具开发者的功能
  • 利用区块链技术丰富其应用开发者

以下作者编写了这个分类: Binh Q Nguyen,Elli Androulaki, Angelo De Caro, Sheehan Anderson, Manish Sethi, ThorstenKramp, Alessandro Sorniotti, Marko Vukolic, Florian Simon Schubert, Jason KYellick, Konstantinos Christidis, Srinivasan Muralidharan, Anna D Derbakova,Dulce Ponceleon, David Kravitz, Diego Masini.

以下评审员对本文档进行了评审: Frank Lu, JohnWolpert, Bishop Brock, Nitin Gaur, Sharon Weed, Konrad Pabjan.

下面这些贡献者对这份规范提供了技术支持: Gennaro Cuomo,Joseph A Latone, Christian Cachin


  • 1.1 什么是 fabric ?
  • 1.2 为什么是 fabric ?
  • 1.3 术语

  • 2.1 架构
  • 2.1.1 Membership 服务
  • 2.1.2 Blockchain 服务
  • 2.1.3 Chaincode 服务
  • 2.1.4 事件
  • 2.1.5 应用程序接口
  • 2.1.6 命令行界面
  • 2.2 拓扑
  • 2.2.1 单验证 Peer
  • 2.2.2 多验证 Peers
  • 2.2.3 多链

  • 3.1 消息
  • 3.1.1 发现消息
  • 3.1.2 交易消息
  • 3.1.2.1 交易数据结构
  • 3.1.2.2 交易规范
  • 3.1.2.3 交易部署
  • 3.1.2.4 交易调用
  • 3.1.2.5 交易查询
  • 3.1.3 同步消息
  • 3.1.4 共识消息
  • 3.2 总账
  • 3.2.1 区块链
  • 3.2.1.1 块
  • 3.2.1.2 块 Hashing
  • 3.2.1.3 非散列数据(NonHashData)
  • 3.2.1.4 交易
  • 3.2.2 世界状态(World State)
  • 3.2.2.1 世界状态的 Hashing
  • 3.2.2.1.1 Bucket-tree
  • 3.3 Chaincode
  • 3.3.1 Virtual Machine 实例化
  • 3.3.2 Chaincode 协议
  • 3.3.2.1 Chaincode 部署
  • 3.3.2.2 Chaincode 调用
  • 3.3.2.3 Chaincode 查询
  • 3.3.2.4 Chaincode 状态
  • 3.4 可插拔的共识框架
  • 3.4.1 共识者接口
  • 3.4.2 共识程序接口
  • 3.4.3 Inquirer 接口
  • 3.4.4 Communicator 接口
  • 3.4.5 SecurityUtils 接口
  • 3.4.6 LedgerStack 接口
  • 3.4.7 Executor 接口
  • 3.4.7.1 开始批量交易
  • 3.4.7.2 执行交易
  • 3.4.7.3 提交回滚交易
  • 3.4.8 Ledger 接口
  • 3.4.8.1 ReadOnlyLedger 接口
  • 3.4.8.2 UtilLedger 接口
  • 3.4.8.3 WritableLedger 接口
  • 3.4.9 RemoteLedgers 接口
  • 3.4.10 Controller 包
  • 3.4.11 Helper 包
  • 3.5 事件
  • 3.5.1 事件流
  • 3.5.2 事件结构
  • 3.5.3 事件适配器

  •  
    1. 安全
  • 4.1 商业安全需求
  • 4.2 使用成员管理的用户隐私
  • 4.2.1 用户/客户端注册过程
  • 4.2.2 过期和废止证书
  • 4.3 基础设施层面提供的交易安全
  • 4.3.1 交易的安全生命周期
  • 4.3.2 交易保密性
  • 4.3.2.1 针对用户的保密
  • 4.3.2.2 针对验证器的保密
  • 4.3.3 防重放攻击
  • 4.4 应用的访问控制功能
  • 4.4.1 调用访问控制
  • 4.4.2 读访问控制
  • 4.5 在线钱包服务
  • 4.6 网络安全(TLS)
  • 4.7 当前版本的限制
  • 4.7.1 简化客户端
  • 4.7.2 简化交易保密

  • 5.1 概览
  • 5.2 Core PBFT

  • 6.1 REST 服务
  • 6.2 REST API
  • 6.3 CLI

  • 7.1 应用组成
  • 7.2 应用样例

  • 8.1 企业集成
  • 8.2 性能与可扩展性
  • 8.3 附加的共识插件
  • 8.4 附加的语言


这份文档规范了适用于工业界的区块链的概念,架构和协议。

fabric 是在系统中数字事件,交易调用,不同参与者共享的总账。总账只能通过共识的参与者来更新,而且一旦被记录,信息永远不能被修改。每一个记录的事件都可以根据参与者的协议进行加密验证。

交易是安全的,私有的并且可信的。每个参与者通过向网络membership服务证明自己的身份来访问系统。交易是通过发放给各个的参与者,不可连接的,提供在网络上完全匿名的证书来生成的。交易内容通过复杂的密钥加密来保证只有参与者才能看到,确保业务交易私密性。

总账可以按照规定规则来审计全部或部分总账分录。在与参与者合作中,审计员可以通过基于时间的证书来获得总账的查看,连接交易来提供实际的资产操作。

fabric 是区块链技术的一种实现,比特币是可以在fabric上构建的一种简单应用。它通过模块化的架构来允许组件的“插入-运行”来实现这份协议规范。它具有强大的容器技术来支持任何主流的语言来开发智能合约。利用熟悉的和被证明的技术是fabric的座右铭。

早期的区块链技术提供一个目的集合,但是通常对具体的工业应用支持的不是很好。为了满足现代市场的需求,fabric 是基于工业关注点针对特定行业的多种多样的需求来设计的,并引入了这个领域内的开拓者的经验,如扩展性。fabric 为权限网络,隐私,和多个区块链网络的私密信息提供一种新的方法。

以下术语在此规范的有限范围内定义,以帮助读者清楚准确的了解这里所描述的概念。

 是区块链上执行功能的一个请求。功能是使用**链码(Chaincode)**来实现的。

 是向客户端应用这样发出交易的实体。

 是一系列包含交易和当前**世界状态(World State)**的加密的链接块。

 是包含交易执行结果的变量集合。

 是作为交易的一部分保存在总账上的应用级的代码(如智能合约)。链码运行的交易可能会改变世界状态。

 是网络中负责达成共识,验证交易并维护总账的一个计算节点。

 是网络上作为代理把交易员连接到附近验证节点的计算节点。非验证Peer只验证交易但不执行它们。它还承载事件流服务和REST服务。

 是一个由每个实体或节点都是网络成员所组成的区块链网络。匿名节点是不允许连接的。

 是链上的交易者需要隐瞒自己在网络上身份。虽然网络的成员可以查看交易,但是交易在没有得到特殊的权限前不能连接到交易者。

 是交易的内容不能被非利益相关者访问到的功能。

 作为商业用途的区块链需要遵守法规,很容易让监管机构审计交易记录。所以区块链是必须的。

fabric是由下面这个小节所描述的核心组件所组成的。

这个架构参考关注在三个类别中:会员(Membership),区块链(Blockchan)和链码(chaincode)。这些类别是逻辑结构,而不是物理上的把不同的组件分割到独立的进程,地址空间,(虚拟)机器中。

成员服务为网络提供身份管理,隐私,保密和可审计性的服务。在一个不带权限的区块链中,参与者是不需要被授权的,且所有的节点都可以同样的提交交易并把它们汇集到可接受的块中,既:它们没有角色的区分。成员服务通过公钥基础设施(Public KeyInfrastructure (PKI))和去中心化的/共识技术使得不带权限的区块链变成带权限的区块链。在后者中,通过实体注册来获得长时间的,可能根据实体类型生成的身份凭证(登记证书enrollmentcertificates)。在用户使用过程中,这样的证书允许交易证书颁发机构(TransactionCertificate Authority (TCA))颁发匿名证书。这样的证书,如交易证书,被用来对提交交易授权。交易证书存储在区块链中,并对审计集群授权,否则交易是不可链接的。

区块链服务通过 HTTP/2 上的点对点(peer-to-peer)协议来管理分布式总账。为了提供最高效的哈希算法来维护世界状态的复制,数据结构进行了高度的优化。每个部署中可以插入和配置不同的共识算法(PBFT, Raft, PoW,PoS)。

链码服务提供一个安全的,轻量的沙箱在验证节点上执行链码。环境是一个“定的”且安全的包含签过名的安全操作系统镜像和链码语言,Go,Java 和 Node.js 的运行时和 SDK 层。可以根据需要来启用其他语言。

验证 peers 和链码可以向在网络上监听并采取行动的应用发送事件。这是一些预定义好的事件集合,链码可以生成客户化的事件。事件会被一个或多个事件适配器消费。之后适配器可能会把事件投递到其他设备,如 Web hooks 或 Kafka。

fabric的主要接口是 REST API,并通过 Swagger 2.0 来改变。API 允许注册用户,区块链查询和发布交易。链码与执行交易的堆间的交互和交易的结果查询会由 API 集合来规范。

CLI包含REST API的一个子集使得开发者能更快的测试链码或查询交易状态。CLI 是通过 Go 语言来实现,并可在多种操作系统上操作。

fabric 的一个部署是由成员服务,多个验证 peers、非验证 peers 和一个或多个应用所组成一个链。也可以有多个链,各个链具有不同的操作参数和安全要求。

功能上讲,一个非验证 peer 是验证 peer 的子集;非验证 peer 上的功能都可以在验证 peer 上启用,所以在最简单的网络上只有一个验证peer组成。这个配置通常使用在开发环境:单个验证 peer 在编辑-编译-调试周期中被启动。

单个验证 peer 不需要共识,默认情况下使用noops插件来处理接收到的交易。这使得在开发中,开发人员能立即收到返回。

生产或测试网络需要有多个验证和非验证 peers 组成。非验证 peer 可以为验证 peer 分担像 API 请求处理或事件处理这样的压力。

网状网络(每个验证peer需要和其它验证peer都相连)中的验证 peer 来传播信息。一个非验证 peer 连接到附近的,允许它连接的验证 peer。当应用可能直接连接到验证 peer 时,非验证 peer 是可选的。

验证和非验证 peer 的各个网络组成一个链。可以根据不同的需求创建不同的链,就像根据不同的目的创建不同的 Web 站点。

fabric的点对点(peer-to-peer)通信是建立在允许双向的基于流的消息gRPC上的。它使用Protocol Buffers来序列化peer之间传输的数据结构。Protocol buffers是语言无关,平台无关并具有可扩展机制来序列化结构化的数据的技术。数据结构,消息和服务是使用 proto3 language注释来描述的。

消息在节点之间通过Messageproto 结构封装来传递的,可以分为 4 种类型:发现(Discovery), 交易(Transaction), 同步(Synchronization)和共识(Consensus)。每种类型在payload中定义了多种子类型。

messageMessage {

   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对象。

在启动时,如果CORE_PEER_DISCOVERY_ROOTNODE被指定,那么 peer 就会运行发现协议。CORE_PEER_DISCOVERY_ROOTNODE是网络(任意peer)中扮演用来发现所有 peer 的起点角色的另一个 peer 的 IP 地址。协议序列以payload是一个包含:

messageHelloMessage {

  PeerEndpoint peerEndpoint = 1;

  uint64 blockNumber = 2;

}

messagePeerEndpoint {

    PeerID ID = 1;

    string address = 2;

    enum Type {

      UNDEFINED = 0;

      VALIDATOR = 1;

      NON_VALIDATOR = 2;

    }

    Type type = 3;

    bytes pkiID = 4;

}

 

messagePeerID {

    string name = 1;

}

这样的端点的HelloMessage对象的DISC_HELLO消息开始的。

  • PeerID 是在启动时或配置文件中定义的 peer 的任意名字
  • PeerEndpoint 描述了端点和它是验证还是非验证 peer
  • pkiID 是 peer 的加密ID
  • address 以ip:port这样的格式表示的 peer 的主机名或IP和端口
  • blockNumber 是 peer 的区块链的当前的高度

如果收到的DISC_HELLO 消息的块的高度比当前 peer 的块的高度高,那么它马上初始化同步协议来追上当前的网络。

DISC_HELLO之后,peer 会周期性的发送DISC_GET_PEERS来发现任意想要加入网络的 peer。收到DISC_GET_PEERS后,peer 会发送payload 包含PeerEndpoint的数组的DISC_PEERS作为响应。这是不会使用其它的发现消息类型。

有三种不同的交易类型:部署(Deploy),调用(Invoke)和查询(Query)。部署交易向链上安装指定的链码,调用和查询交易会调用部署号的链码。另一种需要考虑的类型是创建(Create)交易,其中部署好的链码是可以在链上实例化并寻址的。这种类型在写这份文档时还没有被实现。

CHAIN_TRANSACTION和CHAIN_QUERY类型的消息会在payload带有Transaction对象:

messageTransaction {

    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;

}

 

messageTransactionPayload {

         bytes payload = 1;

}

 

enumConfidentialityLevel {

    PUBLIC = 0;

    CONFIDENTIAL = 1;

}

 

  • type - 交易的类型, 为1时表示:
    • UNDEFINED - 为未来的使用所保留.
    • CHAINCODE_DEPLOY - 代表部署新的链码.
      • CHAINCODE_INVOKE - 代表一个链码函数被执行并修改了世界状态
      • CHAINCODE_QUERY - 代表一个链码函数被执行并可能只读取了世界状态
      • CHAINCODE_TERMINATE - 标记的链码不可用,所以链码中的函数将不能被调用
  • chaincodeID - 链码源码,路径,构造函数和参数哈希所得到的ID
  • payloadHash - TransactionPayload.payload所定义的哈希字节.
  • metadata - 应用可能使用的,由自己定义的任意交易相关的元数据
  • uuid - 交易的唯一ID
  • timestamp - peer 收到交易时的时间戳
  • confidentialityLevel - 数据保密的级别。当前有两个级别。未来可能会有多个级别。
  • nonce - 为安全而使用
  • cert - 交易者的证书
  • signature - 交易者的签名
  • TransactionPayload.payload - 交易的payload所定义的字节。由于payload可以很大,所以交易消息只包含payload的哈希

交易安全的详细信息可以在第四节找到

一个交易通常会关联链码定义及其执行环境(像语言和安全上下文)的链码规范。现在,有一个使用Go语言来编写链码的实现。将来可能会添加新的语言。

messageChaincodeSpec {

    enum Type {

        UNDEFINED = 0;

        GOLANG = 1;

        NODE = 2;

    }

    Type type = 1;

    ChaincodeID chaincodeID = 2;

    ChaincodeInput ctorMsg = 3;

    int32 timeout = 4;

    string secureContext = 5;

    ConfidentialityLevel confidentialityLevel =6;

    bytes metadata = 7;

}

 

messageChaincodeID {

    string path = 1;

    string name = 2;

}

 

messageChaincodeInput {

    string function = 1;

    repeated string args  = 2;

}

  • chaincodeID - 链码源码的路径和名字
  • ctorMsg - 调用的函数名及参数
  • timeout - 执行交易所需的时间(以毫秒表示)
  • confidentialityLevel - 这个交易的保密级别
  • secureContext - 交易者的安全上下文
  • metadata - 应用想要传递下去的任何数据

当 peer 收到chaincodeSpec后以合适的交易消息包装它并广播到网络

部署交易的类型是CHAINCODE_DEPLOY,且它的payload包含ChaincodeDeploymentSpec对象。

messageChaincodeDeploymentSpec {

    ChaincodeSpec chaincodeSpec = 1;

    google.protobuf.Timestamp effectiveDate =2;

    bytes codePackage = 3;

}

  • chaincodeSpec - 参看上面的3.1.2.2节.
  • effectiveDate - 链码准备好可被调用的时间
  • codePackage - 链码源码的gzip

当验证 peer 部署链码时,它通常会校验codePackage的哈希来保证交易被部署到网络后没有被篡改。

调用交易的类型是CHAINCODE_DEPLOY,且它的payload包含ChaincodeInvocationSpec对象。

messageChaincodeInvocationSpec {

    ChaincodeSpec chaincodeSpec = 1;

}

查询交易除了消息类型是CHAINCODE_QUERY其它和调用交易一样

同步协议以3.1.1节描述的,当 peer 知道它自己的区块落后于其它 peer 或和它们不一样后所发起的。peer 广播SYNC_GET_BLOCKS,SYNC_STATE_GET_SNAPSHOT或SYNC_STATE_GET_DELTAS并分别接收SYNC_BLOCKS,SYNC_STATE_SNAPSHOT或 SYNC_STATE_DELTAS。

安装的共识插件(如:pbft)决定同步协议是如何被应用的。每个消息是针对具体的状态来设计的:

 是一个SyncBlockRange对象,包含一个连续区块的范围的payload的请求。

messageSyncBlockRange {

    uint64 correlationId = 1;

    uint64 start = 2;

    uint64 end = 3;

}

接收peer使用包含 SyncBlocks对象的payload的SYNC_BLOCKS信息来响应

messageSyncBlocks {

    SyncBlockRange range = 1;

    repeated Block blocks = 2;

}

start和end标识包含的区块的开始和结束,返回区块的顺序由start和end的值定义。如:当start=3,end=5时区块的顺序将会是3,4,5。当start=5,end=3时区块的顺序将会是5,4,3。

 请求当前世界状态的快照。 payload是一个SyncStateSnapshotRequest对象

messageSyncStateSnapshotRequest {

  uint64 correlationId = 1;

}

correlationId是请求 peer 用来追踪响应消息的。接受 peer 回复payload为SyncStateSnapshot实例的SYNC_STATE_SNAPSHOT信息

messageSyncStateSnapshot {

    bytes delta = 1;

    uint64 sequence = 2;

    uint64 blockNumber = 3;

    SyncStateSnapshotRequest request = 4;

}

这条消息包含快照或以0开始的快照流序列中的一块。终止消息是len(delta) == 0的块

 请求连续区块的状态变化。默认情况下总账维护500笔交易变化。 delta(j)是block(i)和block(j)之间的状态转变,其中i=j-1。 payload包含SyncStateDeltasRequest实例

messageSyncStateDeltasRequest {

    SyncBlockRange range = 1;

}

接收 peer 使用包含 SyncStateDeltas实例的payload的SYNC_STATE_DELTAS信息来响应

messageSyncStateDeltas {

    SyncBlockRange

标签: ssk207变送器ssk207压力变送器0aa1压力变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台