블록체인 자습서 Fabric1.0 소스 코드 분석 Peer peer channel 명령 및 하위 명령 구현

7570 단어 channelfabric
브로맨스 체인 튜토리얼 Fabric 1.0소스 코드 분석: Peer peer channel 명령 및 하위 명령 실현, 2018년 하반기 블록체인 업계는 발전 초기의 경박함, 이성으로 회귀하고 있다. 겉으로 보면 관련 인재 수요와 몸값이 하락하고 있는 것 같다.그러나 사실 초기 거품의 점퇴는 블록체인의 진정한 기술에 더 많은 관심을 갖게 했다.
Fabric1.0 소스 노트의 Peer peer channel 명령 및 하위 명령 구현
1. peer channel create 하위 명령 구현(채널 생성)
1.1 Orderer 클라이언트 초기화
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) 코드는 다음과 같습니다.
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 블록체인을 만드는 거래를 발송한다.
err = sendCreateChainTransaction(cf)
//   peer/channel/create.go

sendCreateChainTransaction(cf) 코드는 다음과 같습니다.
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 창세 블록을 가져오고 파일에 쓰기
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 클라이언트 초기화
cf, err = InitCmdFactory(EndorserRequired, OrdererNotRequired)
//   peer/channel/join.go

2.2 ChaincodeInvocationSpec 메시지 구성(cscc.JoinChain)
spec, err := getJoinCCSpec()
invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
//   peer/channel/join.go

spec,err: = getJoinCCSpec() 코드는 다음과 같습니다.
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 작성 및 서명
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) 코드는 다음과 같습니다.
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) 코드는 다음과 같습니다.
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 제출 및 처리
var proposalResp *pb.ProposalResponse
proposalResp, err = cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
//   peer/channel/join.go

3. peer channel 업데이트(닻 노드 설정 업데이트)
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

좋은 웹페이지 즐겨찾기