Fabric1.0源代码分析PeerBroadcastClient(Broadcast客户端)

合集下载

兄弟连区块链技术培训Fabric 1.0源代码分析(17)gossip(流言算法) #deliverclient(deliver客户端)

兄弟连区块链技术培训Fabric 1.0源代码分析(17)gossip(流言算法) #deliverclient(deliver客户端)

兄弟连区块链技术培训Fabric 1.0源代码分析(17)gossip (流言算法)#deliverclient(deliver客户端)# Fabric 1.0源代码笔记之 gossip(流言算法) #deliverclient(deliver客户端)## 1、deliverclient概述deliverclient代码分布在gossip/service、core/deliverservice目录下,目录结构如下:* gossip/service目录:* gossip_service.go,DeliveryServiceFactory接口定义及实现。

* core/deliverservice目录:* deliveryclient.go,DeliverService接口定义及实现。

* client.go,broadcastClient结构体,实现AtomicBroadcast_BroadcastCli ent接口。

* requester.go,blocksRequester结构体及方法。

* blocksprovider目录,BlocksProvider接口定义及实现。

## 2、DeliveryServiceFactory接口定义及实现```gotype DeliveryServiceFactory interface {Service(g GossipService, endpoints []string, msc api.MessageCryptoS ervice) (deliverclient.DeliverService, error)}type deliveryFactoryImpl struct {}// Returns an instance of delivery clientfunc (*deliveryFactoryImpl) Service(g GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) { return deliverclient.NewDeliverService(&deliverclient.Config{CryptoSvc: mcs,Gossip: g,Endpoints: endpoints,ConnFactory: deliverclient.DefaultConnectionFactory,ABCFactory: deliverclient.DefaultABCFactory,})}//代码在gossip/service/gossip_service.go```## 3、DeliverService接口定义及实现### 3.1、DeliverService接口定义用于与orderer沟通获取新区块,并发送给committer。

兄弟连区块链教程Fabric1.0源代码分析gRPC Fabric中注册的gRPC Service一

兄弟连区块链教程Fabric1.0源代码分析gRPC Fabric中注册的gRPC Service一

兄弟连区块链教程Fabric1.0源代码分析gRPC(Fabric中注册的gRPC Service)一兄弟连区块链教程Fabric1.0源代码分析gRPC(Fabric中注册的gRPC Service)一,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。

但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# Fabric 1.0源代码笔记之 -gRPC(Fabric中注册的gRPC Service)Peer节点中注册的gRPC Service,包括:* Events Service(事件服务):Chat* Admin Service(管理服务):GetStatus、StartServer、GetModuleLogLevel、SetModuleLogLevel、RevertLogLevels* Endorser Service(背书服务):ProcessProposal* ChaincodeSupport Service(链码支持服务):Register* Gossip Service(Gossip服务):GossipStream、PingOrderer节点中注册的gRPC Service,包括:* AtomicBroadcast Service(广播服务):Broadcast、Deliver## 1、Peer节点中注册的gRPC Service### 1.1、Events Service(事件服务)#### 1.1.1、Events Service客户端```gotype EventsClient interface {// event chatting using EventChat(ctx context.Context, opts ...grpc.CallOption) (Events_ChatClient, error)}type eventsClient struct {cc *grpc.ClientConn}func NewEventsClient(cc *grpc.ClientConn) EventsClient {return &eventsClient{cc}}func (c *eventsClient) Chat(ctx context.Context, opts ...grpc.CallOption) (Events_ChatClient, error) {stream, err := grpc.NewClientStream(ctx,&_Events_serviceDesc.Streams[0], , "/protos.Events/Chat", opts...) if err != nil {return nil, err}x := &eventsChatClient{stream}return x, nil}//代码在protos/peer/events.pb.go```#### 1.1.2、Events Service服务端```gotype EventsServer interface {Chat(Events_ChatServer) error}func RegisterEventsServer(s *grpc.Server, srv EventsServer) {s.RegisterService(&_Events_serviceDesc, srv)}func _Events_Chat_Handler(srv interface{}, stream grpc.ServerStream) error {return srv.(EventsServer).Chat(&eventsChatServer{stream})}var _Events_serviceDesc = grpc.ServiceDesc{ServiceName: "protos.Events",HandlerType: (*EventsServer)(nil),Methods: []grpc.MethodDesc{},Streams: []grpc.StreamDesc{{StreamName: "Chat",Handler: _Events_Chat_Handler,ServerStreams: true,ClientStreams: true,},},Metadata: "peer/events.proto",}//代码在protos/peer/events.pb.go```### 1.2、Admin Service(管理服务)#### 1.2.1、Admin Service客户端```gotype AdminClient interface {// Return the serve status.GetStatus(ctx context.Context, in *google_protobuf.Empty,opts ...grpc.CallOption) (*ServerStatus, error)StartServer(ctx context.Context, in *google_protobuf.Empty,opts ...grpc.CallOption) (*ServerStatus, error)GetModuleLogLevel(ctx context.Context, in *LogLevelRequest,opts ...grpc.CallOption) (*LogLevelResponse, error)SetModuleLogLevel(ctx context.Context, in *LogLevelRequest,opts ...grpc.CallOption) (*LogLevelResponse, error)RevertLogLevels(ctx context.Context, in *google_protobuf.Empty,opts ...grpc.CallOption) (*google_protobuf.Empty, error)}type adminClient struct {cc *grpc.ClientConn}func NewAdminClient(cc *grpc.ClientConn) AdminClient {return &adminClient{cc}}func (c *adminClient) GetStatus(ctx context.Context, in*google_protobuf.Empty, opts ...grpc.CallOption) (*ServerStatus, error) { out := new(ServerStatus)err := grpc.Invoke(ctx, "/protos.Admin/GetStatus", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) StartServer(ctx context.Context, in*google_protobuf.Empty, opts ...grpc.CallOption) (*ServerStatus, error) {out := new(ServerStatus)err := grpc.Invoke(ctx, "/protos.Admin/StartServer", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) GetModuleLogLevel(ctx context.Context, in*LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) { out := new(LogLevelResponse)err := grpc.Invoke(ctx, "/protos.Admin/GetModuleLogLevel", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) SetModuleLogLevel(ctx context.Context, in*LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) { out := new(LogLevelResponse)err := grpc.Invoke(ctx, "/protos.Admin/SetModuleLogLevel", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) RevertLogLevels(ctx context.Context, in*google_protobuf.Empty, opts ...grpc.CallOption) (*google_protobuf.Empty, error) {out := new(google_protobuf.Empty)err := grpc.Invoke(ctx, "/protos.Admin/RevertLogLevels", in, out, , opts...)if err != nil {return nil, err}return out, nil}//代码在protos/peer/admin.pb.go```#### 1.2.2、Admin Service服务端```gotype AdminServer interface {GetStatus(context.Context, *google_protobuf.Empty) (*ServerStatus, error)StartServer(context.Context, *google_protobuf.Empty) (*ServerStatus, error)GetModuleLogLevel(context.Context, *LogLevelRequest)(*LogLevelResponse, error)SetModuleLogLevel(context.Context, *LogLevelRequest)(*LogLevelResponse, error)RevertLogLevels(context.Context, *google_protobuf.Empty)(*google_protobuf.Empty, error)}func RegisterAdminServer(s *grpc.Server, srv AdminServer) {s.RegisterService(&_Admin_serviceDesc, srv)}func _Admin_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {in := new(google_protobuf.Empty)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).GetStatus(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/GetStatus",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).GetStatus(ctx,req.(*google_protobuf.Empty))}return interceptor(ctx, in, info, handler)}func _Admin_StartServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {in := new(google_protobuf.Empty)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).StartServer(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/StartServer",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).StartServer(ctx,req.(*google_protobuf.Empty))}return interceptor(ctx, in, info, handler)}func _Admin_GetModuleLogLevel_Handler(srv interface{}, ctxcontext.Context, dec func(interface{}) error, interceptorgrpc.UnaryServerInterceptor) (interface{}, error) {in := new(LogLevelRequest)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).GetModuleLogLevel(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/GetModuleLogLevel",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).GetModuleLogLevel(ctx,req.(*LogLevelRequest))}return interceptor(ctx, in, info, handler)}func _Admin_SetModuleLogLevel_Handler(srv interface{}, ctxcontext.Context, dec func(interface{}) error, interceptorgrpc.UnaryServerInterceptor) (interface{}, error) {in := new(LogLevelRequest)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).SetModuleLogLevel(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/SetModuleLogLevel",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).SetModuleLogLevel(ctx,req.(*LogLevelRequest))}return interceptor(ctx, in, info, handler)}func _Admin_RevertLogLevels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {in := new(google_protobuf.Empty)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).RevertLogLevels(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/RevertLogLevels",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).RevertLogLevels(ctx,req.(*google_protobuf.Empty))}return interceptor(ctx, in, info, handler)}var _Admin_serviceDesc = grpc.ServiceDesc{ServiceName: "protos.Admin",HandlerType: (*AdminServer)(nil),Methods: []grpc.MethodDesc{{MethodName: "GetStatus",Handler: _Admin_GetStatus_Handler,},{MethodName: "StartServer",Handler: _Admin_StartServer_Handler,},{MethodName: "GetModuleLogLevel",Handler: _Admin_GetModuleLogLevel_Handler, },{MethodName: "SetModuleLogLevel",Handler: _Admin_SetModuleLogLevel_Handler, },{MethodName: "RevertLogLevels",Handler: _Admin_RevertLogLevels_Handler, },},Streams: []grpc.StreamDesc{},Metadata: "peer/admin.proto",}//代码在protos/peer/admin.pb.go```未完待续感谢关注兄弟连区块链教程分享!。

兄弟连区块链技术培训Fabric 1.0源代码分析(4) Chaincode(链码) platforms(链码语言平台)

兄弟连区块链技术培训Fabric 1.0源代码分析(4) Chaincode(链码) platforms(链码语言平台)

兄弟连区块链技术培训Fabric 1.0源代码分析(4)Chain code(链码)#platforms(链码语言平台)Fabric 1.0源代码笔记之 Chaincode(链码) #platforms(链码语言平台)## 1、platforms概述platforms代码集中在core/chaincode/platforms目录下。

* core/chaincode/platforms目录,链码的编写语言平台实现,如golang或java。

* platforms.go,Platform接口定义,及platforms相关工具函数。

* util目录,Docker相关工具函数。

* java目录,java语言平台实现。

* golang目录,golang语言平台实现。

## 2、Platform接口定义```gotype Platform interface {//验证ChaincodeSpecValidateSpec(spec *pb.ChaincodeSpec) error//验证ChaincodeDeploymentSpecValidateDeploymentSpec(spec *pb.ChaincodeDeploymentSpec) error//获取部署PayloadGetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error)//生成DockerfileGenerateDockerfile(spec *pb.ChaincodeDeploymentSpec) (string, erro r)//生成DockerBuildGenerateDockerBuild(spec *pb.ChaincodeDeploymentSpec, tw *tar.Write r) error}//代码在core/chaincode/platforms/platforms.go```## 3、platforms相关工具函数### 3.1、platforms相关工具函数```go//按链码类型构造Platform接口实例,如golang.Platform{}func Find(chaincodeType pb.ChaincodeSpec_Type) (Platform, error)//调取platform.GetDeploymentPayload(spec),获取部署Payloadfunc GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error)//优先获取tls根证书,如无则获取tls证书func getPeerTLSCert() ([]byte, error)//调取platform.GenerateDockerfile(cds),创建Dockerfilefunc generateDockerfile(platform Platform, cds *pb.ChaincodeDeploymentS pec, tls bool) ([]byte, error)//调取platform.GenerateDockerBuild(cds, tw),创建DockerBuildfunc generateDockerBuild(platform Platform, cds *pb.ChaincodeDeployment Spec, inputFiles InputFiles, tw *tar.Writer) error//调取generateDockerfile(platform, cds, cert != nil)func GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec) (io.Reader, e rror)//代码在core/chaincode/platforms/platforms.go```### 3.2、Docker相关工具函数```go//contents+hash合并后再哈希func ComputeHash(contents []byte, hash []byte) []byte//哈希目录下文件并打包func HashFilesInDir(rootDir string, dir string, hash []byte, tw *tar.Wr iter) ([]byte, error)//目录是否存在func IsCodeExist(tmppath string) error//编译链码func DockerBuild(opts DockerBuildOptions) error//代码在core/chaincode/platforms/util/utils.go```func DockerBuild(opts DockerBuildOptions) error代码如下:```gotype DockerBuildOptions struct {Image stringEnv []stringCmd stringInputStream io.ReaderOutputStream io.Writer}func DockerBuild(opts DockerBuildOptions) error {client, err := cutil.NewDockerClient()if err != nil {return fmt.Errorf("Error creating docker client: %s", err)}if opts.Image == "" {//通用的本地编译环境opts.Image = cutil.GetDockerfileFromConfig("chaincode.builder") }//确认镜像是否存在或从远程拉取_, err = client.InspectImage(opts.Image)if err != nil {err = client.PullImage(docker.PullImageOptions{Repository: opts. Image}, docker.AuthConfiguration{})}//创建一个暂时的容器container, err := client.CreateContainer(docker.CreateContainerOpti ons{Config: &docker.Config{Image: opts.Image,Env: opts.Env,Cmd: []string{"/bin/sh", "-c", opts.Cmd},AttachStdout: true,AttachStderr: true,},})//删除容器defer client.RemoveContainer(docker.RemoveContainerOptions{ID: cont ainer.ID})//上传输入err = client.UploadToContainer(container.ID, docker.UploadToContain erOptions{Path: "/chaincode/input",InputStream: opts.InputStream,})stdout := bytes.NewBuffer(nil)_, err = client.AttachToContainerNonBlocking(docker.AttachToContain erOptions{Container: container.ID,OutputStream: stdout,ErrorStream: stdout,Logs: true,Stdout: true,Stderr: true,Stream: true,})//启动容器err = client.StartContainer(container.ID, nil)//等待容器返回retval, err := client.WaitContainer(container.ID)//获取容器输出err = client.DownloadFromContainer(container.ID, docker.DownloadFro mContainerOptions{Path: "/chaincode/output/.",OutputStream: opts.OutputStream,})return nil}//代码在core/chaincode/platforms/util/utils.go```## 4、golang语言平台实现### 4.1、golang.Platform结构体定义及方法Platform接口golang语言平台实现,即golang.Platform结构体定义及方法。

兄弟连区块链教程Fabric1.0源代码分析blockfile区块文件存储二

兄弟连区块链教程Fabric1.0源代码分析blockfile区块文件存储二

兄弟连区块链教程Fabric1.0源代码分析blockfile区块文件存储二兄弟连区块链教程Fabric1.0源代码分析blockfile区块文件存储二。

涉及方法如下:```go//构造blockIndexfunc newBlockIndex(indexConfig *blkstorage.IndexConfig, db*leveldbhelper.DBHandle) *blockIndex//获取最后一个块索引(或编号),取key为"indexCheckpointKey"的值,即为最新的区块编号func (index *blockIndex) getLastBlockIndexed() (uint64, error)func (index *blockIndex) indexBlock(blockIdxInfo *blockIdxInfo) error //索引区块//根据区块哈希,获取文件区块指针func (index *blockIndex) getBlockLocByHash(blockHash []byte)(*fileLocPointer, error)//根据区块编号,获取文件区块指针func (index *blockIndex) getBlockLocByBlockNum(blockNum uint64)(*fileLocPointer, error)//根据交易ID,获取文件交易指针func (index *blockIndex) getTxLoc(txID string) (*fileLocPointer, error) //根据交易ID,获取文件区块指针func (index *blockIndex) getBlockLocByTxID(txID string) (*fileLocPointer, error)//根据区块编号和交易编号,获取文件交易指针func (index *blockIndex) getTXLocByBlockNumTranNum(blockNum uint64, tranNum uint64) (*fileLocPointer, error)//根据交易ID,获取交易验证代码func (index *blockIndex) getTxValidationCodeByTxID(txID string)(peer.TxValidationCode, error)//代码在common/ledger/blkstorage/fsblkstorage/blockindex.go```补充blockIdxInfo结构体定义:块索引信息。

fabric项目源代码

fabric项目源代码

fabric项目源代码Fabric是一个区块链解决方案,它是一个模块化的、可拓展的、高效的平台,可以方便地部署和管理分布式网络。

Fabric的源代码是开源的,目前由Hyperledger项目管理,任何人都可以在Hyperledger的GitHub仓库中访问和使用它。

Fabric的代码结构非常清晰,其中包含了许多关键的组件和模块,例如peer节点、orderer节点、网络拓扑结构等。

Fabric基于模块化的结构设计,可以支持很多种不同的共识机制、加密算法、智能合约等,因此可以广泛应用于不同的场景。

Fabric代码的核心部分是它的智能合约。

智能合约是一组自动运行的规则,用于执行与交换一定价值相关的业务逻辑。

在Fabric中,智能合约是通过Chaincode实现的,可以通过基于golang的编译器编写。

Chaincode有两种类型,一种是System Chaincode,它是由Fabric提供的,包含了一些核心的功能,例如安全性、管理和查询等。

另一种是User Chaincode,它是由用户自己编写的,用于实现业务逻辑。

Fabric的交易流程是这样的:当用户发送一个交易请求时,交易请求会被广播给所有的peer节点。

当peer节点确认交易请求的有效性后,它会进行交易验证,并将交易请求发送给orderer节点。

orderer节点会将交易请求打包成交易块,并将其广播给所有peer节点。

peer节点会接受交易块,并验证交易是否正确。

如果交易被验证通过,peer节点会更新其状态数据库,并将交易结果返回给用户。

Fabric在将交易块传递给下一个peer节点时,采用了PBFT共识算法。

PBFT算法是一种拜占庭容错(BFT)算法,可以保证在不超过⅓的恶意节点的情况下,系统可以达成共识。

除了PBFT以外,Fabric还支持其他共识算法,例如Raft和Solo。

这些共识算法的选择取决于给定的场景和应用需求。

同时,Fabric还提供了灵活的身份和访问控制机制,可以在系统中实现不同级别的身份验证和授权。

兄弟连区块链教程Fabric1.0源代码分析Peer peer node start命令实现

兄弟连区块链教程Fabric1.0源代码分析Peer peer node start命令实现

兄弟连区块链教程Fabric1.0源代码分析Peer peer node start命令实现兄弟连区块链教程Fabric1.0源代码分析Peer peer node start命令实现,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。

但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# Fabric 1.0源代码笔记之 Peer #peer node start命令实现有个图2## 1、peer node加载子命令start和statuspeer node加载子命令start和status,代码如下:```gofunc Cmd() *mand {nodeCmd.AddCommand(startCmd()) //加载子命令startnodeCmd.AddCommand(statusCmd()) //加载子命令statusreturn nodeCmd}var nodeCmd = &mand{Use: nodeFuncName,Short: fmt.Sprint(shortDes),Long: fmt.Sprint(longDes),}//代码在peer/node/node.go```startCmd()代码如下:其中serve(args)为peer node start的实现代码,比较复杂,本文将重点讲解。

另statusCmd()代码与startCmd()相近,暂略。

```gofunc startCmd() *mand {flags := nodeStartCmd.Flags()flags.BoolVarP(&chaincodeDevMode, "peer-chaincodedev", "", false, "Whether peer in chaincode development mode")flags.BoolVarP(&peerDefaultChain, "peer-defaultchain", "", false, "Whether to start peer with chain testchainid")flags.StringVarP(&orderingEndpoint, "orderer", "o", "orderer:7050", "Ordering service endpoint") //ordererreturn nodeStartCmd}var nodeStartCmd = &mand{Use: "start",Short: "Starts the node.",Long: `Starts a node that interacts with the network.`,RunE: func(cmd *mand, args []string) error {return serve(args) //serve(args)为peer node start的实现代码},}//代码在peer/node/start.go```**注:如下内容均为serve(args)的代码,即peer node start命令执行流程。

兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令

兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令

兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令一兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。

但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# Fabric 1.0源代码笔记之 Peer #peer根命令入口及加载子命令## 1、加载环境变量配置和配置文件Fabric支持通过环境变量对部分配置进行更新,如:CORE_LOGGING_LEVEL为输出的日志级别、CORE_PEER_ID为Peer的ID等。

此部分功能由第三方包viper来实现,viper除支持环境变量的配置方式外,还支持配置文件方式。

viper使用方法参考:https:///spf13/viper。

如下代码为加载环境变量配置,其中cmdRoot为"core",即CORE_开头的环境变量。

```goviper.SetEnvPrefix(cmdRoot)viper.AutomaticEnv()replacer := strings.NewReplacer(".", "_")viper.SetEnvKeyReplacer(replacer)//代码在peer/main.go```加载配置文件,同样由第三方包viper来实现,具体代码如下:其中cmdRoot为"core",即/etc/hyperledger/fabric/core.yaml。

```goerr := common.InitConfig(cmdRoot)//代码在peer/main.go```如下代码为common.InitConfig(cmdRoot)的具体实现:```goconfig.InitViper(nil, cmdRoot)err := viper.ReadInConfig()//代码在peer/common/common.go```另附config.InitViper(nil, cmdRoot)的代码实现:优先从环境变量FABRIC_CFG_PATH中获取配置文件路径,其次为当前目录、开发环境目录(即:src//hyperledger/fabric/sampleconfig)、和OfficialPath(即:/etc/hyperledger/fabric)。

fabric 源码解析

fabric 源码解析

fabric 源码解析(实用版)目录1.引言2.fabric 概述3.fabric 源码结构4.fabric 的主要组件5.fabric 的核心功能6.结论正文【引言】本文将对 fabric 源码进行解析。

fabric 是一款高性能、轻量级的微服务框架,提供了服务注册、服务发现、负载均衡、熔断降级等功能。

通过解析 fabric 的源码,可以更好地理解其内部机制和实现方式。

【fabric 概述】fabric 是一款基于 Go 语言编写的微服务框架,提供了高性能、轻量级的服务注册、服务发现、负载均衡、熔断降级等功能。

fabric 支持多种服务发现方式,如 DNS 方式、HTTP 和 RPC 方式等。

同时,fabric 还提供了丰富的监控指标和日志功能,方便用户对服务进行监控和调试。

【fabric 源码结构】fabric 的源码结构如下所示:```fabric├── cmd│├── server│├── client│└── fabric│├── config│├── internal│├── apis│├── controllers │├── log│├── metrics│├── plugins│└── service│├── pkg│├── errors│├── util│└── services│├── scripts│├── static│└── version.go```其中,cmd 目录包含了 fabric 的命令行工具,config 目录包含了fabric 的配置文件,internal 目录包含了 fabric 的主要组件,pkg 目录包含了 fabric 的一些公共库,scripts 目录包含了 fabric 的一些脚本文件,static 目录包含了 fabric 的一些静态资源文件,version.go 文件包含了 fabric 的版本信息。

【fabric 的主要组件】fabric 的主要组件如下所示:1.服务注册中心:服务注册中心是 fabric 的核心组件之一,负责服务的注册和发现。

兄弟连区块链教程Fabric1.0源代码分析policy(背书策略)

兄弟连区块链教程Fabric1.0源代码分析policy(背书策略)

兄弟连区块链教程Fabric1.0源代码分析policy(背书策略)兄弟连区块链教程Fabric1.0源代码分析policy(背书策略),2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。

但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# Fabric 1.0源代码笔记之 policy(背书策略)## 1、policy概述policy代码分布在core/policy、core/policyprovider、common/policies目录下。

目录结构如下:* core/policy/policy.go,PolicyChecker接口定义及实现、PolicyCheckerFactory 接口定义。

* core/policyprovider/provider.go,PolicyChecker工厂默认实现。

* common/policies目录* policy.go,ChannelPolicyManagerGetter接口及实现。

* implicitmeta_util.go,通道策略工具函数。

## 2、PolicyChecker工厂### 2.1、PolicyCheckerFactory接口定义```gotype PolicyCheckerFactory interface {NewPolicyChecker() PolicyChecker //构造PolicyChecker实例}var pcFactory PolicyCheckerFactory //全局变量定义及赋值函数func RegisterPolicyCheckerFactory(f PolicyCheckerFactory) {pcFactory = f}//代码在core/policy/policy.go```### 2.2、PolicyCheckerFactory接口默认实现```gotype defaultFactory struct{}//构造policy.PolicyCheckerfunc (f *defaultFactory) NewPolicyChecker() policy.PolicyChecker {return policy.NewPolicyChecker(peer.NewChannelPolicyManagerGetter(),//&channelPolicyManagerGetter{}mgmt.GetLocalMSP(),mgmt.NewLocalMSPPrincipalGetter(),)}//获取policy.PolicyChecker,即调用policy.GetPolicyChecker()func GetPolicyChecker() policy.PolicyCheckerfunc init() { //初始化全局变量pcFactorypolicy.RegisterPolicyCheckerFactory(&defaultFactory{})}```## 3、PolicyChecker接口定义及实现### 3.1、PolicyChecker接口定义```gotype PolicyChecker interface {CheckPolicy(channelID, policyName string, signedProp*pb.SignedProposal) errorCheckPolicyBySignedData(channelID, policyName string, sd[]*common.SignedData) errorCheckPolicyNoChannel(policyName string, signedProp *pb.SignedProposal) error}//代码在core/policy/policy.go```### 3.2、PolicyChecker接口实现PolicyChecker接口实现,即policyChecker结构体及方法。

fabric 源码解析

fabric 源码解析

fabric 源码解析摘要:I.简介- 介绍fabric 项目- 阐述项目背景和意义II.fabric 源码结构解析- 整体架构概述- 主要模块及其功能介绍- orderer- peer- couchdb- configtx- gossip- protobuf- chaincodeIII.fabric 源码关键功能详解- orderer 模块- 共识算法实现- 消息广播机制- peer 模块- 节点通信与组网- 账本数据存储与同步- couchdb 模块- 数据存储与查询- 数据一致性保证- configtx 模块- 配置管理与更新- 网络参数设置- gossip 模块- 消息传播机制- 网络拓扑发现- protobuf 模块- 数据序列化与反序列化- 消息格式定义- chaincode 模块- 智能合约管理- 合约执行与调用IV.fabric 的应用与前景- 实际应用场景- 发展趋势与展望正文:I.简介Fabric 是一个由Hyperledger 项目组开发的分布式账本技术,它基于区块链技术,提供了一套完整的解决方案,包括共识算法、分布式账本、智能合约等关键功能。

Fabric 的源代码是开源的,这使得我们可以深入理解其技术实现细节,进一步挖掘其应用潜力。

本文将对Fabric 的源代码进行解析,帮助读者更好地了解其技术架构和关键功能。

II.fabric 源码结构解析Fabric 的源代码结构清晰,模块化程度高。

整体上,它分为orderer、peer、couchdb、configtx、gossip、protobuf 和chaincode 这几个主要模块。

- orderer 模块:负责共识算法的实现,主要包括了Fabric 的共识算法BFT 和RAFT。

此外,它还实现了消息广播机制,以保证区块的快速传播。

- peer 模块:负责节点通信与组网,以及账本数据存储与同步。

它包括了节点发现、网络连接管理、消息传递等功能。

兄弟连区块链教程Fabric1.0源代码分析配置交易-生成通道配置

兄弟连区块链教程Fabric1.0源代码分析配置交易-生成通道配置

兄弟连区块链教程Fabric1.0源代码分析配置jiaoyi-生成通道配置兄弟连区块链教程Fabric1.0源代码分析配置jiaoyi-生成通道配置,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。

但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# Fabric 1.0源代码笔记之 configtx(配置jiaoyi) #configtxgen(生成通道配置)## 1、configtxgen概述configtxgen,用于生成通道配置,具体有如下三种用法:* 生成Orderer服务启动的初始区块(即系统通道的创世区块文件)* configtxgen -profile TwoOrgsOrdererGenesis-outputBlock ./channel-artifacts/genesis.block* 生成新建应用通道的配置jiaoyi(即用于创建应用通道的配置jiaoyi文件)* configtxgen -profile TwoOrgsChannel-outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel* 生成锚节点配置更新文件* configtxgen -profile TwoOrgsChannel-outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx-channelID mychannel -asOrg Org1MSPconfigtxgen代码分布在common/configtx/tool目录,目录结构如下:* localconfig/config.go,configtx.yaml配置文件相关的结构体及方法。

## 2、configtx.yaml配置文件示例```bashProfiles:TwoOrgsOrdererGenesis: #Orderer系统通道配置Orderer:<<: *OrdererDefaults #引用OrdererDefaults并合并到当前Organizations: #属于Orderer通道的组织- *OrdererOrgConsortiums: #Orderer所服务的联盟列表SampleConsortium:Organizations:- *Org1- *Org2TwoOrgsChannel: #应用通道配置Consortium: SampleConsortium #应用通道关联的联盟Application:<<: *ApplicationDefaults #引用ApplicationDefaults并合并到当前 Organizations: #初始加入应用通道的组织- *Org1- *Org2Organizations:- &OrdererOrgName: OrdererOrgID: OrdererMSP # MSP IDMSPDir: crypto-config/ordererOrganizations//msp #MSP 相关文件本地路径- &Org1Name: Org1MSPID: Org1MSPMSPDir: crypto-config/peerOrganizations//mspAnchorPeers: #锚节点地址,用于跨组织的Gossip通信- Host: Port: 7051- &Org2Name: Org2MSPID: Org2MSPMSPDir: crypto-config/peerOrganizations//mspAnchorPeers: #锚节点地址,用于跨组织的Gossip通信- Host: Port: 7051Orderer: &OrdererDefaultsOrdererType: solo # Orderer共识插件类型,分solo或kafkaAddresses:- :7050 #服务地址BatchTimeout: 2s #创建批量jiaoyi的zui大超时,一批jiaoyi构成一个块BatchSize: #写入区块内的jiaoyi个数MaxMessageCount: 10 #一批消息的zui大个数AbsoluteMaxBytes: 98 MB #一批jiaoyi的zui大字节数,任何时候均不能超过PreferredMaxBytes: 512 KB #批量jiaoyi的建议字节数Kafka:Brokers: #Kafka端口- 127.0.0.1:9092Organizations: #参与维护Orderer的组织,默认空Application: &ApplicationDefaultsOrganizations: #加入到通道的组织信息,此处为不包括任何组织```配置文件解读:* 每个Profile表示某种场景下的通道配置模板,包括Orderer系统通道模板和应用通道模板,其中TwoOrgsOrdererGenesis为系统通道模板,TwoOrgsChannel为应用通道模板。

兄弟连区块链教程Fabric1.0源代码分析scc系统链码cscc通道相关

兄弟连区块链教程Fabric1.0源代码分析scc系统链码cscc通道相关

兄弟连区块链教程Fabric1.0源代码分析scc(系统链码)cscc(通道相关)兄弟连区块链教程Fabric1.0源代码分析scc(系统链码)cscc(通道相关),2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。

但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# Fabric 1.0源代码笔记之 scc(系统链码) #cscc(通道相关)## 1、cscc概述cscc代码在core/scc/cscc/configure.go。

## 2、PeerConfiger结构体```gotype PeerConfiger struct {policyChecker policy.PolicyChecker}//代码在core/scc/cscc/configure.go```## 3、Init方法```gofunc (e *PeerConfiger) Init(stub shim.ChaincodeStubInterface) pb.Response {//初始化策略检查器,用于访问控制e.policyChecker = policy.NewPolicyChecker(peer.NewChannelPolicyManagerGetter(),mgmt.GetLocalMSP(),mgmt.NewLocalMSPPrincipalGetter(),)return shim.Success(nil)}//代码在core/scc/cscc/configure.go```## 4、Invoke方法```gofunc (e *PeerConfiger) Invoke(stub shim.ChaincodeStubInterface)pb.Response {//args[0]为JoinChain或GetChannelsargs := stub.GetArgs()fname := string(args[0]) //Invoke functionsp, err := stub.GetSignedProposal() //获取SignedProposalswitch fname {case JoinChain: //加入通道//此处args[1]为创世区块block, err := utils.GetBlockFromBlockBytes(args[1])cid, err := utils.GetChainIDFromBlock(block)err := validateConfigBlock(block)err = e.policyChecker.CheckPolicyNoChannel(mgmt.Admins, sp) return joinChain(cid, block)case GetConfigBlock:err = e.policyChecker.CheckPolicy(string(args[1]),policies.ChannelApplicationReaders, sp)return getConfigBlock(args[1])case GetChannels:err = e.policyChecker.CheckPolicyNoChannel(mgmt.Members, sp) return getChannels()}}//代码在core/scc/cscc/configure.go```## 5、其他方法```go//校验创世区块func validateConfigBlock(block *common.Block) errorfunc joinChain(chainID string, block *common.Block) pb.Responsefunc getConfigBlock(chainID []byte) pb.Responsefunc getChannels() pb.Response//代码在core/scc/cscc/configure.go```### 5.1、joinChain```gofunc joinChain(chainID string, block *common.Block) pb.Response {err := peer.CreateChainFromBlock(block) //创建chainpeer.InitChain(chainID)err := producer.SendProducerBlockEvent(block)return shim.Success(nil)}//代码在core/scc/cscc/configure.go```#### 5.1.1、创建Chain(或channel)peer.CreateChainFromBlock(block)代码如下:```gofunc CreateChainFromBlock(cb *common.Block) error {cid, err := utils.GetChainIDFromBlock(cb) //获取ChainIDvar l ledger.PeerLedgerl, err = ledgermgmt.CreateLedger(cb) //创建Ledgerreturn createChain(cid, l, cb)}//代码在core/peer/peer.go```createChain(cid, l, cb)代码如下:```gofunc createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error {envelopeConfig, err := utils.ExtractEnvelope(cb, 0) //获取配置Envelope configtxInitializer := configtx.NewInitializer() //type initializer structgossipEventer := service.GetGossipService().NewConfigEventer() //获取gossipServiceInstancegossipCallbackWrapper := func(cm configtxapi.Manager) {ac, ok := configtxInitializer.ApplicationConfig()if !ok {// TODO, handle a missing ApplicationConfig more gracefully ac = nil}gossipEventer.ProcessConfigUpdate(&chainSupport{Manager: cm,Application: ac,})service.GetGossipService().SuspectPeers(func(identityapi.PeerIdentityType) bool {// TODO: this is a place-holder that would somehow make the MSP layer suspect// that a given certificate is revoked, or its intermediate CA is revoked.// In the meantime, before we have such an ability, we return true in order// to suspect ALL identities in order to validate all of them. return true})}trustedRootsCallbackWrapper := func(cm configtxapi.Manager) {updateTrustedRoots(cm)}configtxManager, err := configtx.NewManagerImpl(envelopeConfig,configtxInitializer,[]func(cm configtxapi.Manager){gossipCallbackWrapper, trustedRootsCallbackWrapper},)if err != nil {return err}// TODO remove once all references to mspmgmt are gone from peer code mspmgmt.XXXSetMSPManager(cid, configtxManager.MSPManager())ac, ok := configtxInitializer.ApplicationConfig()if !ok {ac = nil}cs := &chainSupport{Manager: configtxManager,Application: ac, // TODO, refactor as this is accessible through Managerledger: ledger,}c := committer.NewLedgerCommitterReactive(ledger,txvalidator.NewTxValidator(cs), func(block *common.Block) error {chainID, err := utils.GetChainIDFromBlock(block)if err != nil {return err}return SetCurrConfigBlock(block, chainID)})ordererAddresses :=configtxManager.ChannelConfig().OrdererAddresses()if len(ordererAddresses) == 0 {return errors.New("No ordering service endpoint provided in configuration block")}service.GetGossipService().InitializeChannel(cs.ChainID(), c, ordererAddresses)chains.Lock()defer chains.Unlock()chains.list[cid] = &chain{cs: cs,cb: cb,committer: c,}return nil}//代码在core/peer/peer.go```补充initializer:```gotype initializer struct {*resourcesppr *policyProposerRoot}//代码在common/configtx/initializer.go```感谢关注兄弟连区块链教程分享!。

兄弟连区块链技术培训Fabric 1.0源代码分析(30) Orderer BroadcastServer(Broadcast服务端)

兄弟连区块链技术培训Fabric 1.0源代码分析(30) Orderer BroadcastServer(Broadcast服务端)

兄弟连区块链技术培训Fabric 1.0源代码分析(30) Orderer BroadcastServer(Broadcast服务端)# Fabric 1.0源代码笔记之 Orderer #BroadcastServer(Broadcast服务端)## 1、BroadcastServer概述BroadcastServer相关代码在protos/orderer、orderer目录下。

protos/orderer/ab.pb.go,AtomicBroadcastServer接口定义。

orderer/server.go,go,AtomicBroadcastServer接口实现。

## 2、AtomicBroadcastServer接口定义### 2.1、AtomicBroadcastServer接口定义```gotype AtomicBroadcastServer interface {Broadcast(AtomicBroadcast_BroadcastServer) errorDeliver(AtomicBroadcast_DeliverServer) error}//代码在protos/orderer/ab.pb.go···### 2.2、gRPC相关实现```govar _AtomicBroadcast_serviceDesc = grpc.ServiceDesc{ServiceName: "orderer.AtomicBroadcast",HandlerType: (*AtomicBroadcastServer)(nil),Methods: []grpc.MethodDesc{},Streams: []grpc.StreamDesc{{StreamName: "Broadcast",Handler: _AtomicBroadcast_Broadcast_Handler,ServerStreams: true,ClientStreams: true,},{StreamName: "Deliver",Handler: _AtomicBroadcast_Deliver_Handler,ServerStreams: true,ClientStreams: true,},},Metadata: "orderer/ab.proto",}func RegisterAtomicBroadcastServer(s *grpc.Server, srv AtomicBroadcastSe rver) {s.RegisterService(&_AtomicBroadcast_serviceDesc, srv)}func _AtomicBroadcast_Broadcast_Handler(srv interface{}, stream grpc.Ser verStream) error {return srv.(AtomicBroadcastServer).Broadcast(&atomicBroadcastBroadca stServer{stream})}func _AtomicBroadcast_Deliver_Handler(srv interface{}, stream grpc.Serve rStream) error {return srv.(AtomicBroadcastServer).Deliver(&atomicBroadcastDeliverSe rver{stream})}//代码在protos/orderer/ab.pb.go```## 3、AtomicBroadcastServer接口实现### 3.1、server结构体server结构体:```gotype server struct {bh broadcast.Handlerdh deliver.Handler}type broadcastSupport struct {multichain.Managerbroadcast.ConfigUpdateProcessor}//代码在orderer/server.go```broadcast.Handler:```gotype Handler interface {Handle(srv ab.AtomicBroadcast_BroadcastServer) error }type handlerImpl struct {sm SupportManager}func NewHandlerImpl(sm SupportManager) Handler {return &handlerImpl{sm: sm,}}type SupportManager interface {ConfigUpdateProcessorGetChain(chainID string) (Support, bool)}type ConfigUpdateProcessor interface { //处理通道配置更新Process(envConfigUpdate *cb.Envelope) (*cb.Envelope, error)}//代码在orderer/common/broadcast/broadcast.go```deliver.Handler:```gotype Handler interface {Handle(srv ab.AtomicBroadcast_DeliverServer) error}type deliverServer struct {sm SupportManager}type SupportManager interface {GetChain(chainID string) (Support, bool)}//代码在orderer/common/deliver/deliver.go```### 3.2、server结构体相关方法```go//构建server结构体func NewServer(ml multichain.Manager, signer crypto.LocalSigner) ab.Atom icBroadcastServer//s.bh.Handle(srv)func (s *server) Broadcast(srv ab.AtomicBroadcast_BroadcastServer) error //s.dh.Handle(srv)func (s *server) Deliver(srv ab.AtomicBroadcast_DeliverServer) error//代码在orderer/server.go```func NewServer(ml multichain.Manager, signer crypto.LocalSigner) ab.Atom icBroadcastServer代码如下:```gofunc NewServer(ml multichain.Manager, signer crypto.LocalSigner) ab.Atom icBroadcastServer {s := &server{dh: deliver.NewHandlerImpl(deliverSupport{Manager: ml}),bh: broadcast.NewHandlerImpl(broadcastSupport{Manager: ml,ConfigUpdateProcessor: configupdate.New(ml.SystemChannelID(), configUpdateSupport{Manager: ml}, signer),}),}return s}//代码在orderer/server.go```### 3.3、Broadcast服务端Broadcast处理流程Broadcast服务端Broadcast处理流程,即broadcast.handlerImpl.Handle方法。

兄弟连区块链教程Fabric1.0源代码分析MSP成员关系服务提供者二

兄弟连区块链教程Fabric1.0源代码分析MSP成员关系服务提供者二

兄弟连区块链教程Fabric1.0源代码分析MSP成员关系服务提供者二兄弟连区块链教程Fabric1.0源代码分析MSP成员关系服务提供者二。

## 3、MSP接口实现MSP接口实现,即bccspmsp结构体及方法,bccspmsp定义如下:```gotype bccspmsp struct {rootCerts []Identity //信任的CA证书列表intermediateCerts []Identity //信任的中间证书列表tlsRootCerts [][]byte //信任的CA TLS 证书列表tlsIntermediateCerts [][]byte //信任的中间TLS 证书列表certificationTreeInternalNodesMap map[string]bool //待定signer SigningIdentity //签名身份admins []Identity //管理身份列表bccsp bccsp.BCCSP //加密服务提供者name string //MSP名字opts *x509.VerifyOptions //MSP成员验证选项CRL []*pkix.CertificateList //证书吊销列表ouIdentifiers map[string][][]byte //组织列表cryptoConfig *m.FabricCryptoConfig //加密选项}//代码在msp/mspimpl.go```涉及方法如下:```gofunc NewBccspMsp() (MSP, error) //创建bccsp实例,以及创建并初始化bccspmsp 实例func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error ////根据MSPConfig设置MSP实例func (msp *bccspmsp) GetType() ProviderType //获取MSP类型,即FABRICfunc (msp *bccspmsp) GetIdentifier() (string, error) //获取MSP名字func (msp *bccspmsp) GetTLSRootCerts() [][]byte //获取信任的CA TLS 证书列表msp.tlsRootCertsfunc (msp *bccspmsp) GetTLSIntermediateCerts() [][]byte //获取信任的中间TLS 证书列表msp.tlsIntermediateCertsfunc (msp *bccspmsp) GetDefaultSigningIdentity() (SigningIdentity, error) ////获取默认的签名身份msp.signerfunc (msp *bccspmsp) GetSigningIdentity(identifier *IdentityIdentifier) (SigningIdentity, error) //暂未实现,可忽略func (msp *bccspmsp) Validate(id Identity) error //校验身份是否有效,调取msp.validateIdentity(id)实现func (msp *bccspmsp) DeserializeIdentity(serializedID []byte) (Identity, error) //身份反序列化func (msp *bccspmsp) SatisfiesPrincipal(id Identity, principal*m.MSPPrincipal) error //验证给定的身份与principal中所描述的类型是否相匹配//代码在msp/mspimpl.go```func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error代码如下:```goconf := &m.FabricMSPConfig{}err := proto.Unmarshal(conf1.Config, conf) //将conf1.Config []byte解码为FabricMSPConfig = err := msp.setupCrypto(conf) //设置加密选项msp.cryptoConfigerr := msp.setupCAs(conf) //设置MSP成员验证选项msp.opts,并添加信任的CA证书msp.rootCerts和信任的中间证书msp.intermediateCertserr := msp.setupAdmins(conf) //设置管理身份列表msp.adminserr := msp.setupCRLs(conf) //设置证书吊销列表msp.CRLerr := msp.finalizeSetupCAs(conf); err != nil //设置msp.certificationTreeInternalNodesMaperr := msp.setupSigningIdentity(conf) //设置签名身份msp.signererr := msp.setupOUs(conf) //设置组织列表msp.ouIdentifierserr := msp.setupTLSCAs(conf) //设置并添加信任的CA TLS 证书列表msp.tlsRootCerts,以及信任的CA TLS 证书列表msp.tlsIntermediateCertsfor i, admin := range msp.admins {err = admin.Validate() //确保管理员是有效的成员}//代码在msp/mspimpl.go```func (msp *bccspmsp) validateIdentity(id *identity)代码如下:```govalidationChain, err := msp.getCertificationChainForBCCSPIdentity(id) //获取BCCSP身份认证链err = msp.validateIdentityAgainstChain(id, validationChain) //根据链验证身份err = msp.validateIdentityOUs(id) //验证身份中所携带的组织信息有效//代码在msp/mspimpl.go```## 4、MSPManager接口实现结构体定义:```gotype mspManagerImpl struct {mspsMap map[string]MSP //MSP的映射up bool //是否正常启用}//代码在msp/mspmgrimpl.go```方法:```gofunc NewMSPManager() MSPManager //创建mspManagerImpl实例func (mgr *mspManagerImpl) Setup(msps []MSP) error //将msps装入mgr.mspsMap func (mgr *mspManagerImpl) GetMSPs() (map[string]MSP, error) //获取mgr.mspsMapfunc (mgr *mspManagerImpl) DeserializeIdentity(serializedID []byte) (Identity, error) //调用msp.DeserializeIdentity()实现身份反序列化//代码在msp/mspmgrimpl.go```## 5、Identity、SigningIdentity接口实现identity结构体定义(身份):```gotype identity struct {id *IdentityIdentifier //身份标识符(含Mspid和Id,均为string)cert *x509.Certificate //代表身份的x509证书pk bccsp.Key //身份公钥msp *bccspmsp //拥有此实例的MSP实例}//代码在msp/identities.go```补充IdentityIdentifier结构体定义(身份标识符):```gotype IdentityIdentifier struct {Mspid string //Msp idId string //Id}//代码在msp/msp.go```identity结构体涉及方法如下:```gofunc newIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, msp *bccspmsp) (Identity, error) //创建identity实例func NewSerializedIdentity(mspID string, certPEM []byte) ([]byte, error) //新建身份SerializedIdentity并序列化func (id *identity) SatisfiesPrincipal(principal *msp.MSPPrincipal) error //调用msp的SatisfiesPrincipal检查身份与principal中所描述的类型是否匹配func (id *identity) GetIdentifier() *IdentityIdentifier //获取id.idfunc (id *identity) GetMSPIdentifier() string //获取id.id.Mspidfunc (id *identity) Validate() error //调取id.msp.Validate(id)校验身份是否有效func (id *identity) GetOrganizationalUnits() []*OUIdentifier //获取组织单元func (id *identity) Verify(msg []byte, sig []byte) error //用这个身份校验消息签名func (id *identity) Serialize() ([]byte, error)//身份序列化func (id *identity) getHashOpt(hashFamily string) (bccsp.HashOpts, error) //调取bccsp.GetHashOpt//代码在msp/identities.go```signingidentity结构体定义(签名身份):```gotype signingidentity struct {identity //嵌入identitysigner crypto.Signer //crypto标准库中Signer接口}//代码在msp/identities.go```signingidentity结构体涉及方法如下:```go//新建signingidentity实例func newSigningIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, signer crypto.Signer, msp *bccspmsp) (SigningIdentity, error) func (id *signingidentity) Sign(msg []byte) ([]byte, error) //签名msg func (id *signingidentity) GetPublicVersion() Identity //获取id.identity //代码在msp/identities.go```## 6、MSPConfig相关结构体及方法MSPConfig相关结构体定义:FabricMSPConfig定义与bccspmsp接近,FabricMSPConfig序列化后以[]byte存入MSPConfig.Config中。

fabric项目源代码

fabric项目源代码

Fabric项目源代码1. 介绍Fabric项目是一个开源的区块链解决方案,旨在帮助企业构建高性能、高可信度的分布式应用程序。

它提供了一个模块化的体系结构,允许用户自定义区块链网络和智能合约,并提供了丰富的开发工具和SDK,以便开发者能够快速构建和部署自己的区块链应用。

2. 架构设计Fabric项目的架构设计非常灵活和模块化,可以根据具体的业务需求进行定制。

它主要由以下几个组件组成:2.1 区块链网络区块链网络是Fabric项目的核心组件,它由一组分布式节点组成,这些节点可以是不同的组织或参与方。

区块链网络采用了“拜占庭容错”(BFT)一致性算法,确保网络中的节点能够达成共识,保证数据的一致性和安全性。

同时,区块链网络还支持多链并行操作,不同的链可以处理不同的业务逻辑。

2.2 智能合约智能合约是Fabric项目中的核心概念,它实现了业务逻辑的自动化执行和数据的可信共享。

Fabric项目支持智能合约的编写和部署,开发者可以使用多种编程语言(如Golang、Java等)来实现自己的智能合约。

同时,Fabric项目还提供了一系列的合约开发工具和框架,帮助开发者更快地构建和测试自己的智能合约。

2.3 身份认证与访问控制Fabric项目提供了丰富的身份认证和访问控制机制,确保区块链网络中的参与者具有合法的身份,并且只有经过授权的用户才能够访问和操作区块链数据。

Fabric 项目采用了“成员服务提供者”(MSP)的模式,每个组织都可以通过MSP注册和管理自己的用户身份,同时还支持角色和权限管理,以实现精细化的访问控制。

2.4 交易处理Fabric项目中的交易处理是通过“链码”(Chaincode)来实现的,链码类似于传统应用程序中的“函数”或“方法”,可以实现业务逻辑的自动化执行。

每个链码都运行在一个独立的容器中,它可以读取和写入区块链中的状态数据,并按照预设的规则进行数据验证和操作。

Fabric项目支持链码的升级和迁移,以应对业务需求的变化。

兄弟连区块链教程Fabric1.0源代码分析gRPC Fabric中注册的gRPC Service二

兄弟连区块链教程Fabric1.0源代码分析gRPC Fabric中注册的gRPC Service二

兄弟连区块链教程Fabric1.0源代码分析gRPC(Fabric中注册的gRPC Service)二兄弟连区块链教程Fabric1.0源代码分析gRPC(Fabric中注册的gRPC Service)二。

### 1.3、Endorser Service(背书服务)#### 1.3.1、Endorser Service客户端```gotype EndorserClient interface {ProcessProposal(ctx context.Context, in *SignedProposal,opts ...grpc.CallOption) (*ProposalResponse, error)}type endorserClient struct {cc *grpc.ClientConn}func NewEndorserClient(cc *grpc.ClientConn) EndorserClient {return &endorserClient{cc}}func (c *endorserClient) ProcessProposal(ctx context.Context, in*SignedProposal, opts ...grpc.CallOption) (*ProposalResponse, error) {out := new(ProposalResponse)err := grpc.Invoke(ctx, "/protos.Endorser/ProcessProposal", in, out, , opts...)if err != nil {return nil, err}return out, nil}//代码在protos/peer/peer.pb.go```#### 1.3.2、Endorser Service服务端```gotype EndorserServer interface {ProcessProposal(context.Context, *SignedProposal) (*ProposalResponse, error)}func RegisterEndorserServer(s *grpc.Server, srv EndorserServer) {s.RegisterService(&_Endorser_serviceDesc, srv)}func _Endorser_ProcessProposal_Handler(srv interface{}, ctxcontext.Context, dec func(interface{}) error, interceptorgrpc.UnaryServerInterceptor) (interface{}, error) {in := new(SignedProposal)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(EndorserServer).ProcessProposal(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Endorser/ProcessProposal",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(EndorserServer).ProcessProposal(ctx,req.(*SignedProposal))}return interceptor(ctx, in, info, handler)}var _Endorser_serviceDesc = grpc.ServiceDesc{ServiceName: "protos.Endorser",HandlerType: (*EndorserServer)(nil),Methods: []grpc.MethodDesc{{MethodName: "ProcessProposal",Handler: _Endorser_ProcessProposal_Handler,},},Streams: []grpc.StreamDesc{},Metadata: "peer/peer.proto",}//代码在protos/peer/peer.pb.go```### 1.4、ChaincodeSupport Service(链码支持服务)#### 1.4.1、ChaincodeSupport Service客户端```gotype ChaincodeSupportClient interface {Register(ctx context.Context, opts ...grpc.CallOption) (ChaincodeSupport_RegisterClient, error)}type chaincodeSupportClient struct {cc *grpc.ClientConn}func NewChaincodeSupportClient(cc *grpc.ClientConn) ChaincodeSupportClient {return &chaincodeSupportClient{cc}}func (c *chaincodeSupportClient) Register(ctx context.Context,opts ...grpc.CallOption) (ChaincodeSupport_RegisterClient, error) { stream, err := grpc.NewClientStream(ctx,&_ChaincodeSupport_serviceDesc.Streams[0], ,"/protos.ChaincodeSupport/Register", opts...)if err != nil {return nil, err}x := &chaincodeSupportRegisterClient{stream}return x, nil}//代码在protos/peer/peer.pb.go```#### 1.4.2、ChaincodeSupport Service服务端```gotype ChaincodeSupportServer interface {Register(ChaincodeSupport_RegisterServer) error}func RegisterChaincodeSupportServer(s *grpc.Server, srv ChaincodeSupportServer) {s.RegisterService(&_ChaincodeSupport_serviceDesc, srv)}func _ChaincodeSupport_Register_Handler(srv interface{}, streamgrpc.ServerStream) error {returnsrv.(ChaincodeSupportServer).Register(&chaincodeSupportRegisterServer{s tream})}var _ChaincodeSupport_serviceDesc = grpc.ServiceDesc{ServiceName: "protos.ChaincodeSupport",HandlerType: (*ChaincodeSupportServer)(nil),Methods: []grpc.MethodDesc{},Streams: []grpc.StreamDesc{{StreamName: "Register",Handler: _ChaincodeSupport_Register_Handler,ServerStreams: true,ClientStreams: true,},},Metadata: "peer/chaincode_shim.proto",}//代码在protos/peer/peer.pb.go```### 1.5、Gossip Service(Gossip服务)#### 1.5.1、Gossip Service客户端```gotype GossipClient interface {// GossipStream is the gRPC stream used for sending and receiving messagesGossipStream(ctx context.Context, opts ...grpc.CallOption)(Gossip_GossipStreamClient, error)// Ping is used to probe a remote peer's alivenessPing(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)}type gossipClient struct {cc *grpc.ClientConn}func NewGossipClient(cc *grpc.ClientConn) GossipClient {return &gossipClient{cc}}func (c *gossipClient) GossipStream(ctx context.Context,opts ...grpc.CallOption) (Gossip_GossipStreamClient, error) {stream, err := grpc.NewClientStream(ctx,&_Gossip_serviceDesc.Streams[0], , "/gossip.Gossip/GossipStream", opts...)if err != nil {return nil, err}x := &gossipGossipStreamClient{stream}return x, nil}type Gossip_GossipStreamClient interface {Send(*Envelope) errorRecv() (*Envelope, error)grpc.ClientStream}type gossipGossipStreamClient struct {grpc.ClientStream}func (x *gossipGossipStreamClient) Send(m *Envelope) error {return x.ClientStream.SendMsg(m)}func (x *gossipGossipStreamClient) Recv() (*Envelope, error) {m := new(Envelope)if err := x.ClientStream.RecvMsg(m); err != nil {return nil, err}return m, nil}func (c *gossipClient) Ping(ctx context.Context, in *Empty,opts ...grpc.CallOption) (*Empty, error) {out := new(Empty)err := grpc.Invoke(ctx, "/gossip.Gossip/Ping", in, out, , opts...) if err != nil {return nil, err}return out, nil}//代码在protos/gossip/message.pb.go```#### 1.5.2、Gossip Serviced服务端```gotype GossipServer interface {// GossipStream is the gRPC stream used for sending and receiving messagesGossipStream(Gossip_GossipStreamServer) error// Ping is used to probe a remote peer's alivenessPing(context.Context, *Empty) (*Empty, error)}func RegisterGossipServer(s *grpc.Server, srv GossipServer) {s.RegisterService(&_Gossip_serviceDesc, srv)}func _Gossip_GossipStream_Handler(srv interface{}, streamgrpc.ServerStream) error {returnsrv.(GossipServer).GossipStream(&gossipGossipStreamServer{stream})}type Gossip_GossipStreamServer interface {Send(*Envelope) errorRecv() (*Envelope, error)grpc.ServerStream}type gossipGossipStreamServer struct {grpc.ServerStream}func (x *gossipGossipStreamServer) Send(m *Envelope) error {return x.ServerStream.SendMsg(m)}func (x *gossipGossipStreamServer) Recv() (*Envelope, error) {m := new(Envelope)if err := x.ServerStream.RecvMsg(m); err != nil {return nil, err}return m, nil}func _Gossip_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {in := new(Empty)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(GossipServer).Ping(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/gossip.Gossip/Ping",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(GossipServer).Ping(ctx, req.(*Empty))}return interceptor(ctx, in, info, handler)}var _Gossip_serviceDesc = grpc.ServiceDesc{ServiceName: "gossip.Gossip",HandlerType: (*GossipServer)(nil),Methods: []grpc.MethodDesc{{MethodName: "Ping",Handler: _Gossip_Ping_Handler,},},Streams: []grpc.StreamDesc{{StreamName: "GossipStream",Handler: _Gossip_GossipStream_Handler,ServerStreams: true,ClientStreams: true,},},Metadata: "gossip/message.proto",}//代码在protos/gossip/message.pb.go```## 2、Orderer节点中注册的gRPC Service### 2.1、AtomicBroadcast Service(广播服务)#### 2.1.1、AtomicBroadcast Service客户端```gotype AtomicBroadcastClient interface {// broadcast receives a reply of Acknowledgement for eachcommon.Envelope in order, indicating success or type of failureBroadcast(ctx context.Context, opts ...grpc.CallOption) (AtomicBroadcast_BroadcastClient, error)// deliver first requires an Envelope of type DELIVER_SEEK_INFO with Payload data as a mashaled SeekInfo message, then a stream of block replies is received.Deliver(ctx context.Context, opts ...grpc.CallOption) (AtomicBroadcast_DeliverClient, error)}type atomicBroadcastClient struct {cc *grpc.ClientConn}func NewAtomicBroadcastClient(cc *grpc.ClientConn) AtomicBroadcastClient {return &atomicBroadcastClient{cc}}func (c *atomicBroadcastClient) Broadcast(ctx context.Context,opts ...grpc.CallOption) (AtomicBroadcast_BroadcastClient, error) {stream, err := grpc.NewClientStream(ctx,&_AtomicBroadcast_serviceDesc.Streams[0], ,"/orderer.AtomicBroadcast/Broadcast", opts...)if err != nil {return nil, err}x := &atomicBroadcastBroadcastClient{stream}return x, nil}func (c *atomicBroadcastClient) Deliver(ctx context.Context,opts ...grpc.CallOption) (AtomicBroadcast_DeliverClient, error) {stream, err := grpc.NewClientStream(ctx,&_AtomicBroadcast_serviceDesc.Streams[1], ,"/orderer.AtomicBroadcast/Deliver", opts...)if err != nil {return nil, err}x := &atomicBroadcastDeliverClient{stream}return x, nil}//代码在protos/orderer/ab.pb.go```#### 2.1.2、AtomicBroadcast Service服务端```gotype AtomicBroadcastServer interface {// broadcast receives a reply of Acknowledgement for eachcommon.Envelope in order, indicating success or type of failureBroadcast(AtomicBroadcast_BroadcastServer) error// deliver first requires an Envelope of type DELIVER_SEEK_INFO with Payload data as a mashaled SeekInfo message, then a stream of block replies is received.Deliver(AtomicBroadcast_DeliverServer) error}func RegisterAtomicBroadcastServer(s *grpc.Server, srv AtomicBroadcastServer) {s.RegisterService(&_AtomicBroadcast_serviceDesc, srv)}func _AtomicBroadcast_Broadcast_Handler(srv interface{}, streamgrpc.ServerStream) error {returnsrv.(AtomicBroadcastServer).Broadcast(&atomicBroadcastBroadcastServer{s tream})}func _AtomicBroadcast_Deliver_Handler(srv interface{}, streamgrpc.ServerStream) error {returnsrv.(AtomicBroadcastServer).Deliver(&atomicBroadcastDeliverServer{strea m})}var _AtomicBroadcast_serviceDesc = grpc.ServiceDesc{ServiceName: "orderer.AtomicBroadcast",HandlerType: (*AtomicBroadcastServer)(nil),Methods: []grpc.MethodDesc{},Streams: []grpc.StreamDesc{{StreamName: "Broadcast",Handler: _AtomicBroadcast_Broadcast_Handler,ServerStreams: true,ClientStreams: true,},{StreamName: "Deliver",Handler: _AtomicBroadcast_Deliver_Handler,ServerStreams: true,ClientStreams: true,},},Metadata: "orderer/ab.proto",}//代码在protos/orderer/ab.pb.go```感谢关注兄弟连区块链教程分享!。

兄弟连区块链技术培训Fabric 1.0源代码分析(31) Peer

兄弟连区块链技术培训Fabric 1.0源代码分析(31) Peer

兄弟连区块链技术培训Fabric 1.0源代码分析(31) Peer# Fabric 1.0源代码笔记之 Peer## 1、Peer概述在Fabric中,Peer(节点)是指在网络中负责接收交易请求、维护一致账本的各个fabr ic-peer实例。

节点之间彼此通过gRPC通信。

按角色划分,Peer包括两种类型:* Endorser(背书者):负责对来自客户端的交易提案进行检查和背书。

* Committer(提交者):负责检查交易请求,执行交易并维护区块链和账本结构。

Peer核心代码在peer目录下,其他相关代码分布在core/peer和protos/peer目录下。

目录结构如下:* peer目录:* main.go,peer命令入口。

* node目录,peer node命令及子命令peer node start和peer node status实现。

* node.go,peer node命令入口。

* start.go,peer node start子命令实现。

* status.go,peer node status子命令实现。

* channel目录,peer channel命令及子命令实现。

* chaincode目录,peer chaincode命令及子命令实现。

* clilogging目录,peer clilogging命令及子命令实现。

* version目录,peer version命令实现。

* common目录,peer相关通用代码。

* common.go,部分公共函数。

* ordererclient.go,BroadcastClient接口及实现。

* gossip目录,gossip最终一致性算法相关代码。

* core/peer目录:* config.go,Peer配置相关工具函数。

* peer.go,Peer服务相关工具函数。

* core/endorser目录:背书服务端。

如下为分节说明Peer代码:* [Fabric 1.0源代码笔记之 Peer #peer根命令入口及加载子命令](peer_main.md) * [Fabric 1.0源代码笔记之 Peer #peer node start命令实现](peer_node_start. md)* [Fabric 1.0源代码笔记之 Peer #peer channel命令及子命令实现](peer_chann el.md)* [Fabric 1.0源代码笔记之 Peer #peer chaincode命令及子命令实现](peer_cha incode.md)* [Fabric 1.0源代码笔记之 Peer #EndorserClient(Endorser客户端)](Endors erClient.md)* [Fabric 1.0源代码笔记之 Peer #EndorserServer(Endorser服务端)](Endors erServer.md)* [Fabric 1.0源代码笔记之 Peer #BroadcastClient(Broadcast客户端)](Broa dcastClient.md)* [Fabric 1.0源代码笔记之 Peer #committer(提交者)](committer.md)## 2、Peer配置相关工具函数```go//为全局变量localAddress和peerEndpoint赋值func CacheConfiguration() (err error)func cacheConfiguration() //调用CacheConfiguration()//获取localAddressfunc GetLocalAddress() (string, error)//获取peerEndpointfunc GetPeerEndpoint() (*pb.PeerEndpoint, error)//获取Peer安全配置func GetSecureConfig() (comm.SecureServerConfig, error)//代码在core/peer/config.go```PeerEndpoint结构体定义如下:```gotype PeerID struct {Name string}type PeerEndpoint struct {Id *PeerIDAddress string}//代码在protos/peer/peer.pb.go```SecureServerConfig结构体定义如下:```gotype SecureServerConfig struct {ServerCertificate []byte //签名公钥,取自peer.tls.cert.fileServerKey []byte //签名私钥,取自peer.tls.key.fileServerRootCAs [][]byte //根CA证书,取自peer.tls.rootcert.fileClientRootCAs [][]byteUseTLS bool //是否启用TLS,取自peer.tls.enabledRequireClientCert bool}//代码在core/comm/server.go```## 3、Peer服务相关工具函数```gofunc (cs *chainSupport) Ledger() ledger.PeerLedgerfunc (cs *chainSupport) GetMSPIDs(cid string) []stringfunc MockInitialize()func MockSetMSPIDGetter(mspIDGetter func(string) []string)func Initialize(init func(string)) //Peer初始化,并部署系统链码func InitChain(cid string)func getCurrConfigBlockFromLedger(ledger ledger.PeerLedger) (*common.Bl ock, error)func createChain(cid string, ledger ledger.PeerLedger, cb *common.Bloc k) errorfunc CreateChainFromBlock(cb *common.Block) errorfunc MockCreateChain(cid string) errorfunc GetLedger(cid string) ledger.PeerLedgerfunc GetPolicyManager(cid string) policies.Managerfunc GetCurrConfigBlock(cid string) *common.Blockfunc updateTrustedRoots(cm configtxapi.Manager)func buildTrustedRootsForChain(cm configtxapi.Manager)func GetMSPIDs(cid string) []stringfunc SetCurrConfigBlock(block *common.Block, cid string) errorfunc NewPeerClientConnection() (*grpc.ClientConn, error)func GetLocalIP() stringfunc NewPeerClientConnectionWithAddress(peerAddress string) (*grpc.Clie ntConn, error)func GetChannelsInfo() []*pb.ChannelInfo//构造type channelPolicyManagerGetter struct{}func NewChannelPolicyManagerGetter() policies.ChannelPolicyManagerGette rfunc (c *channelPolicyManagerGetter) Manager(channelID string) (policie s.Manager, bool)func CreatePeerServer(listenAddress string,secureConfig comm.SecureServ erConfig) (comm.GRPCServer, error)func GetPeerServer() comm.GRPCServer//代码在core/peer/peer.go。

兄弟连区块链技术培训Fabric 1.0源代码分析(34) Peer #peer chaincode命令及子命令实现

兄弟连区块链技术培训Fabric 1.0源代码分析(34) Peer #peer chaincode命令及子命令实现

兄弟连区块链技术培训Fabric 1.0源代码分析(34) Peer #peer cha incode命令及子命令实现# Fabric 1.0源代码笔记之 Peer #peer chaincode命令及子命令实现## 1、peer chaincode install子命令实现(安装链码)### 1.0、peer chaincode install子命令概述peer chaincode install,将链码的源码和环境封装为一个链码安装打包文件,并传输到背书节点。

peer chaincode install支持如下两种方式:* 指定代码方式,peer chaincode install -n <链码名称> -v <链码版本> -p <链码路径>* 基于链码打包文件方式,peer chaincode install <链码打包文件>### 1.1、初始化Endorser客户端```gocf, err = InitCmdFactory(true, false)//代码在peer/chaincode/install.go```cf, err = InitCmdFactory(true, false)代码如下:```gofunc InitCmdFactory(isEndorserRequired, isOrdererRequired bool) (*Chainc odeCmdFactory, error) {var err errorvar endorserClient pb.EndorserClientif isEndorserRequired {//获取Endorser客户端endorserClient, err = common.GetEndorserClientFnc() //func GetEn dorserClient() (pb.EndorserClient, error)}//获取签名signer, err := common.GetDefaultSignerFnc()var broadcastClient common.BroadcastClientif isOrdererRequired {//此处未用到,暂略}//构造ChaincodeCmdFactoryreturn &ChaincodeCmdFactory{EndorserClient: endorserClient,Signer: signer,BroadcastClient: broadcastClient,}, nil}//代码在peer/chaincode/common.go```### 1.2、构造ChaincodeDeploymentSpec消息(链码信息及链码文件打包)```goif ccpackfile == "" { //指定代码方式,重新构造构造ChaincodeDeploymentSpec 消息ccpackmsg, err = genChaincodeDeploymentSpec(cmd, chaincodeName, chai ncodeVersion)} else { //基于链码打包文件方式,直接读取ChaincodeDeploymentSpec消息var cds *pb.ChaincodeDeploymentSpecccpackmsg, cds, err = getPackageFromFile(ccpackfile)}//代码在peer/chaincode/install.go```ccpackmsg, err = genChaincodeDeploymentSpec(cmd, chaincodeName, chaincod eVersion)代码如下:```gofunc genChaincodeDeploymentSpec(cmd *mand, chaincodeName, chain codeVersion string) (*pb.ChaincodeDeploymentSpec, error) {//已经存在,直接报错if existed, _ := ccprovider.ChaincodePackageExists(chaincodeName, ch aincodeVersion); existed {return nil, fmt.Errorf("chaincode %s:%s already exists", chainco deName, chaincodeVersion)}spec, err := getChaincodeSpec(cmd)cds, err := getChaincodeDeploymentSpec(spec, true)return cds, nil}//代码在peer/chaincode/install.go```spec, err := getChaincodeSpec(cmd)代码如下:```gofunc getChaincodeSpec(cmd *mand) (*pb.ChaincodeSpec, error) { spec := &pb.ChaincodeSpec{}err := checkChaincodeCmdParams(cmd) //检查参数合法性input := &pb.ChaincodeInput{}//flags.StringVarP(&chaincodeCtorJSON, "ctor", "c", "{}",ctor为链码具体执行参数信息,默认为{}err := json.Unmarshal([]byte(chaincodeCtorJSON), &input)//flags.StringVarP(&chaincodeLang, "lang", "l", "golang",lang为链码的编写语言,默认为golangchaincodeLang = strings.ToUpper(chaincodeLang)spec = &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincod eLang]),ChaincodeId: &pb.ChaincodeID{Path: chaincodePath, Name: chaincod eName, Version: chaincodeVersion},Input: input,}return spec, nil}//代码在peer/chaincode/common.go```cds, err := getChaincodeDeploymentSpec(spec, true)代码如下:```gofunc getChaincodeDeploymentSpec(spec *pb.ChaincodeSpec, crtPkg bool) (*p b.ChaincodeDeploymentSpec, error) {var codePackageBytes []byteif chaincode.IsDevMode() == false && crtPkg {var err errorerr = checkSpec(spec) //检查spec合法性codePackageBytes, err = container.GetChaincodePackageBytes(spe c) //打包链码文件及依赖文件}//构造ChaincodeDeploymentSpecchaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes}return chaincodeDeploymentSpec, nil//代码在peer/chaincode/common.go```### 1.3、创建lscc Proposal并签名```gocreator, err := cf.Signer.Serialize() //获取签名者//按ChaincodeDeploymentSpec构造Proposal,即链码ChaincodeDeploymentSpec消息作为参数传递给lscc系统链码并调用//调用createProposalFromCDS(chainID, cds, creator, policy, escc, vscc, " deploy")prop, _, err := utils.CreateInstallProposalFromCDS(msg, creator)var signedProp *pb.SignedProposalsignedProp, err = utils.GetSignedProposal(prop, cf.Signer) //签名提案//代码在peer/chaincode/install.go```createProposalFromCDS(chainID, cds, creator, policy, escc, vscc, "deploy ")代码如下:```gofunc createProposalFromCDS(chainID string, msg proto.Message, creator [] byte, policy []byte, escc []byte, vscc []byte, propType string) (*peer.P roposal, string, error) {var ccinp *peer.ChaincodeInputvar b []bytevar err errorb, err = proto.Marshal(msg)switch propType {case "deploy":fallthroughcase "upgrade":cds, ok := msg.(*peer.ChaincodeDeploymentSpec)ccinp = &peer.ChaincodeInput{Args: [][]byte{[]byte(propType), [] byte(chainID), b, policy, escc, vscc}}case "install":ccinp = &peer.ChaincodeInput{Args: [][]byte{[]byte(propType), b}}}lsccSpec := &peer.ChaincodeInvocationSpec{ //构造lscc ChaincodeInvoc ationSpecChaincodeSpec: &peer.ChaincodeSpec{Type: peer.ChaincodeSpec_GOLANG,ChaincodeId: &peer.ChaincodeID{Name: "lscc"},Input: ccinp}}return CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, chainID, lsccSpec, creator)}//代码在protos/utils/proputils.go```### 1.4、提交并处理Proposal```goproposalResponse, err := cf.EndorserClient.ProcessProposal(context.Backg round(), signedProp)//代码在peer/chaincode/install.go```## 2、peer chaincode instantiate子命令实现(实例化链码)### 2.0、peer chaincode instantiate概述peer chaincode instantiate命令通过构造生命周期管理系统链码(LSCC)的交易,将安装过的链码在指定通道上进行实例化调用。

HyperledgerFabric1.0从零开始(四)——Fabric源码及镜像文件处理

HyperledgerFabric1.0从零开始(四)——Fabric源码及镜像文件处理

HyperledgerFabric1.0从零开始(四)——Fabric源码及镜像⽂件处理2:Fabric源码及镜像⽂件处理2.1下载Fabric源码下载Fabric源码是因为要⽤到源码中提到的列⼦和⼯具,⼯具编译需要⽤到go语⾔环境,因此需要把源码⽬录放到$GOPATH下。

通过1.3中go的安装配置,$GOPATH设置为/opt/gopath。

我们可以使⽤Git命令下载源码,也可以使⽤go get命令,偷懒⼀点,我们直接⽤go get命令获取最新的Fabric源码:go get /hyperledger/fabric【注:使⽤离线环境或者内⽹环境的朋友可以直接选择对应版本在github上下载,再通过ftp上传到指定⽬录即可】这个可能等的时间⽐较久,等完成后,我们可以在~/go/src//hyperledger/fabric中找到所有的最新的源代码。

由于Fabric⼀直在更新,所有我们并不需要最新最新的源码,需要切换到v1.0.0版本的源码即可:1 cd /opt/gopath/src//hyperledger/fabric/2 git checkout -b v1.0.0本步骤也可直接在github上将源码下载⾄本地,再通过ftp上传⾄hyperledger⽬录。

如果没有git命令,还需要先执⾏以下命令,构建本地git环境。

yum install git最终⽬录在FTP的视图正常情况下如下所⽰:2.2下载Fabric相关镜像⽂件该操作有多种⽅式进⾏,如果是测试Fabric集群⽅案,直接进⼊fabric/examples/e2e_cli⽬录下,运⾏./download-dockerimages.sh,即可下载该⼯程必要的镜像⽂件。

⼀般情况下,为了保证镜像与下载到hyperledger中的源码demo版本号相对应,该种⽅法属于较为妥当的⽅案。

但为了今后升级⽅便,且版本可以由⾃⼰控制,故本次还将介绍另⼀种⽅案,也是笔者推荐的⽅案。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

兄弟连区块链教程Fabric1.0源代码分析PeerBroadcastClient(Broadcast客户端)兄弟连区块链教程Fabric1.0源代码分析PeerBroadcastClient(Broadcast客户端),2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。

但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

# Fabric1.0源代码笔记之Peer DeliverClient(Deliver客户端)
## 1、DeliverClient概述
DeliverClient代码分布如下:
* peer/channel/deliverclient.go,deliverClientIntf接口定义及实现,以及DeliverClient工具函数。

* protos/orderer/ab.pb.go,AtomicBroadcast_DeliverClient接口定义和实现。

## 2、deliverClientIntf接口定义及实现
### 2.1、DeliverClient工具函数
```go
//构造deliverClient
func newDeliverClient(conn *grpc.ClientConn, client
ab.AtomicBroadcast_DeliverClient, chainID string) *deliverClient
//代码在peer/channel/deliverclient.go
```
### 2.2、deliverClientIntf接口定义及实现
```go
type deliverClientIntf interface {
getSpecifiedBlock(num uint64) (*common.Block, error)
getOldestBlock() (*common.Block, error)
getNewestBlock() (*common.Block, error)
Close() error
}
type deliverClient struct {
conn *grpc.ClientConn
client ab.AtomicBroadcast_DeliverClient
chainID string
}
//构造查询Envelope
func seekHelper(chainID string, position *ab.SeekPosition)
*common.Envelope
//r.client.Send(seekHelper(r.chainID, &ab.SeekPosition{Type:
&ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: blockNumber}}}))
func (r *deliverClient) seekSpecified(blockNumber uint64) error
//r.client.Send(seekHelper(r.chainID, &ab.SeekPosition{Type:
&ab.SeekPosition_Oldest{Oldest: &ab.SeekOldest{}}}))
func (r *deliverClient) seekOldest() error
//return r.client.Send(seekHelper(r.chainID, &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}))
func (r *deliverClient) seekNewest() error
//r.client.Recv()读取块
func (r *deliverClient) readBlock() (*common.Block, error)
//r.seekSpecified(num)和r.readBlock()
func (r *deliverClient) getSpecifiedBlock(num uint64) (*common.Block, error)
//r.seekOldest()和r.readBlock()
func (r *deliverClient) getOldestBlock() (*common.Block, error)
//r.seekNewest()和r.readBlock()
func (r *deliverClient) getNewestBlock() (*common.Block, error)
//r.conn.Close()
func (r *deliverClient) Close() error
//cf.DeliverClient.getSpecifiedBlock(0)获取创世区块
func getGenesisBlock(cf *ChannelCmdFactory) (*common.Block, error)
//代码在peer/channel/deliverclient.go
```
func seekHelper(chainID string, position *ab.SeekPosition)
*common.Envelope代码如下:
```go
func seekHelper(chainID string, position *ab.SeekPosition)
*common.Envelope {
seekInfo := &ab.SeekInfo{
Start: position,
Stop: position,
Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
}
msgVersion := int32(0)
epoch := uint64(0)
env, err :=
utils.CreateSignedEnvelope(common.HeaderType_CONFIG_UPDATE, chainID, localmsp.NewSigner(), seekInfo, msgVersion, epoch)
return env
}
//代码在peer/channel/deliverclient.go
```
感谢关注兄弟连区块链教程分享!。

相关文档
最新文档