当前位置:网站首页>Fabric 1.0源代码分析(33) Peer #peer channel命令及子命令实现
Fabric 1.0源代码分析(33) Peer #peer channel命令及子命令实现
2022-04-23 11:45:00 【yinchengmvp】
# Fabric 1.0源代码笔记 之 Peer #peer channel命令及子命令实现
## 1、peer channel create子命令实现(创建通道)
### 1.1、初始化Orderer客户端
```go
const (
EndorserRequired EndorserRequirement = true
EndorserNotRequired EndorserRequirement = false
OrdererRequired OrdererRequirement = true
OrdererNotRequired OrdererRequirement = false
)
cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired)
//代码在peer/channel/create.go
```
cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired)代码如下:
```go
type ChannelCmdFactory struct {
EndorserClient pb.EndorserClient //EndorserClient
Signer msp.SigningIdentity //Signer
BroadcastClient common.BroadcastClient //BroadcastClient
DeliverClient deliverClientIntf //DeliverClient
BroadcastFactory BroadcastClientFactory //BroadcastClientFactory,type BroadcastClientFactory func() (common.BroadcastClient, error)
}
func InitCmdFactory(isEndorserRequired EndorserRequirement, isOrdererRequired OrdererRequirement) (*ChannelCmdFactory, error) {
var err error
cmdFact := &ChannelCmdFactory{}
cmdFact.Signer, err = common.GetDefaultSignerFnc() //GetDefaultSignerFnc = GetDefaultSigner
cmdFact.BroadcastFactory = func() (common.BroadcastClient, error) {
return common.GetBroadcastClientFnc(orderingEndpoint, tls, caFile) //GetBroadcastClientFnc = GetBroadcastClient
}
//peer channel join或list需要endorser,本处暂未使用
if isEndorserRequired {
cmdFact.EndorserClient, err = common.GetEndorserClientFnc()
}
//peer channel create或fetch需要orderer
if isOrdererRequired {
var opts []grpc.DialOption
if tls {
if caFile != "" {
creds, err := credentials.NewClientTLSFromFile(caFile, "")
opts = append(opts, grpc.WithTransportCredentials(creds))
}
} else {
opts = append(opts, grpc.WithInsecure())
}
conn, err := grpc.Dial(orderingEndpoint, opts...)
client, err := ab.NewAtomicBroadcastClient(conn).Deliver(context.TODO())
cmdFact.DeliverClient = newDeliverClient(conn, client, chainID) //构造deliverClient
}
return cmdFact, nil
}
//代码在peer/channel/channel.go
```
### 1.2、发送创建区块链的交易
```go
err = sendCreateChainTransaction(cf)
//代码在peer/channel/create.go
```
sendCreateChainTransaction(cf)代码如下:
```go
func sendCreateChainTransaction(cf *ChannelCmdFactory) error {
var err error
var chCrtEnv *cb.Envelope
if channelTxFile != "" { //peer channel create -f指定通道交易配置文件
chCrtEnv, err = createChannelFromConfigTx(channelTxFile) //获取创世区块
} else {
chCrtEnv, err = createChannelFromDefaults(cf) //没有指定通道交易配置文件
}
chCrtEnv, err = sanityCheckAndSignConfigTx(chCrtEnv) //检查和签名交易配置
var broadcastClient common.BroadcastClient
broadcastClient, err = cf.BroadcastFactory()
defer broadcastClient.Close()
err = broadcastClient.Send(chCrtEnv)
return err
}
//代码在peer/channel/create.go
```
### 1.3、获取创世区块并写入文件
```go
var block *cb.Block
block, err = getGenesisBlock(cf) //获取创世区块
b, err := proto.Marshal(block) //块序列化
err = ioutil.WriteFile(file, b, 0644) //写入文件
//代码在peer/channel/create.go
```
## 2、peer channel join子命令实现(加入通道)
### 2.1、初始化Endorser客户端
```go
cf, err = InitCmdFactory(EndorserRequired, OrdererNotRequired)
//代码在peer/channel/join.go
```
### 2.2、构造ChaincodeInvocationSpec消息(cscc.JoinChain)
```go
spec, err := getJoinCCSpec()
invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
//代码在peer/channel/join.go
```
spec, err := getJoinCCSpec()代码如下:
```go
func getJoinCCSpec() (*pb.ChaincodeSpec, error) {
gb, err := ioutil.ReadFile(genesisBlockPath)
input := &pb.ChaincodeInput{Args: [][] byte{[]byte(cscc.JoinChain), gb}}
spec := &pb.ChaincodeSpec{
Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[ "GOLANG"]),
ChaincodeId: &pb.ChaincodeID{Name: "cscc"},
Input: input,
}
return spec, nil
}
//代码在peer/channel/join.go
```
### 2.3、创建cscc Proposal并签名
```go
creator, err := cf.Signer.Serialize()
//从CIS创建Proposal,CIS即ChaincodeInvocationSpec
//调用CreateChaincodeProposal(typ, chainID, cis, creator)
//而后调用CreateChaincodeProposalWithTransient(typ, chainID, cis, creator, nil)
prop, _, err = putils.CreateProposalFromCIS(pcommon.HeaderType_CONFIG, "", invocation, creator)
var signedProp *pb.SignedProposal
signedProp, err = putils.GetSignedProposal(prop, cf.Signer)
//代码在peer/channel/join.go
```
CreateChaincodeProposalWithTransient(typ, chainID, cis, creator, nil)代码如下:
```go
func CreateChaincodeProposalWithTransient(typ common.HeaderType, chainID string, cis *peer.ChaincodeInvocationSpec, creator [] byte, transientMap map[ string][] byte) (*peer.Proposal, str ing, error) {
//创建随机Nonce
nonce, err := crypto.GetRandomNonce()
//计算交易ID
//digest, err := factory.GetDefault().Hash(append(nonce, creator...),&bccsp.SHA256Opts{})
txid, err := ComputeProposalTxID(nonce, creator)
return CreateChaincodeProposalWithTxIDNonceAndTransient(txid, typ, chainID, cis, nonce, creator, transientMap)
}
//代码在protos/utils/proputils.go
```
CreateChaincodeProposalWithTxIDNonceAndTransient(txid, typ, chainID, cis, nonce, creator, transientMap)代码如下:
```go
func CreateChaincodeProposalWithTxIDNonceAndTransient(txid string, typ common.HeaderType, chainID string, cis *peer.ChaincodeInvocationSpec, nonce, creator [] byte, transientMap map[ string][] byte) (*peer.Proposal, string, error) {
ccHdrExt := &peer.ChaincodeHeaderExtension{ChaincodeId: cis.ChaincodeSpec.ChaincodeId}
ccHdrExtBytes, err := proto.Marshal(ccHdrExt)
cisBytes, err := proto.Marshal(cis)
ccPropPayload := &peer.ChaincodeProposalPayload{Input: cisBytes, TransientMap: transientMap}
ccPropPayloadBytes, err := proto.Marshal(ccPropPayload)
var epoch uint64 = 0
timestamp := util.CreateUtcTimestamp()
hdr := &common.Header{ChannelHeader: MarshalOrPanic(&common.ChannelHeader{
Type: int32(typ),
TxId: txid,
Timestamp: timestamp,
ChannelId: chainID,
Extension: ccHdrExtBytes,
Epoch: epoch}),
SignatureHeader: MarshalOrPanic(&common.SignatureHeader{Nonce: nonce, Creator: creator})}
hdrBytes, err := proto.Marshal(hdr)
return &peer.Proposal{Header: hdrBytes, Payload: ccPropPayloadBytes}, txid, nil
}
//代码在protos/utils/proputils.go
```
### 2.4、提交并处理Proposal
```go
var proposalResp *pb.ProposalResponse
proposalResp, err = cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
//代码在peer/channel/join.go
```
## 3、peer channel update(更新锚节点配置)
```go
cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired)
fileData, err := ioutil.ReadFile(channelTxFile)
ctxEnv, err := utils.UnmarshalEnvelope(fileData)
sCtxEnv, err := sanityCheckAndSignConfigTx(ctxEnv)
var broadcastClient common.BroadcastClient
broadcastClient, err = cf.BroadcastFactory()
defer broadcastClient.Close()
return broadcastClient.Send(sCtxEnv)
//代码在peer/channel
```
版权声明
本文为[yinchengmvp]所创,转载请带上原文链接,感谢
https://blog.51cto.com/u_9634496/5248244
边栏推荐
- 1.Electron开发环境搭建
- The fourth chapter is about enabling and disabling the im column storage of table space for im enabled filling objects (IM 4.5)
- How imeu is associated with imcu (IM 5.5)
- Design and practice of the smallest short website system in the whole network
- Resolution due to AMD not found_ ags_ x64. DLL, unable to continue code execution. Reinstallation of the program may solve this problem, Forza horizon 5
- 创客教育中的统筹方案管理模式
- 探究机器人教育的器材与教学
- Laravel admin time range selector daterange default value problem
- Share two practical shell scripts
- On the integration of steam education in early childhood education
猜你喜欢
Analyze the rules for the use of robots with good performance
Simple construction of rebbitmq
配电房远程综合监控系统在10kV预制舱项目中的应用
kettle复制记录到结果和从结果获取记录使用
Overall plan management mode in maker Education
科创人·派拉软件CEO谭翔:零信任本质是数字安全,To B也要深研用户心智
Redis学习之五---高并发分布式锁实战
MQ is easy to use in laravel
少儿编程结构的改变之路
Laravel绑定钉钉群警报(php)
随机推荐
Cognition and R & D technology of micro robot
MQ的了解
用户接口和IM表达式(IM 5.6)
探究机器人教育的器材与教学
Laravel always returns JSON response
激活函数之阶跃函数
用curl库压缩成发送字符串为utf8并用curl库发送
IM表达式如何工作(5.3)
IM 体系结构:CPU架构:SIMD向量处理(IM-2.3)
2022 love analysis · panoramic report of industrial Internet manufacturers
Advanced file IO of system programming (13) -- IO multiplexing - Select
Study notes of C [8] SQL [1]
qt5. 8. You want to use SQLite in the 64 bit static library, but the static library has no method to compile the supporting library
Tensorflow使用keras创建神经网络的方法
微型机器人的认知和研发技术
redis优化系列(二)Redis主从原理、主从常用配置
MQ is easy to use in laravel
Use kettle to copy records to and get records from results
Precautions for PCB
解读机器人编程课程的生物认知度