解读Fabric通道配置

444 阅读13分钟

1. 通道配置解析

在最初创建通道的时候,需要指定配置信息,这里面就有权限定义等内容。

配置交易会生成一个配置区块,配置区块是中除了配置交易不存在其他交易,第一个配置区块就是创世区块。更新配置流程是拉取配置、转换为人可读的格式、修改并提交审核。

这个是整个channel的配置结构,proto的定义如下:

message ConfigGroup {
    uint64 version = 1; ## 每次修改增长
    map<string,ConfigGroup> groups = 2; ## 包括Orderer信息和应用信息,比如channelMSP信息修改权限、
    map<string,ConfigValue> values = 3; ## 其中包括很多channel设置,比如hash算法等
    map<string,ConfigPolicy> policies = 4; ## 定义了很多权限策略,满足策略才可以修改对应配置
    string mod_policy = 5; ## 修改当前结构下内容的权限策略
}

在解读详细配置之前,首先要理解Fabric配置的修改策略,它是一种分层的策略配置,比如最上层的ConfigGroup有自己的mod_policy,这个策略对当前这一层适用,比如要修改values里面的hash算法,交易签名就必须满足mod_policy,而这个mod_policy被定义在policies中。

下面来解读一下具体配置文件:

{
  "channel_group": {
    "groups": {
      "Application": {},
      "Orderer": {}
    },
    "mod_policy": "Admins", 
    "policies": {
      "Admins": {
        "mod_policy": "Admins",
        "policy": {
          "type": 3,
          "value": {
            "rule": "MAJORITY",
            "sub_policy": "Admins"
          }
        },
        "version": "0"
      },
      "Readers": {
        "mod_policy": "Admins",
        "policy": {
          "type": 3,
          "value": {
            "rule": "ANY",
            "sub_policy": "Readers"
          }
        },
        "version": "0"
      },
      "Writers": {
        "mod_policy": "Admins",
        "policy": {
          "type": 3,
          "value": {
            "rule": "ANY",
            "sub_policy": "Writers"
          }
        },
        "version": "0"
      }
    },
    "values": {
      "BlockDataHashingStructure": {
        "mod_policy": "Admins",
        "value": {
          "width": 4294967295
        },
        "version": "0"
      },
      "Capabilities": {
        "mod_policy": "Admins",
        "value": {
          "capabilities": {
            "V1_4_3": {}
          }
        },
        "version": "0"
      },
      "Consortium": {
        "mod_policy": "Admins",
        "value": {
          "name": "SampleConsortium"
        },
        "version": "0"
      },
      "HashingAlgorithm": {
        "mod_policy": "Admins",
        "value": {
          "name": "SHA256"
        },
        "version": "0"
      },
      "OrdererAddresses": {
        "mod_policy": "/Channel/Orderer/Admins",
        "value": {
          "addresses": [
            "orderer.example.com:7050"
          ]
        },
        "version": "0"
      }
    },
    "version": "0"
  },
  "sequence": "3" ## 每次提交配置加1
}

首先,来看policies。策略Admins如下:

      "Admins": {
        "mod_policy": "Admins",
        "policy": {
          "type": 3,
          "value": {
            "rule": "MAJORITY",
            "sub_policy": "Admins"
          }
        },
        "version": "0"
      },

其中policy结构对应整个策略的内容:

  • type:总共有四种类型,如下:
    enum PolicyType {
        UNKNOWN = 0; // Reserved to check for proper initialization
        SIGNATURE = 1;
        MSP = 2;
        IMPLICIT_META = 3;
    }

在实例中是3,代表ImplicitMetaPolicy,Fabric对其解释如下:

// ImplicitMetaPolicy is a policy type which depends on the hierarchical nature of the configuration
// It is implicit because the rule is generate implicitly based on the number of sub policies
// It is meta because it depends only on the result of other policies
// When evaluated, this policy iterates over all immediate child sub-groups, retrieves the policy
// of name sub_policy, evaluates the collection and applies the rule.
// For example, with 4 sub-groups, and a policy name of "foo", ImplicitMetaPolicy retrieves
// each sub-group, retrieves policy "foo" for each subgroup, evaluates it, and, in the case of ANY
// 1 satisfied is sufficient, ALL would require 4 signatures, and MAJORITY would require 3 signatures.
message ImplicitMetaPolicy {
    enum Rule {
        ANY = 0;      // Requires any of the sub-policies be satisfied, if no sub-policies exist, always returns true
        ALL = 1;      // Requires all of the sub-policies be satisfied
        MAJORITY = 2; // Requires a strict majority (greater than half) of the sub-policies be satisfied
    }
    string sub_policy = 1;
    Rule rule = 2;
}

它这个策略的意思是将会在找下一层的策略中找名叫sub_policy的策略来执行,MAJORITY意味着要有超过一半的子策略被满足,即ApplicationOrderer都必须满足。

  • value:这部分对应于ImplicitMetaPolicysub_policy就是指下一层要满足的策略名字,rule则是三选一。

下面来看下第一个子组Application的内容:

{
    "Application": {
        "groups": {
            "Org1MSP": {...},
            "Org2MSP": {...}
        },
        "mod_policy": "Admins",
        "policies": {
            "Admins": {
                "mod_policy": "Admins",
                "policy": {
                    "type": 3,
                    "value": {
                        "rule": "MAJORITY",
                        "sub_policy": "Admins"
                    }
                },
                "version": "0"
            },
            "Readers": {
                "mod_policy": "Admins",
                "policy": {
                    "type": 3,
                    "value": {
                        "rule": "ANY",
                        "sub_policy": "Readers"
                    }
                },
                "version": "0"
            },
            "Writers": {
                "mod_policy": "Admins",
                "policy": {
                    "type": 3,
                    "value": {
                        "rule": "ANY",
                        "sub_policy": "Writers"
                    }
                },
                "version": "0"
            }
        },
        "values": {
            "Capabilities": {
                "mod_policy": "Admins",
                "value": {
                    "capabilities": {
                        "V1_4_2": {}
                    }
                },
                "version": "0"
            }
        },
        "version": "1"
    }
}

可以看到Application这一层也是类似于channel_group的,有groupsvaluespoliciesversionsmod_policy五部分组成,这里就能看出,所谓的分层,就是groups套groups,每层都会定义policy。

关键是Application下一层Org1MSPOrg2MSP的内容,这里展示Org1MSP

{
    "groups": {},
    "mod_policy": "Admins",
    "policies": {
        "Admins": {
            "mod_policy": "Admins",
            "policy": {
                "type": 1,
                "value": {
                    "identities": [{
                        "principal": {
                            "msp_identifier": "Org1MSP",
                            "role": "ADMIN"
                        },
                        "principal_classification": "ROLE"
                    }],
                    "rule": {
                        "n_out_of": {
                            "n": 1,
                            "rules": [{
                                "signed_by": 0
                            }]
                        }
                    },
                    "version": 0
                }
            },
            "version": "0"
        },
        "Readers": {
            "mod_policy": "Admins",
            "policy": {
                "type": 1,
                "value": {
                    "identities": [{
                            "principal": {
                                "msp_identifier": "Org1MSP",
                                "role": "ADMIN"
                            },
                            "principal_classification": "ROLE"
                        },
                        {
                            "principal": {
                                "msp_identifier": "Org1MSP",
                                "role": "PEER"
                            },
                            "principal_classification": "ROLE"
                        },
                        {
                            "principal": {
                                "msp_identifier": "Org1MSP",
                                "role": "CLIENT"
                            },
                            "principal_classification": "ROLE"
                        }
                    ],
                    "rule": {
                        "n_out_of": {
                            "n": 1,
                            "rules": [{
                                    "signed_by": 0
                                },
                                {
                                    "signed_by": 1
                                },
                                {
                                    "signed_by": 2
                                }
                            ]
                        }
                    },
                    "version": 0
                }
            },
            "version": "0"
        },
        "Writers": {
            "mod_policy": "Admins",
            "policy": {
                "type": 1,
                "value": {
                    "identities": [{
                            "principal": {
                                "msp_identifier": "Org1MSP",
                                "role": "ADMIN"
                            },
                            "principal_classification": "ROLE"
                        },
                        {
                            "principal": {
                                "msp_identifier": "Org1MSP",
                                "role": "CLIENT"
                            },
                            "principal_classification": "ROLE"
                        }
                    ],
                    "rule": {
                        "n_out_of": {
                            "n": 1,
                            "rules": [{
                                    "signed_by": 0
                                },
                                {
                                    "signed_by": 1
                                }
                            ]
                        }
                    },
                    "version": 0
                }
            },
            "version": "0"
        }
    },
    "values": {
        "AnchorPeers": {
            "mod_policy": "Admins",
            "value": {
                "anchor_peers": [{
                    "host": "peer0.org1.example.com",
                    "port": 7051
                }]
            },
            "version": "0"
        },
        "MSP": {
            "mod_policy": "Admins",
            "value": {
                "config": {
                    "admins": [],
                    "crypto_config": {
                        "identity_identifier_hash_function": "SHA256",
                        "signature_hash_family": "SHA2"
                    },
                    "fabric_node_ous": {
                        "admin_ou_identifier": {
                            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
                            "organizational_unit_identifier": "admin"
                        },
                        "client_ou_identifier": {
                            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
                            "organizational_unit_identifier": "client"
                        },
                        "enable": true,
                        "orderer_ou_identifier": {
                            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
                            "organizational_unit_identifier": "orderer"
                        },
                        "peer_ou_identifier": {
                            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
                            "organizational_unit_identifier": "peer"
                        }
                    },
                    "intermediate_certs": [],
                    "name": "Org1MSP",
                    "organizational_unit_identifiers": [],
                    "revocation_list": [],
                    "root_certs": [
                        "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
                    ],
                    "signing_identity": null,
                    "tls_intermediate_certs": [],
                    "tls_root_certs": [
                        "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNXRENDQWY2Z0F3SUJBZ0lSQUtqL29zM1c5R2FaRzJCT1d0T0NxbUl3Q2dZSUtvWkl6ajBFQXdJd2RqRUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIekFkQmdOVkJBTVRGblJzCmMyTmhMbTl5WnpFdVpYaGhiWEJzWlM1amIyMHdIaGNOTWpBeE1UQTFNRGN3TXpBd1doY05NekF4TVRBek1EY3cKTXpBd1dqQjJNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRQpCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWZNQjBHCkExVUVBeE1XZEd4elkyRXViM0puTVM1bGVHRnRjR3hsTG1OdmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDkKQXdFSEEwSUFCTnlNTjVPaGFVb3NVUWtTVDBodllaOFNSeFJNTnJVZE1mdkkzLy9VcHUyTkJJWG4xNWxSWk9yOQp1akZzNUNFQXlBeGVTVE9neFNxOWloRDJXVXRLejF5amJUQnJNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WCkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVIQXdFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlYKSFE0RUlnUWdWdWdaaDV5S3AvWnc4RGFXc2FleWhrZE1OT3A0aFFVbk1UVTJ1UnRNaHlRd0NnWUlLb1pJemowRQpBd0lEU0FBd1JRSWhBTXAvMDRncE5jZEZGSHhzMDhXVmNZbXZuU3kwYUVrdWFlWnc1Y2pLekRwNUFpQXRHcnpJCmR3ZmN2bmNtc0p2NnVCNEhabUtFU3A1ZUVLQ2tsbkNNTGZIeTBnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
                    ]
                },
                "type": 0
            },
            "version": "0"
        }
    },
    "version": "1"
}

先从权限策略开始。

这里的policies就是很具体的了,以下是Admins的内容:

{
    "mod_policy": "Admins",
    "policy": {
        "type": 1,
        "value": {
            "identities": [{
                "principal": {
                    "msp_identifier": "Org1MSP",
                    "role": "ADMIN"
                },
                "principal_classification": "ROLE"
            }],
            "rule": {
                "n_out_of": {
                    "n": 1,
                    "rules": [{
                        "signed_by": 0
                    }]
                }
            },
            "version": 0
        }
    },
    "version": "0"
}

结构很清晰了,首先policy是一个通用的策略结构,type是1,即SIGNATUREvalue对应如下结构:

// SignaturePolicyEnvelope wraps a SignaturePolicy and includes a version for future enhancements
message SignaturePolicyEnvelope {
    int32 version = 1;
    SignaturePolicy rule = 2;
    repeated MSPPrincipal identities = 3;
}

// SignaturePolicy is a recursive message structure which defines a featherweight DSL for describing
// policies which are more complicated than 'exactly this signature'.  The NOutOf operator is sufficent
// to express AND as well as OR, as well as of course N out of the following M policies
// SignedBy implies that the signature is from a valid certificate which is signed by the trusted
// authority specified in the bytes.  This will be the certificate itself for a self-signed certificate
// and will be the CA for more traditional certificates
message SignaturePolicy {
    message NOutOf {
        int32 n = 1;
        repeated SignaturePolicy rules = 2;
    }
    oneof Type {
        int32 signed_by = 1;
        NOutOf n_out_of = 2;
    }
}

SignaturePolicyEnvelope中,identities是指签名的实体列表,rule是指验证签名的规则集合,这个集合就是SignaturePolicy,它是以递归的形式构造的,可以看到它分为n_out_ofsigned_by两种,当时n_out_of的时候,意味着,下面递归的子规则中满足n个就可以,继续递归直到signed_bysigned_by的意思是这个子规则要求identities中的第几个ID签名。

所以策略Admins的意思是必须要有一个Org1MSPADMIN角色的签名。

至此权限策略定义就明了了。从第一层channel_groupImplicitMetaPolicy开始递归验证到Org1MSP这一层的SignaturePolicyEnvelope,最终完成验证。

下面介绍一下values这一部分。

{
    "AnchorPeers": {
        "mod_policy": "Admins",
        "value": {
            "anchor_peers": [{
                "host": "peer0.org1.example.com",
                "port": 7051
            }]
        },
        "version": "0"
    },
    "MSP": {...},
    "version": "0"
    }
}

第一部分AnchorPeers是组织1的锚节点列表,锚节点可以和其他组织的锚节点通过P2P通信,基于gossip协议去同步交易等。

第二部分MSP,还是直接看protobuf的结构体:

// MSPConfig collects all the configuration information for
// an MSP. The Config field should be unmarshalled in a way
// that depends on the Type
message MSPConfig {
    // Type holds the type of the MSP; the default one would
    // be of type FABRIC implementing an X.509 based provider
    int32 type = 1;

    // Config is MSP dependent configuration info
    bytes config = 2;
}

MSP就是前面提到的channelMSP。

config内容如下:

{
    "admins": [],
    "crypto_config": {
        "identity_identifier_hash_function": "SHA256",
        "signature_hash_family": "SHA2"
    },
    "fabric_node_ous": {
        "admin_ou_identifier": {
            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
            "organizational_unit_identifier": "admin"
        },
        "client_ou_identifier": {
            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
            "organizational_unit_identifier": "client"
        },
        "enable": true,
        "orderer_ou_identifier": {
            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
            "organizational_unit_identifier": "orderer"
        },
        "peer_ou_identifier": {
            "certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=",
            "organizational_unit_identifier": "peer"
        }
    },
    "intermediate_certs": [],
    "name": "Org1MSP",
    "organizational_unit_identifiers": [],
    "revocation_list": [],
    "root_certs": [
        "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVVENDQWZpZ0F3SUJBZ0lSQU5TMEM5Nkdpb1U1ZWNiMUpUVi9PYmt3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF4TVRBMU1EY3dNekF3V2hjTk16QXhNVEF6TURjd016QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQktvUy85YUxFMW1NdExPclNsdCtESDlTVTNKM2VmUnczTkZsU1JMMXh2dUZ1WkcvanQvZEdXRnZwa3lXZEdOZwpGYS9xcDBTcm1zSjhnSXZuVWhRMTlmU2piVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKblFvR0JLRk9uYzNUcW84emE4am1qdHFkdXBhdW5NU0ZTSm9TUUgrM0MzRXdDZ1lJS29aSXpqMEVBd0lEUndBdwpSQUlnY2dOOUdUdk85NDZNN2dwbmhJY1RYdXplcDAxdTYxQlZlOXhleEw3K1lEY0NJRWpPR2ZxZnpURkRQMWFaClBvdThUbVoyZmtjYnVZWVNhcHdLRFE3blZtYmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
    ],
    "signing_identity": null,
    "tls_intermediate_certs": [],
    "tls_root_certs": [
        "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNXRENDQWY2Z0F3SUJBZ0lSQUtqL29zM1c5R2FaRzJCT1d0T0NxbUl3Q2dZSUtvWkl6ajBFQXdJd2RqRUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIekFkQmdOVkJBTVRGblJzCmMyTmhMbTl5WnpFdVpYaGhiWEJzWlM1amIyMHdIaGNOTWpBeE1UQTFNRGN3TXpBd1doY05NekF4TVRBek1EY3cKTXpBd1dqQjJNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRQpCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWZNQjBHCkExVUVBeE1XZEd4elkyRXViM0puTVM1bGVHRnRjR3hsTG1OdmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDkKQXdFSEEwSUFCTnlNTjVPaGFVb3NVUWtTVDBodllaOFNSeFJNTnJVZE1mdkkzLy9VcHUyTkJJWG4xNWxSWk9yOQp1akZzNUNFQXlBeGVTVE9neFNxOWloRDJXVXRLejF5amJUQnJNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WCkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVIQXdFd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBcEJnTlYKSFE0RUlnUWdWdWdaaDV5S3AvWnc4RGFXc2FleWhrZE1OT3A0aFFVbk1UVTJ1UnRNaHlRd0NnWUlLb1pJemowRQpBd0lEU0FBd1JRSWhBTXAvMDRncE5jZEZGSHhzMDhXVmNZbXZuU3kwYUVrdWFlWnc1Y2pLekRwNUFpQXRHcnpJCmR3ZmN2bmNtc0p2NnVCNEhabUtFU3A1ZUVLQ2tsbkNNTGZIeTBnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
    ]
}

proto结构体如下:

// FabricMSPConfig collects all the configuration information for
// a Fabric MSP.
// Here we assume a default certificate validation policy, where
// any certificate signed by any of the listed rootCA certs would
// be considered as valid under this MSP.
// This MSP may or may not come with a signing identity. If it does,
// it can also issue signing identities. If it does not, it can only
// be used to validate and verify certificates.
message FabricMSPConfig {
    // Name holds the identifier of the MSP; MSP identifier
    // is chosen by the application that governs this MSP.
    // For example, and assuming the default implementation of MSP,
    // that is X.509-based and considers a single Issuer,
    // this can refer to the Subject OU field or the Issuer OU field.
    string name = 1;

    // List of root certificates trusted by this MSP
    // they are used upon certificate validation (see
    // comment for IntermediateCerts below)
    repeated bytes root_certs = 2;

    // List of intermediate certificates trusted by this MSP;
    // they are used upon certificate validation as follows:
    // validation attempts to build a path from the certificate
    // to be validated (which is at one end of the path) and
    // one of the certs in the RootCerts field (which is at
    // the other end of the path). If the path is longer than
    // 2, certificates in the middle are searched within the
    // IntermediateCerts pool
    repeated bytes intermediate_certs = 3;

    // Identity denoting the administrator of this MSP
    repeated bytes admins = 4;

    // Identity revocation list
    repeated bytes revocation_list = 5;

    // SigningIdentity holds information on the signing identity
    // this peer is to use, and which is to be imported by the
    // MSP defined before
    SigningIdentityInfo signing_identity = 6;

    // OrganizationalUnitIdentifiers holds one or more
    // fabric organizational unit identifiers that belong to
    // this MSP configuration
    repeated FabricOUIdentifier organizational_unit_identifiers = 7;

    // FabricCryptoConfig contains the configuration parameters
    // for the cryptographic algorithms used by this MSP
    FabricCryptoConfig crypto_config = 8;

    // List of TLS root certificates trusted by this MSP.
    // They are returned by GetTLSRootCerts.
    repeated bytes tls_root_certs = 9;

    // List of TLS intermediate certificates trusted by this MSP;
    // They are returned by GetTLSIntermediateCerts.
    repeated bytes tls_intermediate_certs = 10;

    // fabric_node_ous contains the configuration to distinguish clients from peers from orderers
    // based on the OUs.
    FabricNodeOUs fabric_node_ous = 11;
}

LocalMSP和channelMSP用的同一个结构体。注释中清楚解释了每个字段的含义,这里主要说一下fabric_node_ous。可以看到fabric_node_ous实际上指定了组织最基础的四个角色clientpeeradminorderercertificate设置了这些角色的证书的发行者,organizational_unit_identifier则指定了他们的名字,这个与他们CA的OU中必须要一致。

// FabricNodeOUs contains configuration to tell apart clients from peers from orderers
// based on OUs. If NodeOUs recognition is enabled then an msp identity
// that does not contain any of the specified OU will be considered invalid.
message FabricNodeOUs {
    // If true then an msp identity that does not contain any of the specified OU will be considered invalid.
    bool   enable = 1;

    // OU Identifier of the clients
    FabricOUIdentifier client_ou_identifier = 2;

    // OU Identifier of the peers
    FabricOUIdentifier peer_ou_identifier = 3;

    // OU Identifier of the admins
    FabricOUIdentifier admin_ou_identifier = 4;

    // OU Identifier of the orderers
    FabricOUIdentifier orderer_ou_identifier = 5;
}

// FabricOUIdentifier represents an organizational unit and
// its related chain of trust identifier.
message FabricOUIdentifier {

    // Certificate represents the second certificate in a certification chain.
    // (Notice that the first certificate in a certification chain is supposed
    // to be the certificate of an identity).
    // It must correspond to the certificate of root or intermediate CA
    // recognized by the MSP this message belongs to.
    // Starting from this certificate, a certification chain is computed
    // and bound to the OrganizationUnitIdentifier specified
    bytes certificate = 1;

    // OrganizationUnitIdentifier defines the organizational unit under the
    // MSP identified with MSPIdentifier
    string organizational_unit_identifier = 2;
}

类似地,Orderer组中记录了各种策略和配置,比如排序通道的共识类型,这里是solo。

2. 访问控制列表(ACL)

ACL这部分可以更细粒度控制权限,包括调用链码的某个方法也可以加权限,设置和上面很类似。

添加自己的策略可以通过:初始化通道之前,修改configtx.yaml;或者,通过更新通道的方式,即获取配置区块,修改配置,发送更新配置交易。