深度探索Hyperledger技术与应用之超级账本的策略管理

超级账本Fabric中的权限管理和策略 权限管理是区块链网络十分重要的功能,负责控制某个身份在某个场景下是否允许采取某个操作(如读写某个资源)。 超级账本 Fabric 项目通过策略(Policy)来灵活指定各场景下的操作权限。 策略应用场景 具体来看,常见的策略场景包括如下表所示。其中,大部分都与系统配置链码相关,可以在通道配置中进行指定;部分为代码中的规定。 对于存储在通道配置中的策略,可以利用 configtx.yaml ... 阅读详情

image

上一篇分享了超级账本的系统逻辑架构和网络节点架构和典型交易流程,本篇主要分享超级账本的消息协议结构和策略管理。

1

消息协议结构

1、信封消息结构

信封消息是认证内容中最基本的单元。它由一个消息负载(Payload)和一个签名(Signature)组成。

// 信封包含一个带有签名的负载,以便认证该消息

message Envelope {

    // 编组的负载

    bytes payload = 1;

    // 负载头中指定创建者签名

    bytes signature = 2;

}

    // 负载是消息内容(允许签名)

message Payload {

    // 负载头部,提供身份验证并防止重放

    Header header = 1;

    // 数据,其编码由头的类型定义

    bytes data = 2;

}

负载包含:

1)消息头部。头部带有类型,描述负载的性质以及如何解组数据字段。此外,头部还包含创建者的信息和随机数,以及用来标识时间逻辑窗口的时期信息。只有在两个条件都成立的情况下,Peer节点才能接受一个信封。

  • 消息中指定的时期信息是当前窗口期;

  • 该负载在该周期内只看到一次(即没有重放)。

2)数据字段的类型由头部指定。头部消息的组织方式如下所示:

message Header {

    bytes channel_header = 1;

    bytes signature_header = 2;

}

    // 通道头是一个通用的预防重放和身份标识的消息,它包含在一个被签名的负载之中

message ChannelHeader {

    int32 type = 1; // 头类型0-10000由HeaderType保留和定义

    // 版本指示消息协议版本

    int32 version = 2;

    // 时间戳是发件人创建消息的本地时间

    google.protobuf.Timestamp timestamp = 3;

    // 该消息绑定通道的标识符

    string channel_id = 4;

    // 端到端使用唯一的标识符

    //  -  由较高层设置,如最终用户或SDK

    //  -  传递给背书节点(将检查唯一性)

    //  -  当消息正确传递时,它将被记账节点检索(也会检查唯一性)

    //  -  存储于账本中

    string tx_id = 5;

    // 时期信息基于区块高度而定义,此字段标识时间的逻辑窗口

    // 只有在两个条件都成立的情况下,对方才接受提案响应

    // 1\. 消息中指定的时期信息是当前时期

    // 2\. 该消息在该时期内只看到一次(即没有重放)

    uint64 epoch = 6;

    // 根据消息头类型附加的扩展

    bytes extension = 7;

}

enum HeaderType {

    MESSAGE = 0;                   // 非透明消息

    CONFIG = 1;                    // 通道配置

    CONFIG_UPDATE = 2;             // 通道配置更新

    ENDORSER_TRANSACTION = 3;      // SDK提交背书

    ORDERER_TRANSACTION = 4;       // 排序管理内部使用

    DELIVER_SEEK_INFO = 5;         // 指示Deliver API查找信息

    CHAINCODE_PACKAGE = 6;         // 链码打包安装

}

message SignatureHeader {

    // 消息的创建者,链的证书

    bytes creator = 1;

    // 只能使用一次的任意数字,可用于检测重放攻击

    bytes nonce = 2;

}

信封消息结构对于验证负载的签名是必要的。否则,对于大载荷消息,就必须连接所有的载荷再进行签名验证,这往往成本很高。

经过排序后,批量的信封消息交付给记账节点进行验证,通过验证后的数据被记录到账本之中。

2、配置管理结构

区块链有与之相关的配置,配置设置在创世区块之中,但可能在后续被修改。该配置信息在类型为CONFIGURATION_TRANSACTION的信封消息中编码。配置信息本身就是区块的一个单独交易。配置信息交易没有任何依赖,所以每个配置信息交易必须包含对于链的全量数据,而不是增量数据。使用全量数据更容易引导新的peer或排序节点,也便于未来进行裁剪工作。

CONFIGURATION_TRANSACTION类型的信封消息具有ConfigurationEnvelope类型的负载数据。它定义为:

message ConfigurationEnvelope {

    repeated SignedConfigurationItem Items = 3;

}

配置信息的信封消息有与之关联的序列号和链ID。每次修改配置序列号必须递增,这可以作为防止重放攻击的一个简单机制。配置信息的信封中会嵌入一系列的SignedConfigurationItems,定义如下:

message SignedConfigurationItem {

    bytes ConfigurationItem = 1;

    repeated Envelope Signatures = 2;

}

因为SignedConfigurationItem必须支持多个签名,所以它包含一组重复的信封消息。这些消息中每个都有一个类型为CONFIGURATION_ITEM的头部。负载的数据部分在ConfigurationItem中保存,定义为:

message ConfigurationItem {

    enum ConfigurationType {

        Policy = 0;

        Chain = 1;

        Orderer = 2;

        Fabric = 3;

            }

    bytes ChainID = 1;

    uint64 LastModified = 2;

    ConfigurationType Type = 3;

    string ModificationPolicy = 4;

    string Key = 5;

    bytes Value = 6;

}

Type提供了配置项的范围和编码信息。LastModified字段设置为上一次配置项被修改时配置信息信封中的序列号。ModificationPolicy指向一个已经命名的策略,用来对将来的签名进行评估,以确定修改是否被授权。Key和Value字段分别用作引用配置项及其内容。

修改配置包含以下内容:

  • 检索现有配置;

  • 递增配置信息信封消息中的序列号;

  • 修改所需的配置项,将每个配置项的LastModified字段设置为递增后的序列号;

  • 更新SignedConfigurationItem中的签名信息;

  • 将签名后的信封信息提交给排序节点。

配置管理员将验证:

  • 所有配置项和信封都指向正确的链;

  • 添加或修改了哪些配置项;

  • 有没有现有的配置项被忽略(即提交的数据是全集);

  • 所有配置更改的LastModification都等于信封消息中的序列号;

  • 所有配置更改均符合相应的修改策略。

任何有权更改配置项的角色都可以构建新的配置信息交易。修改配置项将更新序列号并产生新的创始区块,这将引导新加入网络的各种节点。

3、背书流程结构

当Envelope.data中携带与链码相关的消息时,使用ENDORSER_TRANSACTION类型。

获得批准的ENDORSER_TRANSACTION负载流程如下。

首先,客户端向所有相关的背书节点发送提案消息(提案基本上是要进行一些影响账本的动作)。

然后,每个背书节点向客户端发送一个提案响应消息。提案响应包含背书结果的成功/错误码、应答负载和签名。应答负载之中包含提案的哈希值信息,用此信息可以将提案和针对该提案的应答安全地连接起来。

最后,客户端将背书结果写入交易中,签名并发送到排序服务。

在接下来的章节中,我们将详细介绍消息及其流程。

1. 交易提案结构

一个提案消息包含头部(包含描述它的一些元数据,例如类型、调用者的身份、时间、链的ID、加密的随机数)和不透明的负载:

message SignedProposal {

    // 提案

    bytes proposal_bytes = 1;

    // 对提案进行签名,该签名将和头部的创建者标识进行验证

    bytes signature = 2;

}

message Proposal {

    // 提案头部

    bytes header = 1;

    // 提案负载,具体结构由头部的类型决定

    bytes payload = 2;

    // 提案的可选扩展。对于CHAINCODE类型的消息,其内容可能是ChaincodeAction消息

    bytes extension = 3;

}

一个提案发送给背书节点进行背书。该提案包含:

  • 头部,可以解组为头部信息;

  • 负载,由头部的类型决定;

  • 扩展,由头部的类型决定。

和信封消息结构类似,这种SignedProposal消息结构也是重要的。否则,对于大载荷消息,我们必须连接所有的载荷再进行签名验证,这往往成本很高。

当背书节点收到签名后的提案消息后,它将验证消息中的签名。验证签名需要以下步骤。

  • 预验证用户生成签名证书的有效性。一旦SignedProposal.proposal_bytes和Proposal.header都解组成功,就可以认为证书基本是可用的。虽然这种在证书验证前的解组操作可能并不太理想,但是在这个阶段可以过滤掉证书过期的情况。

  • 验证证书是否可信(证书是否由受信任的CA签名),并允许交易(能否通过ACL检查)。

  • 验证SignedProposal.proposal_bytes上的签名是否有效。

  • 检测重放攻击。

以下是当ChainHeader的类型为ENDORSER_TRANSACTION时的消息:

message ChaincodeHeaderExtension {

    // 控制提案的负载在最终交易和账本中的可见程度

    bytes payload_visibility = 1;

    // 要定位的链代码ID

    ChaincodeID chaincode_id = 2;

}

ChaincodeHeaderExtension消息用于指定要调用的链码以及应在账本中呈现的内容。理想情况下,payload_visibility是可配置的,*支持至少3种主要可见性模式:*

  • 负载所有字节都可见;

  • 只有负载的哈希值可见;

  • 任何东西都不可见。

注意,可见性功能可能也会由ESCC设置,此时本字段将会被覆盖。另外本字段也将影响ProposalResponsePayload.proposalHash的内容。

message ChaincodeProposalPayload {

    // 包含调用链码的参数,

    bytes input  = 1;

    // 用于实现某些应用程序级的加密数据

    map<string, bytes> TransientMap = 2;

}

ChaincodeProposalPayload消息包含调用链码的参数。TransientMap字段的内容应始终从信封消息中省略掉,并不记录到账本之中。

message ChaincodeAction {

    // 调用链码产生的读/写集

    bytes results = 1;

    // 调用链码产生的事件

    bytes events = 2;

    // 调用链码的结果

    Response response = 3;

    // 含链ID、背书节点在模拟执行提案时设置

    // 账本节点将验证版本号是否与链码最新版本匹配,含有链ID信息将支持单个交易打开多个链码

    ChaincodeID chaincode_id = 4;

}

ChaincodeAction消息包含执行链码所产生的动作和事件。results字段包含读取集合,events字段包含由链码执行生成的事件。

2. 提案响应结构

提案响应消息从背书节点返回给提案客户端。背书节点使用该消息表达对于交易提案的处理结果。应答结果可能是成功也可能是失败,另外还会包含动作描述和背书节点的签名。如果足够数量的背书节点同意相同的动作并进行签名,则可以生成负载消息,并发送给排序节点。

message ProposalResponse {

    // 消息协议版本

    int32 version = 1;

    // 消息创建时间,由消息发送者定义

    google.protobuf.Timestamp timestamp = 2;

    // 某个动作的背书是否成功

    Response response = 4;

    // 负载,ProposalResponsePayload字节序列

    bytes payload = 5;

    // 提案的具体背书内容,基本上就是背书节点的签名

    Endorsement endorsement = 6;

}

message ProposalResponsePayload {

    // 触发此应答交易提案的哈希值

    bytes proposal_hash = 1;

    // 扩展内容,应该解组为特定类型的消息

    bytes extension = 2;

}

message Endorsement {

    // 背书节点身份(例如,证书信息)

    bytes endorser = 1;

    // 签名,对提案应答负载和背书节点证书这两个内容进行签名

    bytes signature = 2;

}

ProposalResponsePayload消息是提案响应的负载部分。这个消息是客户端请求和背书节点动作之间的“桥梁”。对于链码来说,它包含一个表示提议的哈希值proposal_hash,以及表示链码状态变化和事件extension字段。

proposal_hash字段将交易提案和提案响应两者对应起来,即为了实现异步系统的记账功能也为了追责和抗抵赖的安全诉求。哈希值通常会覆盖整个提案消息的所有字节中。但是,这样实现就意味着只有获得完整的提案消息才能验证哈希值的正确性。

出于保密原因,使用链码不太可能将提案的负载直接存储在账本中。例如,类型为ENDORSER_TRANSACTION的消息,需要将提案的头部和负载分开进行处理:头部总是进行完整散列的,而负载则可能进行完整散列或对哈希值再进行散列,或者根本不进行散列。

3. 背书交易结构

客户端获得足够的背书后,可以将这些背书组合成一个交易信息。这个交易信息可以设置为负载信息的数据字段。以下是在这种情况下要使用的具体消息:

message Transaction {

    // 负载是一个TransactionAction数组,每个交易需要一个数组来适应多个动作

    repeated TransactionAction actions = 1;

}

message TransactionAction {

    // 提案头部

    bytes header = 1;

    // 负载由头部类型决定,它是ChaincodeActionPayload字节序列

    bytes payload = 2;

}

TransactionAction消息将提案绑定到其动作。它的头部是SignatureHeader消息,它的负载是ChaincodeActionPayload消息。

message ChaincodeActionPayload {

    // ChaincodeProposalPayload消息的字节序列,内容来自链码原始调用的参数

    bytes chaincode_proposal_payload = 1;

    // 应用于账本的动作列表

    ChaincodeEndorsedAction action = 2;

}

ChaincodeActionPayload消息携带chaincodeProposalPayload和已经通过背书的动作以应用于账本。主要的可见性模式是“full”(整个ChaincodeProposalPayload消息包含在这里)、“hash”(仅包含ChaincodeProposalPayload消息的哈希值)或“nothing”。该字段将用于检查ProposalResponsePayload.proposalHash的一致性。此外,action字段包含应用于账本的动作列表。

message ChaincodeEndorsedAction {

    // 由背书节点签名的ProposalResponsePayload消息字节序列

    bytes proposal_response_payload = 1;

    // 提案背书,基本上是背书节点的签名

    repeated Endorsement endorsements = 2;

}

ChaincodeEndorsedAction消息承载有关具体提案的背书信息。proposalResponsePayload是由背书节点签名的,对于ENDORSER_TRANSACTION类型,ProposalResponsePayload的extenstion字段会带有一个ChaincodeAction。此外,endorsements字段包含提案已经收到的背书信息。

2

策略管理和访问控制

在Hyperledger Fabric 1.0中,较多的地方都使用策略进行管理,它是一种权限管理的方法,包括交易背书策略、链码的实例化策略、通道管理策略等。

1、策略定义及其类型

策略定义了一些规则,验证签名数据是否符合定义的条件,结果为TRUE或者FALSE。策略的定义如下:

type Policy struct {

    Type  int32  // 策略的类型

    Value []byte // 策略的内容

}

策略的类型有两种。

1)SignaturePolicy:在基于验证签名策略的基础上,支持条件AND、OR、NOutOf的任意组合,其中的NOutOf指的是满足m个条件中的n个就表示满足策略(m≥n)。比如OR(Org1.Admin, NOutOf(2, Org2.Member))表示Org1的管理员或者两个Org2的成员签名都满足策略。

2)ImplicitMetaPolicy:隐含的元策略,是在SignaturePolicy之上的策略,支持大多数的组织管理员这种策略,只适用于通道管理策略。

SignaturePolicy实际只有两种类型,SignedBy和NOutOf,其他的,比如AND和OR都会转换成NOutOf类型。其定义如下:

type SignaturePolicy struct {

    // 支持的类型有:

    // *SignaturePolicy_SignedBy,验证单个签名是否正确

    // *SignaturePolicy_NOutOf_,验证是否有n个签名都正确

    Type isSignaturePolicy_Type `protobuf_oneof:"Type"`

}

ImplicitMetaPolicy是递归策略的定义方法,名称中的Implicit说明规则是由子策略生成的,Meta说明策略依赖其他策略的验证结果。

type ImplicitMetaPolicy struct {

    SubPolicy string                   // 子策略的名称

    Rule      ImplicitMetaPolicy_Rule  // 策略的规则

}

策略的规则支持3种形式:

  • ImplicitMetaPolicy_ANY:任意一个子规则成立就满足策略;

  • ImplicitMetaPolicy_ALL:全部子规则都成立才满足策略;

  • ImplicitMetaPolicy_MAJORITY:大多数的子规则成立就满足策略。

特别说明ImplicitMetaPolicy_MAJORITY需要满足子规则数的计算方法:

threshold = len(subPolicies)/2 + 1

比如一共有3个子策略,需要至少2个子策略成立才能满足策略。如果总共有4个子策略,需要至少3个子策略成立才能满足策略。如果没有子策略,默认是满足的。

策略的内容可以有多种,下面分别来看几种策略:交易背书策略、链码实例化策略和通道管理策略。

2、交易背书策略

交易背书策略是对交易进行背书的规则,是跟通道和链码相关的,在链码实例化的时候指定。在链码调用的时候,需要从背书节点收集足够的签名背书,只有通过背书策略的交易才是有效的。这是通过应用程序和背书节点之间的交互来完成的,这在前面的交易流程里已经介绍过了。

交易背书策略的验证

背书是由一组签名组成的,每个Peer节点接收到区块时,都能根据交易的内容本地验证背书是否符合背书策略,不需要和其他节点交互。验证交易背书的基本原则是:

  • 所有的背书都是有效的,验证消息用有效的证书进行正确的签名;

  • 满足背书策略的有效背书数量,转化为NOutOf格式进行比较;

  • 背书是期望的背书节点签名的,在背书策略中指定了哪些组织和角色是有效的背书节点。

如何来实现这几个原则的呢?我们先从背书签名的命令行语法开始,背书签名的语法AND和OR都可以转为NOutOf:

  • AND(A, B)可以转换为NOutOf(1, A, B);

  • OR(A, B)可以转换为NOutOf(2, A, B)。

我们主要来看下NOutOf如何实现,背书策略的定义如下:

type SignaturePolicyEnvelope struct {

    Version    int32                    // 背书策略版本,默认都是0

    Rule       *SignaturePolicy         // 背书策略规则:签名策略

    Identities []*common1.MSPPrincipal  // 背书策略主体:MSP主体签名

}

其中,MSP主体(Principal)是基于MSP的身份标识的,有如下几种类型。

  • MSPPrincipal_ROLE:基于MSP角色的验证方法,目前只有admin和member两种。

  • MSPPrincipal_ORGANIZATION_UNIT:基于部门的验证方法,同一个MSP中的不同部门。

  • MSPPrincipal_IDENTITY:基于某个具体身份证书的验证方法,验证签名是否有效。

MSPPrincipal的定义如下:

type MSPPrincipal struct {

    PrincipalClassification MSPPrincipal_Classification // MSP的类型

    Principal []byte                // 根据MSP的类型不同,实体有不同的内容

}

根据不同的MSP类型,主体是不同的。

(1)基于MSP角色的验证

当PrincipalClassification是MSPPrincipal_ROLE时,主体存储的内容如下:

type MSPRole struct {

    // MSP标识符

    MspIdentifier string

    // MSP角色:可选值是MSPRole_MEMBER和MSPRole_ADMIN

    Role MSPRole_MSPRoleType

}

不同角色的验证方法如下:

  • MSPRole_MEMBER:验证是否为同一个MSP的有效签名;

  • MSPRole_ADMIN:验证签名者是否是MSP设置好的admin成员。

(2)基于部门的验证

当PrincipalClassification是MSPPrincipal_ORGANIZATION_UNIT时,主体存储的内容如下:

type OrganizationUnit struct {

    // MSP标识符

    MspIdentifier string

    // 组织部门标识符

    OrganizationalUnitIdentifier string

    // 证书标识符:信任证书链和组织部门信息的哈希

    CertifiersIdentifier []byte

}

验证过程的步骤是:

  • 验证是否为相同的MSP;

  • 验证是否是有效的证书;

  • 验证组织部门信息是否匹配。

(3)基于身份证书的验证

当PrincipalClassification是MSPPrincipal_IDENTITY时,主体存储的内容如下:

type identity struct {

    // 身份标识符,包含MSP标识符和身份编号

    id *IdentityIdentifier

    // 身份的数字证书,包含了对公钥的签名

    cert *x509.Certificate

    // 身份的公钥

    pk bccsp.Key

    // 身份的MSP信息

    msp *bccspmsp

}

这样验证MSP是否是有效证书就可以了。

命令行的背书策略语法

在命令行里,可以用一种简单的语言,根据主体的布尔表达式来表示策略。主体是用MSP来表示的,用来验证签名者的标识和签名者在MSP里的角色。目前支持两种角色:member和admin。主体的表示方法是MSP.ROLE,其中MSP是MSP的标识,ROLE可以是memeber也可以是admin。这都是有效的主体:Org0.admin表示由MSP标识Org0的任何一个管理员,Org1.memeber表示由MSP标识Org1的任何一个成员。

其语法是:EXPR(E[, E…]),其中EXPR可以是AND也可以是OR,E可以为一个主体,也可以为嵌套的EXPR。比如:

  • AND(‘Org1.member’, ‘Org2.member’, ‘Org3.member’)要求3个MSP标识Org1、Org2和Org3,其中每个MSP都有1个成员有1个签名;

  • OR(‘Org1.member’, ‘Org2.member’)要求2个MSP标识Org1、Org2,其中任何1个成员有1个签名;

  • OR(‘Org1.member’, AND(‘Org2.member’, ‘Org3.member’))要求MSP标识Org1的成员有1个签名,或者MSP标识Org2和Org3的成员都有1个签名。

目前在命令行的语法中,背书策略只支持AND和OR两种,并不支持更为复杂的NOutOf。这部分的设计在后续内容中也会有调整。SDK对背书策略都会转换成NOutOf语法,不过不是所有的SDK都支持。比如目前fabric-sdk-go提供的默认接口不支持NOutOf语法,但其内部是支持的,稍加改动很容易就能支持。详细可以参考cauthdsl_builder.go文件。

给链码指定背书策略

背书策略可以在部署的时候用-P参数指定,后面是具体的背书策略。比如:

peer chaincode deploy -C testchainid -n mycc -p github.com/hyperledger/fabric/

examples/chaincode/go/chaincode_example02 -c ‘{“Args”:[“init”,”a”,”100”,”b”,”200”]}’

-P “AND(‘Org1.member’, ‘Org2.member’)”

这个命令在链testchainid上部署链码 mycc,背书策略是AND(‘Org1.member’, ‘Org2.member’)。如果命令行里没有指定策略,那么默认的背书策略要求MSP标识DEFAULT成员的一个签名。

3、链码实例化策略

链码实例化策略是用来验证是否有权限进行链码实例化和链码升级的。链码实例化策略是在对链码打包和签名的时候指定的,如果没有指定实例化策略,默认是通道的管理员才能实例化。

type SignedChaincodeDeploymentSpec struct {

    // 链码部署规范

    ChaincodeDeploymentSpec []byte

    // 链码的实例化策略,结构同背书策略,在实例化的时候验证

    InstantiationPolicy []byte

    // 链码所有者的签名背书列表

    OwnerEndorsements []*Endorsement

}

链码实例化策略的定义和背书策略完全一样,验证方法也相同,只是用途和用法不一样。链码实例化策略是直接从链码打包中获取的,实例化完成后会将策略存放在链上。在链码实例化和升级的时候会先验证是否符合当前的实例化策略,验证通过才可以更新链码实例化策略。存储在链上的链码信息结构如下所示:

type ChaincodeData struct {

    // 链码名称

    Name string

    // 链码版本

    Version string

    // 链码的ESCC

    Escc string

    // 链码的VSCC

    Vscc string

    // 链码的背书策略

    Policy []byte

    // 链码的内容:包含链码的名称、版本、链码源码哈希、链码名称和版本的元数据哈希等内容

    // 不包含链码源码

    Data []byte

    // 链码指纹标识,目前没有使用

    Id []byte

    // 链码实例化策略

    InstantiationPolicy []byte

}

链码信息结构ChaincodeData在链上是按链码的名称索引的。

4、通道管理策略

通道配置是递归定义的:

type ConfigGroup struct {

    Version   uint64                   // 配置版本

    Groups    map[string]*ConfigGroup   // 子配置

    Values    map[string]*ConfigValue   // 配置值

    Policies  map[string]*ConfigPolicy  // 配置策略定义

    ModPolicy string                   // 配置修改策略的名称

}

其中,配置值ConfigValue定义的是一些配置数据,定义如下:

type ConfigValue struct {

    Version   uint64 // 配置版本

    Value     []byte // 配置数据,可以是JSON结构的

    ModPolicy string // 配置修改策略名称

}

比如在通道配置中区块生成间隔BatchTimeout设置的值是“2s”,局部的格式如下:

"BatchTimeout": {

    "mod_policy": "Admins",

    "value": {

        "timeout": "2s"

    }

}

我们再来看最重要的配置策略的定义:

type ConfigPolicy struct {

    Version   uint64  // 配置策略版本

    Policy    *Policy // 配置策略的内容,这在前面已经介绍过

    ModPolicy string  // 配置策略中修改策略的名称

}

从上面的定义中我们可以看到,配置策略是基于SignaturePolicy和ImplicitMetaPolicy的,ModPolicy代表的是修改同级策略用到的策略名称。通道定义了3种配置策略,如表3-1所示。

image

通道配置的递归定义

我们来看一个简化的通道配置是如何递归定义的。

Channel:

    Policies:

        Readers

        Writers

        Admins

    Groups:

        Orderer:

            Policies:

                Readers

                Writers

                Admins

            Groups:

                OrdereringOrganization1:

                    Policies:

                        Readers

                        Writers

                        Admins

        Application:

            Policies:

                Readers

----------->    Writers

                Admins

            Groups:

                ApplicationOrganization1:

                    Policies:

                        Readers

                        Writers

                        Admins

                ApplicationOrganization2:

                    Policies:

                        Readers

                        Writers

                        Admins

在上面的配置中,最外层是Channel,它定义了通道的子配置和策略定义。Channel的子配置里面定义了Orderer和Application配置,它们分别是相同的递归定义结构。其中”——->”显示的一行按照层级展开,代表的是/Channel/Application/Writers。

怎么来使用这些配置策略呢?比如在排序服务节点调用Deliver接口的时候会检查这个节点是否满足/Channel/Readers策略。Peer节点同步区块的时候也会检查是否满足/Channel/Application/Readers策略。

通道配置的默认策略

在使用configtxgen工具生成创世区块或者通道配置时,使用的默认策略如表3-2所示。

image

image

深度探索区块链

Hyperledger技术与应用

区块链

张增骏,董宁,朱轩彤,陈剑雄  著

本书由超级账本执行董事Brian Behlendorf领衔推荐,区块链一线落地实践团队、Hyperleger会员智链骨干团对撰写。深入讲解Hyperledger Fabric 1.0的架构、执行逻辑、核心功能实现、从零部署,并以票据案例为例,讲解具体开发实践,穿插开发所需的最佳实践和遇到的问题解决。

机械工业

出版社

image

华章科技是机械出版社的旗下品牌,出版了“计算机科学丛书”等近30个经典套系,在各个细分领域均处于领导地位,其中《Java编程思想》、《算法导论》、《编译原理》、《数据挖掘:概念与技术》、《深入理解计算机系统》、《深入理解Java虚拟机》等著作犹如计算机图书领域的璀璨明珠,长销不衰!

image

HiBlock秉承开放、协作、透明、链接、分享的价值观,致力打造区块链开发者社区。专注于在开发者中推广区块链,帮助开发者真正掌握区块链技术和应用。

本文内容节选自《深度探索区块链:Hyperledger技术与应用》一书的第3章《超级账本的系统架构》。

本书作者:张增骏,董宁,朱轩彤,陈剑雄

感谢机械工业出版社华章分社的支持和分享。

以下是我们的社区介绍,欢迎各种合作、交流、学习:)

image

【信息科学与工程学】【安全领域】第六十七篇 防火墙产品02 传统DDoS防御基于静态阈值,在复杂、自适应的攻击下(如脉冲攻击、低速攻击)效果不佳。将防火墙的防御动作(如触发清洗、调整限速阈值、更新黑白名单)建模为智能体的动作,通过与环境(网络流量)的交互学习最优防御策略。 阅读详情

相关推荐

【信息科学与工程学】【运营科学】第二篇 C4信息与通信网络运营 (C4) ——数据中心网络运营06

13 | 司法诉讼 | 原告律师 | 争取和解优势 | 证据披露的序贯博弈 | 策略性证据释放 | 持有证据集E = {强证据e_s, 中证据e_m, 弱证据e_w}。设公众原有认知人格向量为 Pold​​=(p1​,p2​,...,pk​), 其中p_i为负面特质(如“不敬业”)。危机后, 通过行为序列 {At​}和宣传, 将公众认知向新向量 Pnew​​引导, 使得在关键维度上, Pnew​​与 Pold​​的余弦相似度降低, 并与一个正面的、可接受的“原型”(如“浪子回头”、“慈父”)对齐。

weixin_49199313的博客 1486

3.4 消息协议结构

3.4.1 信封消息结构信封消息是认证内容中最基本的单元。它由一个消息负载(Payload)和一个签名(Signature)组成。// 信封包含一个带有签名的负载,以便认证该消息message Envelope { // 编组的负载 bytes payload = 1; // 负载头中指定创建者签名 bytes signature = 2;} // 负载是消息内容...

测试 721

【信息科学与工程学】【运营科学】第二篇 C4信息与通信网络运营 (C4) ——数据中心网络运营01

这是运营的物理和逻辑对象。C4.11xx 传输资源:光纤、微波、卫星链路;频谱资源(Sub-6GHz, 毫米波)。C4.12xx 节点资源:核心路由器、交换机、基站(gNB)、数据中心服务器。C4.13xx 虚拟化资源:由NFV生成的虚拟网络功能(VNF)、容器、虚拟机和网络切片实例。这是实现智能、灵活运营的核心技术集。C4.21xx 软件定义与虚拟化:软件定义网络 (SDN):控制平面与数据平面分离,实现集中、可编程的网络控制。网络功能虚拟化 (NFV):将传统专用硬件设备的功能以软件形式运行在通用硬件上

weixin_49199313的博客 1476

Hyperledger Fabric 入门笔记(二)Fabric V2.5 总结——交易流程中的消息结构

在入门笔记(二)中,介绍了Fabric的交易流程,其中涉及“交易提案”、“提案响应”、“交易信封”等概念,它们到底包含了什么内容?它们之间又有什么关系?深入探索其中的细节有助于将对Fabric的交易流程有一个全新的认知。

sbsy123456的博客 1830

【信息科学与工程学】【运营科学】第二篇 C4信息与通信网络运营 (C4) ——数据中心网络运营04

典型值:λ1​∈[−0.02,−0.01], λ2​∈[−0.01,0], η1​,η3​∈[0.1,0.3], η2​,η4​∈[0.05,0.15]参数:δ1​∈[−0.8,−0.3], δ2​∈[−0.5,−0.2], δ3​∈[−0.4,−0.1], δ4​∈[−0.6,−0.2]参数:φ1​∈[0.1,0.3], φ2​∈[−0.2,−0.05], φ3​∈[−0.1,0.1], φ4​∈[−0.3,−0.1]参数:α∈[0.3,0.6], β∈[0.2,0.4], γ∈[0.01,0.03]

weixin_49199313的博客 1217

从ATE到ATPG:基于Scan Chain的芯片制造缺陷定位实战解析

本文深入解析了从ATE到ATPG的芯片制造缺陷定位实战技术,重点介绍了Scan Chain的工作原理、异步复位触发器处理技巧以及Design Compiler中的DFT实现方法。通过实际案例展示了如何利用ATE测试数据和ATPG工具进行精确的缺陷定位,并分享了提升测试覆盖率和优化测试成本的专业技巧,为芯片测试工程师提供了宝贵的实战经验。

weixin_42527160的博客 382

Error: could not assemble transaction: ProposalResponsePayloads do not match - proposal response: ve

最近在跑fabric2.3自测链码的时候遇到了很多错误,自己也是很苦恼,改了好几个下午的bug就是找不到真正的问题所在,下面先看一个错误:Error: could not assemble transaction: ProposalResponsePayloads do not match - proposal response: version:1 response:......

lakersssss24的博客 1995

大学生电赛学习之路

可以看到全国大学生电子设计大赛的认可度是非常高的,属于A类学科竞赛。电子设计大赛的形式也是给出题目,参赛者有四天三夜的时间解决问题,题目大致可以分为:控制类、测量类、高频类以及电力电子类。该竞赛会在单数年的9月份举行。但是对于新生来说电赛确实遥不可及的,可能在很多学校本科生是不能进入实验室的,但是就算进了实验室你就有资格去参加电赛或者说能拿一个不错的奖项吗? 现在正值新生开学季,当然会有一大批学生会进入实验室的学习,电赛的举办时间是每年的暑假,所以说对于大一同学来说有一年的时间去准备,那我们就来说一说参加.

weixin_46098612的博客 8790

Hyperledger Fabric Transaction Proposal过程

客户端将交易预提案(Transaction Proposal)通过 gRPC 发送给支持 Endorser 角色的 Peer 进行背书。 这些交易提案可能包括链码的安装、实例化、升级、调用、查询;以及 Peer 节点加入和列出通道操作。 Peer 接收到请求后,会调用core/endorser/endorser.go中Endorser结构体 的ProcessProposal(ctx c...

weixin_34416649的博客 291

别再死磕RD算法了!用MATLAB手把手复现SAR后向投影(BP)成像(附完整代码与避坑点)

本文详细介绍了如何使用MATLAB实现合成孔径雷达(SAR)后向投影(BP)成像算法,突破传统RD算法在大斜视和复杂轨迹场景中的局限。通过完整的代码示例和避坑指南,帮助读者掌握BP算法的核心原理、内存优化策略和并行计算技巧,提升SAR成像精度与效率。

weixin_30908103的博客 298

OnePlus救砖指南:线刷包与OTA全量包实战解析

本文详细解析了OnePlus手机救砖的两种核心方法:线刷包与OTA全量包。针对手机变砖的不同状况(如黑屏、能进Recovery等),文章提供了清晰的判断标准和对应的实战操作指南。重点阐述了线刷包作为终极救砖手段的底层原理与详细步骤,并对比了OTA全量包作为温和修复方案的使用场景与卡刷流程,旨在帮助用户安全、有效地恢复手机系统。

weixin_28312391的博客 1328

41.Fabric 1.0源代码分析(41)putils(protos/utils工具包)

Fabric 1.0源代码笔记 之 putils(protos/utils工具包) 1、putils概述 putils,即protos/utils工具包,代码分布在:protos/utils目录下。 包括:txutils.go、proputils.go、commonutils.go、blockutils.go。 2、txutils //TransactionAction.Payload =&amp;gt;...

boss2967的博客 611

避坑指南:Qgis等时圈分析中ORS插件Key申请与参数设置的常见错误

本文详细解析了QGIS等时圈分析中ORS插件从API密钥申请到参数优化的全流程避坑指南。针对密钥激活、出行模式选择、时空参数设置等七个高频故障点,提供了实用的调试方案和优化技巧,帮助用户高效完成空间可达性分析。

weixin_42546508的博客 304

深度探索区块链/超级账本系统架构(3)

《深度探索区块链》 1。企业级区块链系统中常见的模块构成 1。Hyperledger Fabric 1.0是一种通用的区块链技术,其设计目标: 利用一些成熟的技术实现分布式账本技术(Distributed Ledger Technology,DLT) 2。超级账本采用模块化架构设计,复用通用的功能模块和接口。 3。模块化的方法带来了可扩展性,灵活性等优势,会减少模块修改,升级带来的影...

weixin_33885253的博客 1007

caverdock如何使用,一文给你多方案教学!

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 1392

39-Halcon-- fit_primitives_object_model_3d函数功能(从3D数据中提取几何基元)

Halcon算子fit_primitives_object_model_3d工业应用精要 该算子专为3D几何特征提取设计,支持平面、球体、圆柱等基元拟合。核心优势: 参数化输出:返回几何元素的数学参数(如平面方程、球心半径) 智能控制:通过max_dist、min_size等参数调节拟合精度 工业场景适配:针对薄壁件、孔系等提供专用优化方案 典型应用流程: 数据预处理(点云降噪/采样) 基元类型与参数设置 多阶段拟合(先平面后圆柱) 几何精度验证 误差控制在0.1%-1.2%范围内(视点云密度而定),适用于

weixin_45590420的博客 1162

序

序一作为Linux基金会托管下增长最快的项目,超级账本(Hyperledger)在过去的一年成长十分迅速。这主 要归功于Linux基金会开放、公平的治理模式,就是让各种规模的组织、开发者社区和技术专家可以达成最高水准的合作,以公开、公平和结构化的方式进行迭 代。我们珍视每一个贡献,也鼓励更多的组织和开发者加入其中。2017年7月,超级账本(Hyperledger)迎来了Fabric 1...

测试 259

YOLO11改进|卷积篇|引入SPDConv

YOLO11中添加SPDConv卷积

A1983Z的博客 3698

MCP 与区块链/分布式账本集成——不可否认的审计与智能合约 Skill

常见的做法不是将完整的审计日志写入区块链,而是将日志的哈希值写入区块链。任何对日志的修改都会改变哈希值,与区块链上的哈希值不匹配。这样,区块链作为存证层,提供了日志完整性的证明。使用零知识证明技术,在不泄露原始数据的情况下证明日志的完整性。区块链的存储成本高,不适合存储完整的审计日志。所有调用记录都写入审计日志,日志的哈希值定期上链到联盟链。审计日志存储在链下,哈希值存储在链上。验证时,审计人员从审计系统获取日志,计算哈希,与区块链上的记录比对。第二,审计日志上链的常见做法是上链哈希值而非完整日志。

powerjuly的博客 108

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

fabric-sdk-go解析交易数据详解

本文记录了使用fabric-sdk-go解析某个交易详情的全过程,从而得到比较全面的交易信息。

天草降临的博客 3502

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

超级账本源码解析之MSP

文章目录Cryptogen Cryptogen 为了更好的理解Fabric中MSP是如何工作的,我们先通过源码来看一下Fabric提供的Cryptogen这个命令行工具到底做了什么。 核心代码在common/tools/cryptogen这个目录下,目录树如下: cryptogen ├── ca │ ├── ca_test.go │ └── generator.go ├── csp │ ├── csp.go │ └── csp_test.go ├── main.go ├── metadata

yijiull 613

令人懊恼的阉割版fabric sdk功能缺失

按理说,fabric本身都是用golang开发的,那么fabric-sdk-go作为其亲儿子,功能应该是最为完善的。然而,与我们想法相左的是,golang版本的sdk反而是最不完备的,开发进度滞后,功能缺失。如果要选用最完备的sdk,推荐使用nodejs版本的,再次之java版本。然而,不巧的是,出于某些原因,我们项目偏偏采用了golang版本。 那么我们只能自己来客服一些困难了。比如我...

dhc8242的博客 823

区块链开源实现hyperledger fabric架构详解

hyperledger fabric是区块链中联盟链的优秀实现,主要代码由IBM、Intel、各大银行等贡献,目前v1.1版的kafka共识方式可达到1000/s次的吞吐量。本文中我们依次讨论:区块链的共通特性、fabric核心概念、fabric的交易执行流程。本文来源于笔者欲对公司部分业务上链而进行培训的PPT,故图多文字少,不要怕太长。 1、区块链解决方案的特性 1.1 分布式帐本 区块...

陶辉:聚焦分布式系统的程序员 10万+
上一篇: 深度探索Hyperledger技术与应用之超级账本的系统架构
下一篇: 深度探索Hyperledger技术与应用之超级账本的典型交易流程
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值