兄弟连区块链技术培训Fabric 10源代码分析5Chaincode链码体系总结.docx
- 文档编号:4987173
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:14
- 大小:18.45KB
兄弟连区块链技术培训Fabric 10源代码分析5Chaincode链码体系总结.docx
《兄弟连区块链技术培训Fabric 10源代码分析5Chaincode链码体系总结.docx》由会员分享,可在线阅读,更多相关《兄弟连区块链技术培训Fabric 10源代码分析5Chaincode链码体系总结.docx(14页珍藏版)》请在冰豆网上搜索。
兄弟连区块链技术培训Fabric10源代码分析5Chaincode链码体系总结
兄弟连区块链技术培训Fabric1.0源代码分析(5)Chaincode(链码)体系总结
#Fabric1.0源代码笔记之Chaincode(链码)
##1、Chaincode概述
Chaincode,即链码或智能合约,代码分布在protos/peer目录、core/chaincode和core/common/ccprovider目录,目录结构如下:
* protos/peer目录:
* chaincode.pb.go,ChaincodeDeploymentSpec、ChaincodeInvocationSpec结构体定义。
* core/chaincode目录:
* platforms目录,链码的编写语言平台实现,如golang或java。
* platforms.go,Platform接口定义,及部分工具函数。
* java目录,java语言平台实现。
* golang目录,golang语言平台实现。
* core/common/ccprovider目录:
ccprovider相关实现。
##2、protos相关结构体定义
###2.1、ChaincodeDeploymentSpec结构体定义(用于Chaincode部署)
####2.1.1ChaincodeDeploymentSpec结构体定义
```go
type ChaincodeDeploymentSpec struct {
ChaincodeSpec*ChaincodeSpec //ChaincodeSpec消息
EffectiveDate*google_protobuf1.Timestamp
CodePackage[]byte //链码文件打包
ExecEnvChaincodeDeploymentSpec_ExecutionEnvironment //链码执行环境,DOCKER或SYSTEM
}
type ChaincodeDeploymentSpec_ExecutionEnvironment int32
const (
ChaincodeDeploymentSpec_DOCKERChaincodeDeploymentSpec_ExecutionEnvironment= 0
ChaincodeDeploymentSpec_SYSTEMChaincodeDeploymentSpec_ExecutionEnvironment= 1
)
//代码在protos/peer/chaincode.pb.go
```
####2.1.2、ChaincodeSpec结构体定义
```go
type ChaincodeSpec struct {
TypeChaincodeSpec_Type //链码的编写语言,GOLANG、JAVA
ChaincodeId*ChaincodeID //ChaincodeId,链码路径、链码名称、链码版本
Input*ChaincodeInput //链码的具体执行参数信息
Timeout int32
}
type ChaincodeSpec_Type int32
const (
ChaincodeSpec_UNDEFINEDChaincodeSpec_Type= 0
ChaincodeSpec_GOLANGChaincodeSpec_Type= 1
ChaincodeSpec_NODEChaincodeSpec_Type= 2
ChaincodeSpec_CARChaincodeSpec_Type= 3
ChaincodeSpec_JAVAChaincodeSpec_Type= 4
)
type ChaincodeID struct {
Path string
Name string
Version string
}
type ChaincodeInput struct { //链码的具体执行参数信息
Args[][]byte
}
//代码在protos/peer/chaincode.pb.go
```
###2.2、ChaincodeInvocationSpec结构体定义
```go
type ChaincodeInvocationSpec struct {
ChaincodeSpec*ChaincodeSpec //参考本文2.2
IdGenerationAlg string
}
//代码在protos/peer/chaincode.pb.go
```
##3、ccprovider目录相关实现
###3.1、ChaincodeData结构体
```go
type ChaincodeData struct {
Name string
Version string
Escc string
Vscc string
Policy[]byte //chaincode实例的背书策略
Data[]byte
Id[]byte
InstantiationPolicy[]byte //实例化策略
}
//获取ChaincodeData,优先从缓存中读取
func GetChaincodeData(ccname string,ccversion string)(*ChaincodeData, error)
//代码在core/common/ccprovider/ccprovider.go
```
funcGetChaincodeData(ccnamestring,ccversionstring)(*ChaincodeData,error)代码如下:
```go
var ccInfoFSProvider=&CCInfoFSImpl{}
var ccInfoCache=NewCCInfoCache(ccInfoFSProvider)
func GetChaincodeData(ccname string,ccversion string)(*ChaincodeData, error){
//./peer/node/start.go:
ccprovider.EnableCCInfoCache()
//如果启用ccInfoCache,优先从缓存中读取ChaincodeData
if ccInfoCacheEnabled{
return ccInfoCache.GetChaincodeData(ccname,ccversion)
}
ccpack,err:
=ccInfoFSProvider.GetChaincode(ccname,ccversion)
return ccpack.GetChaincodeData(), nil
}
//代码在core/common/ccprovider/ccprovider.go
```
###3.2、ccInfoCacheImpl结构体
```go
type ccInfoCacheImpl struct {
sync.RWMutex
cache map[string]*ChaincodeData //ChaincodeData
cacheSupportCCCacheSupport
}
//构造ccInfoCacheImpl
func NewCCInfoCache(csCCCacheSupport)*ccInfoCacheImpl
//获取ChaincodeData,优先从c.cache中获取,如果c.cache中没有,则从c.cacheSupport(即CCInfoFSImpl)中获取并写入c.cache
func (c*ccInfoCacheImpl)GetChaincodeData(ccname string,ccversion string)(*ChaincodeData, error)
//代码在core/common/ccprovider/ccinfocache.go
```
func(c *ccInfoCacheImpl)GetChaincodeData(ccnamestring,ccversionstring)(*ChaincodeData,error)代码如下:
```go
func (c*ccInfoCacheImpl)GetChaincodeData(ccname string,ccversion string)(*ChaincodeData, error){
key:
=ccname+ "/" +ccversion
c.RLock()
ccdata,in:
=c.cache[key] //优先从c.cache中获取
c.RUnlock()
if !
in{ //如果c.cache中没有
var errerror
//从c.cacheSupport中获取
ccpack,err:
=c.cacheSupport.GetChaincode(ccname,ccversion)
c.Lock()
//并写入c.cache
ccdata=ccpack.GetChaincodeData()
c.cache[key]=ccdata
c.Unlock()
}
return ccdata, nil
}
//代码在core/common/ccprovider/ccinfocache.go
```
###3.3、CCCacheSupport接口定义及实现
####3.3.1、CCCacheSupport接口定义
```go
type CCCacheSupport interface {
//获取Chaincode包
GetChaincode(ccname string,ccversion string)(CCPackage, error)
}
//代码在core/common/ccprovider/ccprovider.go
```
####3.3.2、CCCacheSupport接口实现(即CCInfoFSImpl结构体)
```go
type CCInfoFSImpl struct{}
//从文件系统中读取并构造CDSPackage或SignedCDSPackage
func (*CCInfoFSImpl)GetChaincode(ccname string,ccversion string)(CCPackage, error){
cccdspack:
=&CDSPackage{}
_,_,err:
=cccdspack.InitFromFS(ccname,ccversion)
if err!
= nil {
//trysignedCDS
ccscdspack:
=&SignedCDSPackage{}
_,_,err=ccscdspack.InitFromFS(ccname,ccversion)
if err!
= nil {
return nil,err
}
return ccscdspack, nil
}
return cccdspack, nil
}
//将ChaincodeDeploymentSpec序列化后写入文件系统
func (*CCInfoFSImpl)PutChaincode(depSpec*pb.ChaincodeDeploymentSpec)(CCPackage, error){
buf,err:
=proto.Marshal(depSpec)
cccdspack:
=&CDSPackage{}
_,err:
=cccdspack.InitFromBuffer(buf)
err=cccdspack.PutChaincodeToFS()
}
//代码在core/common/ccprovider/ccprovider.go
```
###3.4、CCPackage接口定义及实现
####3.4.1、CCPackage接口定义
```go
type CCPackage interface {
//从字节初始化包
InitFromBuffer(buf[]byte)(*ChaincodeData, error)
//从文件系统初始化包
InitFromFS(ccname string,ccversion string)([]byte,*pb.ChaincodeDeploymentSpec, error)
//将chaincode包写入文件系统
PutChaincodeToFS() error
//从包中获取ChaincodeDeploymentSpec
GetDepSpec()*pb.ChaincodeDeploymentSpec
//从包中获取序列化的ChaincodeDeploymentSpec
GetDepSpecBytes()[]byte
//校验ChaincodeData
ValidateCC(ccdata*ChaincodeData) error
//包转换为proto.Message
GetPackageObject()proto.Message
//获取ChaincodeData
GetChaincodeData()*ChaincodeData
//基于包计算获取chaincodeId
GetId()[]byte
}
//代码在core/common/ccprovider/ccprovider.go
```
####3.4.2、CCPackage接口实现(CDSPackage)
```go
type CDSData struct {
CodeHash[]byte //ChaincodeDeploymentSpec.CodePackage哈希
MetaDataHash[]byte //ChaincodeSpec.ChaincodeId.Name和ChaincodeSpec.ChaincodeId.Version哈希
}
type CDSPackage struct {
buf[]byte //ChaincodeDeploymentSpec哈希
depSpec*pb.ChaincodeDeploymentSpec //ChaincodeDeploymentSpec
data*CDSData
datab[]byte
id[]byte //id为CDSData.CodeHash和CDSData.MetaDataHash求哈希
}
//获取ccpack.id
func (ccpack*CDSPackage)GetId()[]byte
//获取ccpack.depSpec
func (ccpack*CDSPackage)GetDepSpec()*pb.ChaincodeDeploymentSpec
//获取ccpack.buf,即ChaincodeDeploymentSpec哈希
func (ccpack*CDSPackage)GetDepSpecBytes()[]byte
//获取ccpack.depSpec
func (ccpack*CDSPackage)GetPackageObject()proto.Message
//构造ChaincodeData
func (ccpack*CDSPackage)GetChaincodeData()*ChaincodeData
//获取ChaincodeDeploymentSpec哈希、CDSData、id
func (ccpack*CDSPackage)getCDSData(cds*pb.ChaincodeDeploymentSpec)([]byte,[]byte,*CDSData, error)
//校验CDSPackage和ChaincodeData
func (ccpack*CDSPackage)ValidateCC(ccdata*ChaincodeData) error
//[]byte反序列化为ChaincodeDeploymentSpec,构造CDSPackage,进而构造ChaincodeData
func (ccpack*CDSPackage)InitFromBuffer(buf[]byte)(*ChaincodeData, error)
//从文件系统中获取ChaincodeData,即buf,err:
=GetChaincodePackage(ccname,ccversion)和_,err=ccpack.InitFromBuffer(buf)
func (ccpack*CDSPackage)InitFromFS(ccname string,ccversion string)([]byte,*pb.ChaincodeDeploymentSpec, error)
//ccpack.buf写入文件,文件名为/var/hyperledger/production/chaincodes/Name.Version
func (ccpack*CDSPackage)PutChaincodeToFS() error
//代码在core/common/ccprovider/cdspackage.go
```
###3.5、CCContext结构体
```go
type CCContext struct { //ChaincodeD上下文
ChainID string
Name string
Version string
TxID string
Syscc bool
SignedProposal*pb.SignedProposal
Proposal*pb.Proposal
canonicalName string
}
//构造CCContext
func NewCCContext(cid,name,version,txid string,syscc bool,signedProp*pb.SignedProposal,prop*pb.Proposal)*CCContext
//name+":
"+version
func (cccid*CCContext)GetCanonicalName() string
//代码在core/common/ccprovider/ccprovider.go
```
##4、chaincode目录相关实现
###4.1、ChaincodeProviderFactory接口定义及实现
####4.1.1、ChaincodeProviderFactory接口定义
```go
type ChaincodeProviderFactory interface {
//构造ChaincodeProvider实例
NewChaincodeProvider()ChaincodeProvider
}
func RegisterChaincodeProviderFactory(ccfactChaincodeProviderFactory){
ccFactory=ccfact
}
func GetChaincodeProvider()ChaincodeProvider{
return ccFactory.NewChaincodeProvider()
}
//代码在core/common/ccprovider/ccprovider.go
```
####4.1.2、ChaincodeProviderFactory接口实现
```go
type ccProviderFactory struct {
}
func (c*ccProviderFactory)NewChaincodeProvider()ccprovider.ChaincodeProvider{
return &ccProviderImpl{}
}
func init(){
ccprovider.RegisterChaincodeProviderFactory(&ccProviderFactory{})
}
//代码在core/chaincode/ccproviderimpl.go
```
###4.2、ChaincodeProvider接口定义及实现
####4.2.1、ChaincodeProvider接口定义
```go
type ChaincodeProvider interface {
GetContext(ledgerledger.PeerLedger)(context.Context, error)
GetCCContext(cid,name,version,txid string,syscc bool,signedProp*pb.SignedProposal,prop*pb.Proposal) interface{}
GetCCValidationInfoFromLSCC(ctxtcontext.Context,txid string,signedProp*pb.SignedProposal,prop*pb.Proposal,chainID string,chaincodeID string)(string,[]byte, error)
ExecuteChaincode(ctxtcontext.Context,cccid interface{},args[][]byte)(*pb.Response,*pb.ChaincodeEvent, error)
Execute(ctxtcontext.Context,cccid interface{},spec interface{})(*pb.Response,*pb.ChaincodeEvent
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 兄弟连区块链技术培训Fabric 10源代码分析5Chaincode链码体系总结 兄弟连 区块 技术培训 Fabric 10 源代码 分析 Chaincode 体系 总结
![提示](https://static.bdocx.com/images/bang_tan.gif)