Hyperledger Fabric channel配置交易
一个超级账本区块链网络里每个channel的共享配置都是存储在一个配置交易里。每个配置交易通常被简称为configtx。
Channel 配置有以下重要属性:
1、有版本标识:配置里的所有元素都有一个关联版本。每次更新配置,版本号都维持最新。另外,每个提交的配置会获得一个序列号。
2、有权限:配置里的每个元素都有一个关联策略,用来管理是否允许对这个元素进行修改。每一个保存有当前配置副本的实例,都会按照关联策略的内容对新收到的配置改动进行验证权限。
3、层次性:一个配置根组包含多个子组,并且层次中的每个组都有关联的值和策略。较低层次可以获取上层的策略。
配置分析
配置作为一个HeaderType_CONFIG
类型的交易
存储在一个不包含其他交易的区块中。这些区块被称为Configuration
Blocks,所有区块中的第一个区块称为genesis
block。
配置的样例存储在fabric/protos/common/configtx.proto
。
HeaderType_CONFIG
类型的
Env
elope
编码
ConfigEnvelop
信息作为
Payload
data的值。
ConfigEnvelop
定义如下:
message
ConfigEnvelope {
Config
config = 1;
Envelope
last_update = 2;
}
last_update
字段在下面的更新配置中有定义,该字段仅用于验证配置。当前提交的配置存在
config
字段,包含一个
Config
消息。
message
Config {
uint64
sequence = 1;
ConfigGroup
channel_group = 2;
}
seq
uence
的值在每次提交配置后加
1,channel_group
字段是包含该配置的根组。
ConfigGroup
是一个递归定义的结构,生成一个
gruops
树,每个组都包含值和策略。
ConfigGroup
的定义如下:
message
ConfigGroup {
uint64
version = 1;
map<string,ConfigGroup>
groups = 2;
map<string,ConfigValue>
values = 3;
map<string,ConfigPolicy>
policies = 4;
string
mod_policy = 5;
}
因为
ConfigGroup
是一个递归结构,有层次概念。接下来我们用
go
语言例子来表示。
//
Assume the following groups are defined
var
root, child1, child2, grandChild1, grandChild2, grandChild3
*ConfigGroup
//
Set the following values
root.Groups["child1"]
= child1
root.Groups["child2"]
= child2
child1.Groups["grandChild1"]
= grandChild1
child2.Groups["grandChild2"]
= grandChild2
child2.Groups["grandChild3"]
= grandChild3
//
The resulting config structure of groups looks like:
//
root:
//
child1:
//
grandChild1
//
child2:
//
grandChild2
//
grandChild3
在config层次结构中,每个组定义了一个层次,每个组有一系列关联的值和策略。值的定义如下:
message
ConfigValue {
uint64
version = 1;
bytes
value = 2;
string
mod_policy = 3;
}
策略的定义如下:
message
ConfigPolicy {
uint64
version = 1;
Policy
policy = 2;
string
mod_policy = 3;
}
注意值、策略和组都有一个version和mod_policy字段。一个元素的version在每次更改后递增。mod_policy用来管理修改元素的签名。对于组,更改就是添加或者移除Values、Policies、或者组地图(或者修改mod_policy)。对于Values和Policies,修改就是改变修改Value或者Policy字段(或者修改mod_policy)。每个元素的mod_policy在当前当前元素中有效
下面是一个定义在Channel.Groups["Application"]
中的策略的示例(这里用的是golang语法,因此Channel.Groups["Application"].Policies["policy1"]
表示根组Channel
的子组Application
的Policies
里的policy1
对应的策略)
policy1
对应Channel.Groups["Application"].Policies["policy1"]
Org1/policy2
对应Channel.Groups["Application"].Groups["Org1"].Policies["policy2"]
/Channel/policy3
对应Channel.Policies["policy3"]
注意,如果mod_policy
引用了一个不存在的策略,那么该元素不可修改。
Configuration updates / 更新配置
更新配置是提交一个HeaderType_CONFIG_UPDATE
类型的Envelope
消息,交易的Payload.data
字段是序列化的ConfigUpdateEnvelope
,其定义如下:
message
ConfigUpdateEnvelope {
bytes
config_update = 1; // A marshaled ConfigUpdate
structure
repeated
ConfigSignature signatures = 2; // Signatures over the config_update
}
其中signatures
字段包含了授权更新配置的签名集,定义如下:
message
ConfigSignature {
bytes
signature_header = 1; // A marshaled SignatureHeader
bytes
signature = 2; // Signature over the concatenation
signatureHeader bytes and config bytes
}
signature_header
如标准交易所定义,而签名则是signature_header
字节和ConfigUpdateEnvelope
中的config_update
字节的拼接。
ConfigUpdateEnvelope
中的config_update
字段是序列化的ConfigUpdate
,其定义为:
message
ConfigUpdate {
string
channel_id = 1; // Which channel this config update is for
ConfigGroup
read_set = 2; // ReadSet explicitly lists the portion of the config
which was read, this should be sparse with only Version set
ConfigGroup
write_set = 3; // WriteSet lists the portion of the config which was
written, this should included updated Versions
}
其中channel_id
是配置更新所对应的channel ID,该字段是必要,因为它界定了支持本次配置更新的所需的签名范围。
read_set
是现有配置的一个子集,其中仅含version
字段,ConfigValue.value
和ConfigPolicy.policy
等其他字段不包含在read_set
中。ConfigGroup
会map字段组成的子集,以便引用配置树的深层元素。例如,为使Application
group包含到read_set
,它的上层(Channel
group)也必须包含到read_set
中,但不必将Channel
group中所有的key都包括进去,比如Orderer``group
或者任何values
或policies
。
write_set
指定了要被修改的那部分配置。由于配置的分层特性,修改深层元素就必须在write_set
中包含其上层元素。write_set
中的任意元素都会在read_set
中指定相同版本的该元素。
例如,给出如下配置:
Channel:
(version 0)
Orderer
(version 0)
Appplication
(version 3)
Org1
(version 2)
修改Org1
提交的read_set
应为:
Channel:
(version 0)
Application:
(version 3)
对应的write_set
应是:
Channel:
(version 0)
Application:
(version 3)
Org1
(version 3)
When the CONFIG_UPDATE
is received, the orderer computes the resulting CONFIG
by doing the following:
接收到CONFIG_UPDATE
后,orderer会通过以下步骤计算CONFIG
结果:
校验
channel_id
和read_set
,read_set
中所有元素必须存在对应的版本。收集
read_set
与write_set
中版本不一致的元素,计算更新集。校验更新集中的元素的版本号是否递增1
校验更新集中每个元素,
ConfigUpdateEnvelope
的签名满足mod_policy
。通过将更新集应用于当前配置,计算该配置的完整新版本
将新配置写成
ConfigEnvelope
作为CONFIG_UPDATE
赋给last_update
字段,新的配置赋给config
字段,sequence
字段自增。将
ConfigEnvelope
写成CONFIG
类型的Envelope
,最终将此作为唯一交易写入配置区块。
当peer(或者任意其他接收Deliver
者)接收到这个配置区块后,就会通过将last_update
信息应用到当前配置并校验orderer计算的config
字段是否包含正确的新配置,来验证该配置是否被正确校验。
Permitted configuration groups and values / 组和值得配置许可
有效的配置都是下面配置的子集。在此,用peer.<MSG>
表示一个ConfigValue
,其value
字段是称为<MSG>
的序列化后的信息,定义在fabric/protos/peer/configuration.proto
。common.<MSG>
,msp.<MSG>
和orderer.<MSG>
分别定义在fabric/protos/common/configuration.proto
,fabric/protos/msp/mspconfig.proto
和fabric/protos/orderer/configuration.proto
。
Note, that the keys {{org_name}}
and {{consortium_name}}
represent arbitrary names, and indicate an element which may be repeated with different names.
注意,下面的{{org_name}}
和 {{consortium_name}}
是任意的名字,表示可以重复使用不同名称的元素。
&ConfigGroup{
Groups:
map<string, *ConfigGroup> {
"Application":&ConfigGroup{
Groups:map<String,
*ConfigGroup> {
{{org_name}}:&ConfigGroup{
Values:map<string,
*ConfigValue>{
"MSP":msp.MSPConfig,
"AnchorPeers":peer.AnchorPeers,
},
},
},
},
"Orderer":&ConfigGroup{
Groups:map<String,
*ConfigGroup> {
{{org_name}}:&ConfigGroup{
Values:map<string,
*ConfigValue>{
"MSP":msp.MSPConfig,
},
},
},
Values:map<string,
*ConfigValue> {
"ConsensusType":orderer.ConsensusType,
"BatchSize":orderer.BatchSize,
"BatchTimeout":orderer.BatchTimeout,
"KafkaBrokers":orderer.KafkaBrokers,
},
},
"Consortiums":&ConfigGroup{
Groups:map<String,
*ConfigGroup> {
{{consortium_name}}:&ConfigGroup{
Groups:map<string,
*ConfigGroup> {
{{org_name}}:&ConfigGroup{
Values:map<string,
*ConfigValue>{
"MSP":msp.MSPConfig,
},
},
},
Values:map<string,
*ConfigValue> {
"ChannelCreationPolicy":common.Policy,
}
},
},
},
},
Values:
map<string, *ConfigValue> {
"HashingAlgorithm":common.HashingAlgorithm,
"BlockHashingDataStructure":common.BlockDataHashingStructure,
"Consortium":common.Consortium,
"OrdererAddresses":common.OrdererAddresses,
},
}
Orderer system channel configuration / Order channel 配置
ordering系统channel定义了创建channel的ordering参数和consortiums。ordering service必须有一个ordering系统channel,这是被创建的第一个channel。建议不要在ordering系统channel初始配置中定义application部分,但是测试是可以这么做。注意,任何对ordering系统channel有读权限的成员都可以查看所有channel创建,因此channel的访问应受限制。
The ordering parameters are defined as the following subset of config:
ordering参数定义如下:
&ConfigGroup{
Groups:
map<string, *ConfigGroup> {
"Orderer":&ConfigGroup{
Groups:map<String,
*ConfigGroup> {
{{org_name}}:&ConfigGroup{
Values:map<string,
*ConfigValue>{
"MSP":msp.MSPConfig,
},
},
},
Values:map<string,
*ConfigValue> {
"ConsensusType":orderer.ConsensusType,
"BatchSize":orderer.BatchSize,
"BatchTimeout":orderer.BatchTimeout,
"KafkaBrokers":orderer.KafkaBrokers,
},
},
},
ordering中的每个组织都在Orderer
组下有一个组元素,这个组定义了一个MSP
参数,这个参数包含该组织的加密身份信息。Orderer
组中的Values
决定了ordering节点的功能。他们存在于每个channel中,所以像orderer.BatchTimeout
就可在不同channel中指定不同值。
启动时,orderer面对含有很多channel信息的文件系统,orderer通过识别带有consortiums组定义的channel来标识系统channel。consortiums组结构如下。
&ConfigGroup{
Groups:
map<string, *ConfigGroup> {
"Consortiums":&ConfigGroup{
Groups:map<String,
*ConfigGroup> {
{{consortium_name}}:&ConfigGroup{
Groups:map<string,
*ConfigGroup> {
{{org_name}}:&ConfigGroup{
Values:map<string,
*ConfigValue>{
"MSP":msp.MSPConfig,
},
},
},
Values:map<string,
*ConfigValue> {
"ChannelCreationPolicy":common.Policy,
}
},
},
},
},
},
注意,每个consortium定义一组成员,就行ordering组织的组织成员一样。每个consortium也都定义了一个ChannelCreationPolicy
,它是一种应用于授权channel创建请求的策略,通常这个值设为ImplicitMetaPolicy
,要求channel的新成员签名授权channel创建。有关channel创建更信息的内容,请参阅文档后面的内容。
Application channel configuration / APP channel 配置
应用程序配置用于为应用类型交易设计的channel。其定义如下:
&ConfigGroup{
Groups:
map<string, *ConfigGroup> {
"Application":&ConfigGroup{
Groups:map<String,
*ConfigGroup> {
{{org_name}}:&ConfigGroup{
Values:map<string,
*ConfigValue>{
"MSP":msp.MSPConfig,
"AnchorPeers":peer.AnchorPeers,
},
},
},
},
},
}
就像Orderer
部分,每个组织被编码为一个组。然而,app channel不仅有MSP
身份信息,每个组织都附加了一个AnchorPeers
列表。这个列表允许不同组织的节点彼此联系。
应用程序channel通过对orderer组织和共识选项的编码,以允许对这些参数进行确定性更新,因此包含了orderer系统channel配置的相同Orderer
部分。但从应用角度看,这会在很大程度上被忽略。
Channel creation / 创建channel
当Orderer 接收到对一个不存在的channel的CONFIG_UPDATE
信息时,orderer就会假设这是个创建channel的请求并执行以下操作:
通过查看高层组中的
Consortium
值,orderer标识所要执行创建channel请求的consortium(译注:这个词暂时不知翻译成什么好)。orderer验证Application组中的组织是对应的consortium中组织的一部分,并验证
ApplicationGroup
的版本是1。orderer验证consortium是否有成员,新的channel也会有application成员(创建没有成员的consortiums和channel只用于测试)。
orderer从ordering系统channel取得
Orderer
组,并创建一个包含新指定成员的Application
组,并将其mod_policy
指定为在consortium config中指定的ChannelCreationPolicy
,从而创建一个模板配置。注意,这个策略(mod_policy)是基于新配置的上下文的,因此需要所有成员的策略就是要需要新channel中所有成员的签名,而不是consortium中的所有成员。orderer用
CONFIG_UPDATE
更新这个模板配置。因为CONFIG_UPDATE
用于Application
组(其版本是1)的修改,所以配置码根据ChannelCreationPolicy
验证这些更新。如果channel创建包含任何其它修改,例如修改单个组织的锚节点,则调用该元素的相应mod策略。带有新channel配置的
CONFIG
交易被包装并通过order系统channel发送到ordering,ordering之后channel就创建完成。
Hyperledger Fabric channel配置交易的更多相关文章
- Hyperledger Fabric动态配置Raft节点
Hyperledger Fabric动态配置Raft节点 最近看官方文档发现新的共识算法etcdRaft允许动态添加或删除排序节点,所以也花了一天时间操作了以下,写篇文章把整个过程记录一下. 初始网络 ...
- Hyperledger Fabric 环境配置
简单说一下 Hyperledger Fabric的配置 1.第一步,安装curl brew install curl 注:没有brew的自行百度(mac) 2. 安装Docker 下载并安装Docke ...
- HyperLedger Fabric 1.4 交易流程(6.3)
区块链最主要的特性之一是去中心化,没有了中心机构的集中处理,为了达成数据的一致性,就需要网络中全民参与管理,并以某种方法达成共识,所以区块链的交易流程也就是共识的过程. 在Fabric中, ...
- Ubuntu下配置Hyperledger Fabric环境
在win10系统的台式机上安装配置Hyperledger Fabric环境 安装Ubuntu 16.04 双系统 镜像下载地址:https://www.ubuntu.com/download/desk ...
- Hyperledger Fabric——balance transfer(三)创建和加入Channel
详细解析blance transfer示例的创建通道(Channel)和加入节点到通道的过程. 创建Channel 1.首先看app.js的路由函数 var createChannel = requi ...
- Hyperledger Fabric 建立一个简单网络
Building you first network 网络结构: 2个Orgnizations(每个Org包含2个peer节点)+1个solo ordering service 打开fabric-sa ...
- Hyperledger fabric 1.3版本的安装部署(原创多机多Orderer部署
首先,我们在安装前,要考虑一个问题 Hyperledger Fabric,通过指定的节点进行背书授权,才能完成交易的存储 延伸开来,就是为了实现容错.高并发.易扩展,需要zookeeper来选择排序引 ...
- Hyperledger Fabric 入门 first-network 搭建
1.准备环境: 安装git.docker.curl.go [root@test_vonedao_83 fabric]# git --version git version 1.8.3.1 [root@ ...
- Hyperledger Fabric开发(二):创建网络
运行fabric-samples项目中的一个例子:first-network,创建第一个网络(Building Your First Network). 该网络共有4个peer节点,划分为2个组织(o ...
随机推荐
- Windows 环境下进行的jenkins持续集成
一台服务器作为代码仓库,一条服务器做持续集成代码仓库目前常见的github.gitlab.gitee持续集成常用Jenkins 服务器的配置这边都以Windows为例进行介绍 1. 安装Jenkins ...
- c#领域驱动设计
代码是个程序员都能写, 怎么的代码才是好的, --------------------------------------------------------------------------- ...
- flex:1详解(转)
转载自:https://blog.csdn.net/fengyjch/article/details/79047908 flex 是 flex-grow.flex-shrink.flex-basis的 ...
- Shiro 与spring 整合的及简单使用(转)
文章完全转载自: http://www.cnblogs.com/learnhow/p/5694876.html ,大家可以点击访问原文链接,个人仅作学习收藏 ! 本篇内容大多总结自张开涛的<跟 ...
- C# Timer 定时任务
C#中,Timer是一个定时器,它可以按照指定的时间间隔或者指定的时间执行一个事件. 指定时间间隔是指按特定的时间间隔,如每1分钟.每10分钟.每1个小时等执行指定事件: 指定时间是指每小时的第30分 ...
- koa源码之delegate使用
koa中context可以直接调用request和response属性的重要原因是使用了delegate将req和res的属性代理到context, Delegator.prototype.gette ...
- es索引管理工具-curator
elasticsearch-curator 是官方收购的开源社区周边产品,用来管理es的索引和快照. 官方文档:https://www.elastic.co/guide/en/elasticsear ...
- C++之标准库map
目录 1.成员函数 2.元素访问 3.迭代器Iterators(C++ 11) 4.容量Capacity 5.修改函数(C++ 11和C++ 17) 6.查找表Lookup 7.观察Observers ...
- 『超分辨率重建』从SRCNN到WDSR
超分辨率重建技术(Super-Resolution)是指从观测到的低分辨率图像重建出相应的高分辨率图像.SR可分为两类: 1. 从多张低分辨率图像重建出高分辨率图像 2. 从单张低分辨率图 ...
- Vue+Element-ui+DateTimePicker 日期时间选择器传值给后台
废话不多说,看代码: <template> <div class="block"> <span class="dem ...