• Fabric 2.2底层结构设计分析


    Fabric 2.2底层结构设计分析


    Fabric的底层定义项目:hyperledger/fabric-protos-go

    一、Block类型分析

    Block定义

    • Block
    type Block struct {
    	Header               *BlockHeader   `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
    	Data                 *BlockData     `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
    	Metadata             *BlockMetadata `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"`
    	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
    	XXX_unrecognized     []byte         `json:"-"`
    	XXX_sizecache        int32          `json:"-"`
    }
    
    • BlockHeader
    type BlockHeader struct {
    	Number               uint64   `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"`
    	PreviousHash         []byte   `protobuf:"bytes,2,opt,name=previous_hash,json=previousHash,proto3" json:"previous_hash,omitempty"`
    	DataHash             []byte   `protobuf:"bytes,3,opt,name=data_hash,json=dataHash,proto3" json:"data_hash,omitempty"`
    	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    	XXX_unrecognized     []byte   `json:"-"`
    	XXX_sizecache        int32    `json:"-"`
    }
    
    • BlockData
    type BlockData struct {
    	Data                 [][]byte `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
    	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    	XXX_unrecognized     []byte   `json:"-"`
    	XXX_sizecache        int32    `json:"-"`
    }
    
    • BlockMetaData
    type BlockMetadata struct {
    	Metadata             [][]byte `protobuf:"bytes,1,rep,name=metadata,proto3" json:"metadata,omitempty"`
    	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    	XXX_unrecognized     []byte   `json:"-"`
    	XXX_sizecache        int32    `json:"-"`
    }
    

    具体关系参考如下Channel的Genesis Block生成过程

    // Block constructs and returns a genesis block for a given channel ID.
    func (f *factory) Block(channelID string) *cb.Block {
    	payloadChannelHeader := protoutil.MakeChannelHeader(cb.HeaderType_CONFIG, msgVersion, channelID, epoch)
    	payloadSignatureHeader := protoutil.MakeSignatureHeader(nil, protoutil.CreateNonceOrPanic())
    	protoutil.SetTxID(payloadChannelHeader, payloadSignatureHeader)
    	payloadHeader := protoutil.MakePayloadHeader(payloadChannelHeader, payloadSignatureHeader)
    	payload := &cb.Payload{Header: payloadHeader, Data: protoutil.MarshalOrPanic(&cb.ConfigEnvelope{Config: &cb.Config{ChannelGroup: f.channelGroup}})}
    	envelope := &cb.Envelope{Payload: protoutil.MarshalOrPanic(payload), Signature: nil}
    
    	block := protoutil.NewBlock(0, nil)
    	block.Data = &cb.BlockData{Data: [][]byte{protoutil.MarshalOrPanic(envelope)}}
    	block.Header.DataHash = protoutil.BlockDataHash(block.Data)
    	block.Metadata.Metadata[cb.BlockMetadataIndex_LAST_CONFIG] = protoutil.MarshalOrPanic(&cb.Metadata{
    		Value: protoutil.MarshalOrPanic(&cb.LastConfig{Index: 0}),
    	})
    	block.Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES] = protoutil.MarshalOrPanic(&cb.Metadata{
    		Value: protoutil.MarshalOrPanic(&cb.OrdererBlockMetadata{
    			LastConfig: &cb.LastConfig{Index: 0},
    		}),
    	})
    	return block
    }
    

    Block类型关系图

    二、交易结构定义分析

    交易类型分类

    HeaderType_MESSAGE              HeaderType = 0
    // channel配置交易
    HeaderType_CONFIG               HeaderType = 1
    // 
    HeaderType_CONFIG_UPDATE        HeaderType = 2
    // 链码交易
    HeaderType_ENDORSER_TRANSACTION HeaderType = 3
    // 
    HeaderType_ORDERER_TRANSACTION  HeaderType = 4
    HeaderType_DELIVER_SEEK_INFO    HeaderType = 5
    HeaderType_CHAINCODE_PACKAGE    HeaderType = 6
    

    交易类型说明

    1. HeaderType_MESSAGE对应的交易类型

    hyperledger/fabric-protos-go/common/configtx.pb.go
    
    type ConfigValue struct {
    	Version              uint64   `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
    	Value                []byte   `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
    	ModPolicy            string   `protobuf:"bytes,3,opt,name=mod_policy,json=modPolicy,proto3" json:"mod_policy,omitempty"`
    	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    	XXX_unrecognized     []byte   `json:"-"`
    	XXX_sizecache        int32    `json:"-"`
    }
    

    2. HeaderType_CONFIG对应的交易类型

    hyperledger/fabric-protos-go/common/configtx.pb.go
    
    type ConfigEnvelope struct {
    	Config               *Config   `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
    	LastUpdate           *Envelope `protobuf:"bytes,2,opt,name=last_update,json=lastUpdate,proto3" json:"last_update,omitempty"`
    	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
    	XXX_unrecognized     []byte    `json:"-"`
    	XXX_sizecache        int32     `json:"-"`
    }
    

    3. HeaderType_CONFIG_UPDATE对应的交易类型

    hyperledger/fabric-protos-go/common/configtx.pb.go
    
    type ConfigUpdateEnvelope struct {
    	ConfigUpdate         []byte             `protobuf:"bytes,1,opt,name=config_update,json=configUpdate,proto3" json:"config_update,omitempty"`
    	Signatures           []*ConfigSignature `protobuf:"bytes,2,rep,name=signatures,proto3" json:"signatures,omitempty"`
    	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
    	XXX_unrecognized     []byte             `json:"-"`
    	XXX_sizecache        int32              `json:"-"`
    }
    

    4. HeaderType_ENDORSER_TRANSACTION对应的交易类型

    hyperledger/fabric-protos-go/peer/transaction.pb.go
    
    type Transaction struct {
    	// The payload is an array of TransactionAction. An array is necessary to
    	// accommodate multiple actions per transaction
    	Actions              []*TransactionAction `protobuf:"bytes,1,rep,name=actions,proto3" json:"actions,omitempty"`
    	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
    	XXX_unrecognized     []byte               `json:"-"`
    	XXX_sizecache        int32                `json:"-"`
    }
    

    5. HeaderType_ORDERER_TRANSACTION对应的交易类型

    hyperledger/fabric-protos-go/common/common.pb.go
    
    type Envelope struct {
    	// A marshaled Payload
    	Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
    	// A signature by the creator specified in the Payload header
    	Signature            []byte   `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
    	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    	XXX_unrecognized     []byte   `json:"-"`
    	XXX_sizecache        int32    `json:"-"`
    }
    

    6. HeaderType_DELIVER_SEEK_INFO对应的交易类型

    hyperledger/fabric-protos-go/orderer/ab.pb.go
    
    type SeekInfo struct {
    	Start                *SeekPosition              `protobuf:"bytes,1,opt,name=start,proto3" json:"start,omitempty"`
    	Stop                 *SeekPosition              `protobuf:"bytes,2,opt,name=stop,proto3" json:"stop,omitempty"`
    	Behavior             SeekInfo_SeekBehavior      `protobuf:"varint,3,opt,name=behavior,proto3,enum=orderer.SeekInfo_SeekBehavior" json:"behavior,omitempty"`
    	ErrorResponse        SeekInfo_SeekErrorResponse `protobuf:"varint,4,opt,name=error_response,json=errorResponse,proto3,enum=orderer.SeekInfo_SeekErrorResponse" json:"error_response,omitempty"`
    	XXX_NoUnkeyedLiteral struct{}                   `json:"-"`
    	XXX_unrecognized     []byte                     `json:"-"`
    	XXX_sizecache        int32                      `json:"-"`
    }
    

    7. HeaderType_CHAINCODE_PACKAGE对应的交易类型

    在源码中未看到使用情况

    交易类型关系图

    三、链码相关

    1. 支持的链码开发语言类型

    hyperledger/fabric-protos-go/peer/chaincode.pb.go
    
    ChaincodeSpec_UNDEFINED ChaincodeSpec_Type = 0
    ChaincodeSpec_GOLANG    ChaincodeSpec_Type = 1
    ChaincodeSpec_NODE      ChaincodeSpec_Type = 2
    ChaincodeSpec_CAR       ChaincodeSpec_Type = 3
    ChaincodeSpec_JAVA      ChaincodeSpec_Type = 4
    

    2. 链码交易定义

    type ChaincodeSpec struct {
    	Type                 ChaincodeSpec_Type `protobuf:"varint,1,opt,name=type,proto3,enum=protos.ChaincodeSpec_Type" json:"type,omitempty"`
    	ChaincodeId          *ChaincodeID       `protobuf:"bytes,2,opt,name=chaincode_id,json=chaincodeId,proto3" json:"chaincode_id,omitempty"`
    	Input                *ChaincodeInput    `protobuf:"bytes,3,opt,name=input,proto3" json:"input,omitempty"`
    	Timeout              int32              `protobuf:"varint,4,opt,name=timeout,proto3" json:"timeout,omitempty"`
    	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
    	XXX_unrecognized     []byte             `json:"-"`
    	XXX_sizecache        int32              `json:"-"`
    }
    
    type ChaincodeID struct {
    	//deploy transaction will use the path
    	Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
    	//all other requests will use the name (really a hashcode) generated by
    	//the deploy transaction
    	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
    	//user friendly version name for the chaincode
    	Version              string   `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
    	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    	XXX_unrecognized     []byte   `json:"-"`
    	XXX_sizecache        int32    `json:"-"`
    }
    
    type ChaincodeInput struct {
    	Args        [][]byte          `protobuf:"bytes,1,rep,name=args,proto3" json:"args,omitempty"`
    	Decorations map[string][]byte `protobuf:"bytes,2,rep,name=decorations,proto3" json:"decorations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
    	// is_init is used for the application to signal that an invocation is to be routed
    	// to the legacy 'Init' function for compatibility with chaincodes which handled
    	// Init in the old way.  New applications should manage their initialized state
    	// themselves.
    	IsInit               bool     `protobuf:"varint,3,opt,name=is_init,json=isInit,proto3" json:"is_init,omitempty"`
    	XXX_NoUnkeyedLiteral struct{} `json:"-"`
    	XXX_unrecognized     []byte   `json:"-"`
    	XXX_sizecache        int32    `json:"-"`
    }
    

    3. 链码的安装过程

    • Fabric经典的lifecycle流程如下:

      1. ProposalsSDK/CLI向Peer节点发起提案,设置背书策略
      2. Execute:Peer执行合约
      3. ProposalRespond【Endorsed】:Peer对执行结果进行签名,向SDK/CLI返回背书结果
      4. BroadcastSDK/CLI整理背书结果,向Orderer广播背书结果
      5. Orderer:Orderer节点对交易排序,然后打包出块
      6. Deliver:Orderer节点将区块发送给Peer节点
      7. Validate & Commit:Peer节点验证和确认
      8. Notify:Peer节点将验证结果返回给SDK/CLI
    • CLI对应lifecycle安装流程如下:
      package -> install package -> queryinstalled -> approveformyorg -> checkcommitreadiness(检查智能合约是否就绪,需要背书策略中的大部分组织同意) -> commit -> querycommitted -> done

      • approveformyorg(组织认可智能合约定义)创建的是CommitChaincodeDefinition proposal交易
      • commit(提交智能合约定义)创建的是ApproveChaincodeDefinitionForMyOrg proposal交易

    参考:Fabric test-network搭建[solo-1orderer-2peer]

    • 链码过程的request的实现代码位置(SDK)
    hyperledger/fabric-sdk-go/pkg/resource/lifecycle.go
    
  • 相关阅读:
    flask与Django的区别
    flask特殊装饰器
    flaskjinjia2模板
    flask类视图
    flask路由系统
    flask初识
    python2与python3 的安装与环境变量的添加
    WebGL_0007:强制横屏的参考
    NodeJS_0011:nodejs重定向到一个链接或本地的页面的方法
    NodeJS_0006:nodejs响应超时处理
  • 原文地址:https://www.cnblogs.com/jiftle/p/15302639.html
Copyright © 2020-2023  润新知