兄弟連區塊鏈技術培訓Fabric 1.0原始碼分析(33) Peer #peer channel命令及子命令實現

來源:互聯網
上載者:User

兄弟連區塊鏈技術培訓Fabric 1.0原始碼分析(33) Peer #peer channel命令及子命令實現

# 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

 是科技發展太快,還是我們已經掉尾?7月7日起,每天兩小時跟清華微軟Google大牛團隊一起實戰區塊鏈。

http://www.ydma.cn/open/course/16來來來,清華學霸尹成大哥帶你飛起來~~~

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.