fabric 源码解析
兄弟连区块链技术培训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区块文件存储二。
涉及方法如下:```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的源代码是开源的,目前由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源代码分析PeerBroadcastClient(Broadcast客户端)

兄弟连区块链教程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//构造deliverClientfunc newDeliverClient(conn *grpc.ClientConn, clientab.AtomicBroadcast_DeliverClient, chainID string) *deliverClient//代码在peer/channel/deliverclient.go```### 2.2、deliverClientIntf接口定义及实现```gotype deliverClientIntf interface {getSpecifiedBlock(num uint64) (*common.Block, error)getOldestBlock() (*common.Block, error)getNewestBlock() (*common.Block, error)Close() error}type deliverClient struct {conn *grpc.ClientConnclient ab.AtomicBroadcast_DeliverClientchainID string}//构造查询Envelopefunc 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代码如下:```gofunc 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```感谢关注兄弟连区块链教程分享!。
兄弟连区块链教程Fabric1.0源代码分析Ledger idStore(ledgerID数据库)

兄弟连区块链教程Fabric1.0源代码分析Ledger idStore(ledgerID数据库)兄弟连区块链教程Fabric1.0源代码分析Ledger idStore(ledgerID数据库),2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。
但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。
# Fabric 1.0源代码笔记之 Ledger #idStore(ledgerID数据库)## 1、idStore概述* Fabric支持创建多个Ledger,不同Ledger以ledgerID区分。
* 多个ledgerID及其创世区块存储在idStore数据库中,idStore数据库基于leveldb 实现。
* idStore默认使用路径:/var/hyperledger/production/ledgersData/ledgerProvider/。
* idStore库中特殊key "underConstructionLedgerKey",用于标志最新在建的ledgerID,ledgerID创建成功后或失败时该标志将清除,另外此标志也用于异常时按ledgerID恢复数据。
* idStore相关代码集中在core/ledger/kvledger/kv_ledger_provider.go。
## 2、idStore结构体定义leveldbhelper更详细内容,参考:[Fabric 1.0源代码笔记之 LevelDB(KV数据库)](../leveldb/README.md)```gotype idStore struct {db *leveldbhelper.DB}//代码在core/ledger/kvledger/kv_ledger_provider.go```## 3、idStore方法定义```gofunc openIDStore(path string) *idStore //按path创建并打开leveldb数据库func (s *idStore) setUnderConstructionFlag(ledgerID string) error //设置ledgerID在建标志,将key为"underConstructionLedgerKey",value为ledgerID写入库func (s *idStore) unsetUnderConstructionFlag() error //取消ledgerID在建标志(确认构建失败时),删除key"underConstructionLedgerKey"func (s *idStore) getUnderConstructionFlag() (string, error) //获取ledgerID 在建标志(按ledgerID恢复时),按key"underConstructionLedgerKey",取ledgerID func (s *idStore) createLedgerID(ledgerID string, gb *common.Block) error //创建LedgerID,即以ledgerID为key,将创世区块写入库func (s *idStore) ledgerIDExists(ledgerID string) (bool, error) //查找ledgerID是否存在,即查库中key为ledgerID是否存在func (s *idStore) getAllLedgerIds() ([]string, error) //获取ledgerID列表func (s *idStore) close() //关闭idStore leveldb数据库func (s *idStore) encodeLedgerKey(ledgerID string) []byte //为ledgerID添加前缀即"l"func (s *idStore) decodeLedgerID(key []byte) string //解除ledgerID前缀//代码在core/ledger/kvledger/kv_ledger_provider.go```func (s *idStore) createLedgerID(ledgerID string, gb *common.Block) error 代码如下:将ledgerID和Block入库,并清除ledgerID在建标志。
fabric 源码解析

fabric 源码解析Fabric(Hyperledger Fabric)是一个基于区块链技术的开源分布式账本平台,它提供了一个可扩展的、高度灵活的企业级区块链框架。
Fabric 由Linux基金会托管,被广泛用于构建企业级区块链解决方案。
Fabric的源码结构复杂,主要分为以下几个部分:1. Chaincode(智能合约):位于`chaincode/`目录下,包含了智能合约的相关代码。
智能合约是在区块链网络上运行的业务逻辑,Fabric支持多种编程语言,如Go、Node.js等。
2. Core(核心):位于`core/`目录下,包含了区块链核心的组件。
主要包括:- `common/`:定义了一些核心的数据结构和共享的工具类。
- `ledger/`:实现了账本相关的逻辑,包括区块链数据的存储和检索。
- `peer/`:包含了节点(Peer)的实现,节点是区块链网络中的参与者。
-`orderer/`:包含了排序服务(Orderer)的实现,排序服务负责将交易按顺序打包成区块。
3. Protos(协议定义):位于`protos/`目录下,包含了使用Protocol Buffers定义的消息格式和服务接口。
这些协议用于节点之间的通信。
4. Fabric CA(证书颁发机构):位于`fabric-ca/`目录下,实现了证书颁发机构的功能,用于管理参与者的身份认证。
5. Fabric SDKs(软件开发工具包):位于`fabric-sdk/`目录下,提供了与Fabric网络交互的软件开发工具包。
SDK支持多种编程语言,如Java、Node.js等。
6. Fabric Samples(示例):位于`samples/`目录下,包含了一些示例应用和配置文件,用于演示如何使用Fabric构建应用。
如果你希望深入了解Fabric的源码,建议从官方文档开始,并参考源码注释、示例代码以及社区的讨论。
同时,你可能需要对区块链的基本概念、共识算法、智能合约等有一定的了解,这有助于更好地理解Fabric的实现。
兄弟连区块链技术培训Fabric 1.0源代码分析(32) Peer #peer node start命令实现

兄弟连区块链技术培训Fabric 1.0源代码分析(32) Pee r #peer node start命令实现## 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.4源码解析:客户端创建通道过程

Fabric1.4源码解析:客户端创建通道过程在使⽤Fabric创建通道的时候,通常我们执⾏⼀条命令完成,这篇⽂章就解析⼀下执⾏这条命令后Fabric源码中执⾏的流程。
peer channel create -o :7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA整个流程的切⼊点在fabric/peer/main.go⽂件中的main()⽅法 (本⽂中使⽤的是Fabric1.4版本,不同版本中内容可能不同)。
这个⽅法中也定义了Peer节点可以执⾏的命令,有关于版本的:version.Cmd(),关于节点状态的:node.Cmd(),关于链码的:chaincode.Cmd(nil),关于客户端⽇志的:clilogging.Cmd(nil),最后⼀个就是关于通道的:channel.Cmd(nil)。
所以我们就从这⾥⼊⼿,看⼀下创建通道的整体流程是什么样的。
点进⾏后,转到了peer/channel/channel.go⽂件中第49⾏,其中定义了Peer节点可以执⾏的对通道进⾏操作的相关命令:func Cmd(cf *ChannelCmdFactory) *mand {AddFlags(channelCmd)#创建通道channelCmd.AddCommand(createCmd(cf))#从通道获取区块channelCmd.AddCommand(fetchCmd(cf))#加⼊通道channelCmd.AddCommand(joinCmd(cf))#列出当前节点所加⼊的通道channelCmd.AddCommand(listCmd(cf))#签名并更新通道配置信息channelCmd.AddCommand(updateCmd(cf))#只对通道配置信息进⾏签名channelCmd.AddCommand(signconfigtxCmd(cf))#获取通道信息channelCmd.AddCommand(getinfoCmd(cf))return channelCmd}具体的Peer节点命令使⽤⽅法可以参考,这⾥不在⼀⼀解释。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
fabric 源码解析
摘要:
I.简介
- 介绍fabric 项目
- 阐述项目背景和意义
II.fabric 源码结构解析
- 整体架构概述
- 主要模块及其功能介绍
- orderer
- peer
- couchdb
- configtx
- gossip
- protobuf
- chaincode
III.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 模块:负责节点通信与组网,以及账本数据存储与同步。
它包括了节点发现、网络连接管理、消息传递等功能。
- couchdb 模块:负责数据存储与查询,以及数据的一致性保证。
它使用了CouchDB 数据库,提供了键值对存储和文档存储两种方式。
- configtx 模块:负责配置管理与更新,以及网络参数设置。
它包括了配置文件的解析、网络参数的设置和更新等功能。
- gossip 模块:负责消息传播机制,以及网络拓扑发现。
它通过Gossip 协议,实现了节点间的消息传播和网络结构发现。
- protobuf 模块:负责数据序列化与反序列化,以及消息格式的定义。
它使用了Google 的Protocol Buffers 技术,提供了高效的数据序列化和反序列化功能。
- chaincode 模块:负责智能合约的管理,以及合约的执行与调用。
它包
括了合约的加载、部署、调用等功能。
III.fabric 源码关键功能详解
接下来,我们将详细介绍Fabric 源码中的关键功能。
- orderer 模块:它实现了BFT 和RAFT 两种共识算法。
在BFT 中,orderer 通过预准备、准备、提交和广播四个阶段,完成区块的生成和传播。
在RAFT 中,orderer 则通过领导选举、日志复制和状态机更新,实现区块的生成和确认。
此外,orderer 模块还实现了消息广播机制,以保证区块的快速传播。
- peer 模块:它负责节点间的通信和组网,以及账本数据存储和同步。
在通信方面,peer 模块实现了Gossip 协议,以实现节点的发现、连接和消息传递。
在数据存储和同步方面,peer 模块实现了Merkle 树,以实现账本数据的高效存储和快速同步。
- couchdb 模块:它负责数据存储和查询,以及数据的一致性保证。
在存储方面,couchdb 模块提供了键值对存储和文档存储两种方式。
在查询方面,它提供了基于键值和基于文档的查询方式。
在数据一致性方面,couchdb 模块实现了数据复制和数据冲突解决,以保证数据的一致性。
- configtx 模块:它负责配置管理和更新,以及网络参数设置。
在配置管理方面,configtx 模块实现了配置文件的解析和更新。
在网络参数设置方面,它提供了网络参数的设置和更新功能。