首页 文章 精选 留言 我的

精选列表

搜索[区块],共3246篇文章
优秀的个人博客,低调大师

供应链区块链溯源系统 | 跨境溯源实践:中欧班列货物通关数据上链

当商品走出国门,进入跨境贸易场景时,新的挑战接踵而至。以中欧班列为例:一趟班列途经中国、哈萨克斯坦、俄罗斯、白俄罗斯、波兰、德国等多个国家,涉及海关、铁路、检验检疫、货代、保险等数十个参与方。传统模式下,货物每经过一个边境口岸,都需要提交纸质报关单、原产地证、检疫证明等文件,这些文件由不同国家的不同机构签发,格式各异、语言不同、真伪难辨。一次跨境运输的通关文件处理时间往往超过 7-15 天,占整个运输周期的 30% 以上。

优秀的个人博客,低调大师

区块链教程Fabric1.0源代码分析Chaincode(链码)体系总结-兄弟连

Fabric 1.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.1 ChaincodeDeploymentSpec结构体定义 type ChaincodeDeploymentSpec struct { ChaincodeSpec *ChaincodeSpec //ChaincodeSpec消息 EffectiveDate *google_protobuf1.Timestamp CodePackage []byte //链码文件打包 ExecEnv ChaincodeDeploymentSpec_ExecutionEnvironment //链码执行环境,DOCKER或SYSTEM } type ChaincodeDeploymentSpec_ExecutionEnvironment int32 const ( ChaincodeDeploymentSpec_DOCKER ChaincodeDeploymentSpec_ExecutionEnvironment = 0 ChaincodeDeploymentSpec_SYSTEM ChaincodeDeploymentSpec_ExecutionEnvironment = 1 ) //代码在protos/peer/chaincode.pb.go 2.1.2、ChaincodeSpec结构体定义 type ChaincodeSpec struct { Type ChaincodeSpec_Type //链码的编写语言,GOLANG、JAVA ChaincodeId *ChaincodeID //ChaincodeId,链码路径、链码名称、链码版本 Input *ChaincodeInput //链码的具体执行参数信息 Timeout int32 } type ChaincodeSpec_Type int32 const ( 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 ) type ChaincodeID struct { Path string Name string Version string } type ChaincodeInput struct { //链码的具体执行参数信息 Args [][]byte } //代码在protos/peer/chaincode.pb.go 2.2、ChaincodeInvocationSpec结构体定义 type ChaincodeInvocationSpec struct { ChaincodeSpec *ChaincodeSpec //参考本文2.2 IdGenerationAlg string } //代码在protos/peer/chaincode.pb.go 3、ccprovider目录相关实现 3.1、ChaincodeData结构体 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 func GetChaincodeData(ccname string, ccversion string) (*ChaincodeData, error)代码如下: 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结构体 type ccInfoCacheImpl struct { sync.RWMutex cache map[string]*ChaincodeData //ChaincodeData cacheSupport CCCacheSupport } //构造ccInfoCacheImpl func NewCCInfoCache(cs CCCacheSupport) *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(ccname string, ccversion string) (ChaincodeData, error) 代码如下: 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 err error //从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接口定义 type CCCacheSupport interface { //获取Chaincode包 GetChaincode(ccname string, ccversion string) (CCPackage, error) } //代码在core/common/ccprovider/ccprovider.go 3.3.2、CCCacheSupport接口实现(即CCInfoFSImpl结构体) type CCInfoFSImpl struct{} //从文件系统中读取并构造CDSPackage或SignedCDSPackage func (*CCInfoFSImpl) GetChaincode(ccname string, ccversion string) (CCPackage, error) { cccdspack := &CDSPackage{} _, _, err := cccdspack.InitFromFS(ccname, ccversion) if err != nil { //try signed CDS 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接口定义 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 //基于包计算获取chaincode Id GetId() []byte } //代码在core/common/ccprovider/ccprovider.go 3.4.2、CCPackage接口实现(CDSPackage) 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结构体 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接口定义 type ChaincodeProviderFactory interface { //构造ChaincodeProvider实例 NewChaincodeProvider() ChaincodeProvider } func RegisterChaincodeProviderFactory(ccfact ChaincodeProviderFactory) { ccFactory = ccfact } func GetChaincodeProvider() ChaincodeProvider { return ccFactory.NewChaincodeProvider() } //代码在core/common/ccprovider/ccprovider.go 4.1.2、ChaincodeProviderFactory接口实现 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接口定义 type ChaincodeProvider interface { GetContext(ledger ledger.PeerLedger) (context.Context, error) GetCCContext(cid, name, version, txid string, syscc bool, signedProp *pb.SignedProposal, prop *pb.Proposal) interface{} GetCCValidationInfoFromLSCC(ctxt context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (string, []byte, error) ExecuteChaincode(ctxt context.Context, cccid interface{}, args [][]byte) (*pb.Response, *pb.ChaincodeEvent, error) Execute(ctxt context.Context, cccid interface{}, spec interface{}) (*pb.Response, *pb.ChaincodeEvent, error) ExecuteWithErrorFilter(ctxt context.Context, cccid interface{}, spec interface{}) ([]byte, *pb.ChaincodeEvent, error) Stop(ctxt context.Context, cccid interface{}, spec *pb.ChaincodeDeploymentSpec) error ReleaseContext() } //代码在core/common/ccprovider/ccprovider.go 4.2.2、ChaincodeProvider接口实现 type ccProviderImpl struct { txsim ledger.TxSimulator //交易模拟器 } type ccProviderContextImpl struct { ctx *ccprovider.CCContext } //获取context.Context,添加TXSimulatorKey绑定c.txsim func (c *ccProviderImpl) GetContext(ledger ledger.PeerLedger) (context.Context, error) //构造CCContext,并构造ccProviderContextImpl func (c *ccProviderImpl) GetCCContext(cid, name, version, txid string, syscc bool, signedProp *pb.SignedProposal, prop *pb.Proposal) interface{} //调用GetChaincodeDataFromLSCC(ctxt, txid, signedProp, prop, chainID, chaincodeID)获取ChaincodeData中Vscc和Policy func (c *ccProviderImpl) GetCCValidationInfoFromLSCC(ctxt context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (string, []byte, error) //调用ExecuteChaincode(ctxt, cccid.(*ccProviderContextImpl).ctx, args)执行上下文中指定的链码 func (c *ccProviderImpl) ExecuteChaincode(ctxt context.Context, cccid interface{}, args [][]byte) (*pb.Response, *pb.ChaincodeEvent, error) //调用Execute(ctxt, cccid.(*ccProviderContextImpl).ctx, spec) func (c *ccProviderImpl) Execute(ctxt context.Context, cccid interface{}, spec interface{}) (*pb.Response, *pb.ChaincodeEvent, error) //调用ExecuteWithErrorFilter(ctxt, cccid.(*ccProviderContextImpl).ctx, spec) func (c *ccProviderImpl) ExecuteWithErrorFilter(ctxt context.Context, cccid interface{}, spec interface{}) ([]byte, *pb.ChaincodeEvent, error) //调用theChaincodeSupport.Stop(ctxt, cccid.(*ccProviderContextImpl).ctx, spec) func (c *ccProviderImpl) Stop(ctxt context.Context, cccid interface{}, spec *pb.ChaincodeDeploymentSpec) error //调用c.txsim.Done() func (c *ccProviderImpl) ReleaseContext() { //代码在core/chaincode/ccproviderimpl.go 4.3、ChaincodeSupport结构体 ChaincodeSupport更详细内容,参考:Fabric 1.0源代码笔记 之 Chaincode(链码) #ChaincodeSupport(链码支持服务端) 4.4、ExecuteChaincode函数(执行链码) 执行链码上下文中指定的链码。 func ExecuteChaincode(ctxt context.Context, cccid *ccprovider.CCContext, args [][]byte) (*pb.Response, *pb.ChaincodeEvent, error) { var spec *pb.ChaincodeInvocationSpec var err error var res *pb.Response var ccevent *pb.ChaincodeEvent spec, err = createCIS(cccid.Name, args) //构造ChaincodeInvocationSpec res, ccevent, err = Execute(ctxt, cccid, spec) return res, ccevent, err } //代码在core/chaincode/chaincodeexec.go res, ccevent, err = Execute(ctxt, cccid, spec)代码如下: func Execute(ctxt context.Context, cccid *ccprovider.CCContext, spec interface{}) (*pb.Response, *pb.ChaincodeEvent, error) { var err error var cds *pb.ChaincodeDeploymentSpec var ci *pb.ChaincodeInvocationSpec cctyp := pb.ChaincodeMessage_INIT //初始化 if cds, _ = spec.(*pb.ChaincodeDeploymentSpec); cds == nil { //优先判断ChaincodeDeploymentSpec if ci, _ = spec.(*pb.ChaincodeInvocationSpec); ci == nil { //其次判断ChaincodeInvocationSpec panic("Execute should be called with deployment or invocation spec") } cctyp = pb.ChaincodeMessage_TRANSACTION //交易 } _, cMsg, err := theChaincodeSupport.Launch(ctxt, cccid, spec) var ccMsg *pb.ChaincodeMessage ccMsg, err = createCCMessage(cctyp, cccid.TxID, cMsg) resp, err := theChaincodeSupport.Execute(ctxt, cccid, ccMsg, theChaincodeSupport.executetimeout) if resp.ChaincodeEvent != nil { resp.ChaincodeEvent.ChaincodeId = cccid.Name resp.ChaincodeEvent.TxId = cccid.TxID } if resp.Type == pb.ChaincodeMessage_COMPLETED { res := &pb.Response{} unmarshalErr := proto.Unmarshal(resp.Payload, res) return res, resp.ChaincodeEvent, nil } } //代码在core/chaincode 5、platforms(链码的编写语言平台) 参考上一篇文章

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册