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意味着要有超过一半的子策略被满足,即Application和Orderer都必须满足。
value:这部分对应于ImplicitMetaPolicy,sub_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的,有groups、values、policies、versions和mod_policy五部分组成,这里就能看出,所谓的分层,就是groups套groups,每层都会定义policy。
关键是Application下一层Org1MSP和Org2MSP的内容,这里展示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,即SIGNATURE,value对应如下结构:
// 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_of和signed_by两种,当时n_out_of的时候,意味着,下面递归的子规则中满足n个就可以,继续递归直到signed_by,signed_by的意思是这个子规则要求identities中的第几个ID签名。
所以策略Admins的意思是必须要有一个Org1MSP的ADMIN角色的签名。
至此权限策略定义就明了了。从第一层channel_group的ImplicitMetaPolicy开始递归验证到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实际上指定了组织最基础的四个角色client、peer、admin和orderer,certificate设置了这些角色的证书的发行者,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;或者,通过更新通道的方式,即获取配置区块,修改配置,发送更新配置交易。