A road to Fabric - create channel 梳理 (上)
代码版本
Fabric : release 5afac39fcdb1d245aab3a94b825ebadb99cdad72
Fabric-go-sdk : master 9fe40b3f41260f5f4f7c8919117c8b07550871fd
1. 生成 crypto - config
todo
2. 生成 channel.tx
channle.tx
实际上是由 github.com/hyperledger/fabric/protos/common#Envelope
通过proto.marshal()
后生成的bytes文件,对应configtx.yaml
中的ChannelConfig
部分:
|
|
创建Envelop
DSL说明
- 括号外表示实际使用类型,括号内表示grpc使用的字段,没有括号表示为基本类型
- 带有
@
表示已被序列化,即类型为bytes; 带有…
对应grpc 中的repeated
关键字- 较复杂的类型使用Go的表达方式
对字段类型有疑问请参考fabric/protos/common/common.proto
与fabric/protos/common/configtx.proto
整个Envelop对象由fabric/common/configtx/template.go#MakeChainCreationTransaction
函数生成,之后通过ioutil
写入channle.tx文件中
|
|
|
|
3 .使用当前User对Envelop.Payload.ConfigUpdateEnvelop
签名
以 go sdk为例 pkg/fabric-client/client.go:247
client方法SignChannelConfig
首先创建ConfigUpdateEnvelop.ConfigSignature
|
|
序列化后与整个ConfigUpdateEnvelop
一起使用User private key进行签名返回
|
|
得到签名后构建ChannelCreateRequest
对象,调用CreateChannel
方法,
|
|
4. 重新用Orderer的MSP生成txid,设置Envelop.Payload.Header
在上一步中,client的当前User Context已经设置为Orderer user,c.NewTxnID()
会调用当前user的Identity()
方法生成序列化的身份证明,之后与一个随机数生成txID
|
|
然后设置Payload header (省略了err catch的代码)可以看到ChannelHeader重新设置了txID为上一步生成的txID,并且通过fc.BuildHeader
添加了’创建Envelop’步骤中缺少的SignatureHeader , 在这里所有的signature均适用orderer的私钥
|
|
之后在pkg/fabric-client/client.go:341
的createOrUpdateChannel
中调用Orderer对象的SendBroadcast
方法,给Orderer发broadcast请求(关于broadcast / deliver机制 Fabric 官方文档中有详细的说明)
|
|
在SendBroadcast
中使用grpc调用Orderer的Broadcast
函数,相关的protobuf为fabric/protos/orderer/ab.proto
,接下来进入Orderer内部处理的环节