当前位置:网站首页>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
边栏推荐
- 积极参与中学机器人竞赛的意义
- Tensorflow使用keras创建神经网络的方法
- oh-my-lotto
- laravel编写Console脚本
- IFLYTEK's revenue in 2021 was 18.3 billion yuan: a year-on-year increase of 41% and a net profit of 1.556 billion yuan
- How to count fixed assets and how to generate an asset count report with one click
- 云呐|固定资产盘点中,支持多种盘点方式(资产清查盘点)
- 科创人·派拉软件CEO谭翔:零信任本质是数字安全,To B也要深研用户心智
- Using Baidu PaddlePaddle EasyDL to accomplish specified target recognition
- The listing of saiweidian Technology Innovation Board broke: a decrease of 26% and the market value of the company was 4.4 billion
猜你喜欢
Write console script by laravel
Change exchange II - [leetcode]
零钱兑换II——【LeetCode】
Siri gave the most embarrassing social death moment of the year
Overall plan management mode in maker Education
nacos基础(5):nacos配置入门
Cognition and R & D technology of micro robot
论坛系统数据库设计
让中小学生在快乐中学习的创客教育
How to count fixed assets and how to generate an asset count report with one click
随机推荐
激活函数之relu函数
After the MySQL router is reinstalled, it reconnects to the cluster for boot - a problem that has been configured in this host before
Nacos Basics (5): getting started with Nacos configuration
laravel编写Console脚本
零钱兑换II——【LeetCode】
docker MySQL主从备份
Nacos Foundation (8): login management
IM 体系结构:CPU架构:SIMD向量处理(IM-2.3)
Using Baidu PaddlePaddle EasyDL to accomplish specified target recognition
Pytorch neural network trainer
Interpretation of 2022 robot education industry analysis report
微型机器人的认知和研发技术
Tensorflow uses keras to create neural networks
qt5.8 64 位静态库中想使用sqlite但静态库没有编译支持库的方法
第四章 为IM 启用填充对象之强制填充In-Memory对象:教程(IM 4.7)
解决由于找不到amd_ags_x64.dll,无法继续执行代码。重新安装程序可能会解决此问题,地平线(Forza Horizon 5)
Golang Pen & interview 01
Summary of QT semaphore unresolved errors
GPU, CUDA,cuDNN三者的關系總結
创客教育中的统筹方案管理模式