# 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

```

网址:http://www.qukuailianxueyuan.io/

欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:CSDN

尹成学院微信:备注:CSDN

网址:http://www.qukuailianxueyuan.io/

欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:CSDN

尹成学院微信:备注:CSDN

Fabric 1.0源代码分析(33) Peer #peer channel命令及子命令实现相关推荐

  1. Fabric 1.0源代码分析(32)Peer #peer根命令入口及加载子命令

    # Fabric 1.0源代码笔记 之 Peer #peer根命令入口及加载子命令 ## 1.加载环境变量配置和配置文件 Fabric支持通过环境变量对部分配置进行更新,如:CORE_LOGGING_ ...

  2. Fabric 1.0源代码分析(31) Peer

    # Fabric 1.0源代码笔记 之 Peer ## 1.Peer概述 在Fabric中,Peer(节点)是指在网络中负责接收交易请求.维护一致账本的各个fabric-peer实例.节点之间彼此通过 ...

  3. Fabric 1.0源代码分析(37) Peer #DeliverClient(Deliver客户端)

    # Fabric 1.0源代码笔记 之 Peer #DeliverClient(Deliver客户端) ## 1.DeliverClient概述 DeliverClient代码分布如下: * peer ...

  4. Fabric 1.0源代码分析(32) Peer #peer node start命令实现

    # Fabric 1.0源代码笔记 之 Peer #peer node start命令实现 ## 1.peer node加载子命令start和status peer node加载子命令start和st ...

  5. Fabric 1.0源代码分析(34) Peer #peer chaincode命令及子命令实现

    # Fabric 1.0源代码笔记 之 Peer #peer chaincode命令及子命令实现 ## 1.peer chaincode install子命令实现(安装链码) ### 1.0.peer ...

  6. Fabric 1.0源代码分析(38) Peer #BroadcastClient(Broadcast客户端)

    # Fabric 1.0源代码笔记 之 Peer #BroadcastClient(Broadcast客户端) ## 1.BroadcastClient概述 BroadcastClient代码分布如下 ...

  7. Fabric 1.0源代码分析(15)gossip(流言算法)

    # Fabric 1.0源代码笔记 之 gossip(流言算法) ## 1.gossip概述 gossip,翻译为流言蜚语,即为一种可最终达到一致的算法.最终一致的另外的含义就是,不保证同时达到一致. ...

  8. Fabric 1.0源代码分析(22)Ledger #blkstorage(block文件存储)

    # Fabric 1.0源代码笔记 之 Ledger #blkstorage(block文件存储) ## blkstorage概述 blkstorage,默认目录/var/hyperledger/pr ...

  9. Fabric 1.0源代码分析(40) Proposal(提案)

    # Fabric 1.0源代码笔记 之 Proposal(提案) ## 1.Proposal概述 Proposal,即向Endorser发起的提案. Proposal代码分布在protos/utils ...

最新文章

  1. 分库分表:如何做到永不迁移数据和避免热点?
  2. Dottrace 10.0.2 使用心得
  3. Godaddy如何导入导出MSSQL数据库
  4. javascript 面向对象编程(工厂模式、构造函数模式、原型模式)
  5. Android init.rc文件解析过程详解(二)
  6. 我竟然混进了 Python 高级圈子!
  7. spring boot配置ip_Spring Cloud 配置中心高可用搭建
  8. 如何用一头死驴赚到998元
  9. 网络营销时不仅需要考虑用户体验,也要赋予情感
  10. PLC可编程控制器的应用
  11. c语言贪吃蛇游戏代码较难,用C语言编写贪吃蛇代码(难度可选)
  12. wincemobile的GPS开发
  13. 重装系统 重启计算机失败,一键重装系统win7后重启进入系统失败
  14. gbk与gb2312并不一样
  15. 小龙 Dev-C++ 5.16 发布了
  16. .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记
  17. Adidas商品上货监控,有货时提醒商品尺码
  18. 港中文、佐治亚理工招收AI博士生
  19. 三天搞定射频识别技术(二)2.3寻卡防冲突选卡
  20. 入网许可证_入网许可证真伪鉴别

热门文章

  1. 深度研究微软的资产负债表和财务状况以及未来投资价值
  2. AxMath的常用操作
  3. bzoj3436小K的农场
  4. java中根据自己的需要画一张jgp的图片
  5. github页面404
  6. Cleave input输入框 自动格式化内容
  7. VS2013 断点总是乱跳
  8. c语言输出函数定义,c语言输入输出函数的定义.doc
  9. Android-上传三星应用商店
  10. TD-LTE上行吞吐率优化指导书V2.0