千家信息网

Fabric链码开发的原则有哪些

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍了Fabric链码开发的原则有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、启用peer节点的开发模式使用开发
千家信息网最后更新 2026年10月31日Fabric链码开发的原则有哪些

这篇文章主要介绍了Fabric链码开发的原则有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

1、启用peer节点的开发模式

使用开发模式开启你的Hyperledger Fabric链码开发流程。这一点无论怎么强调都不过分,这会节省你大量的时间和精力,因为你可以自由地修改代码而无需重新部署并激活链码,也无需一遍遍地重启网络。


2、使用Fabric链码的日志

这可能是能帮助你调试Hyperledger Fabric链码并快速找出链码bug的第一个有用的技能。链码日志很简单易用,使用Fabric内建的logger即可。

3、避免在Fabric链码中使用全局键

在开发Hyperledger Fabric链码时,我们经常会发现在搜索数据方面限制很多,因此要跟踪在键值库中注册的键,我们有时会尝试使用某些全局数据。

例如,当你再Hyperledger Fabric应用中跟踪注册的弹珠时,可能想创建一个全局的计数器以便生成弹珠的下一个ID。但是这么做的时候,你就引入了对这个变量的依赖。在开始的时候这看起来不是个问题,但是当你提交并发交易时就会出错。为什么?让我解释一下。

看一下链码:

package mainimport (        //other imports        "github.com/hyperledger/fabric/core/chaincode/shim"       pb "github.com/hyperledger/fabric/protos/peer")//不要这么做!        totalNumberOfMarbles := 0func (t *SimpleChaincode) initMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response {    var err error            marbleId := fmt.Sprintf("MARBLE_d",totalNumberOfMarbles)        marbleName := args[0]        color := strings.ToLower(args[1])        owner := strings.ToLower(args[3])        size, err := strconv.Atoi(args[2])                //other code to initialize        objectType := "marble"        marble := &marble{objectType, marbleId, marbleName, color, size, owner}                //--------------CODE SMELL----------------        //BIG source of Non-determinism as well as performance hit.        totalNumberOfMarbles = totalNumberOfMarbles + 1         //--------------CODE SMELL----------------                //regular stuff...                 err = stub.PutState(marbleId, marbleJSONasBytes)        if err != nil {                return shim.Error(err.Error())        }}

那么,为什么我不喜欢这样?

第一个原因。假设你已经完成这个Fabric链码,一切都很正常,直到有一天,某个运行这个链码的peer节点,崩溃了。虽然账本数据还在,但是内部有些可怕的事情已经发生了。你可能重新启动peer节点,起初一切看起来都正常。但是突然,这个节点背书的所有交易都开始失败了。为什么?就是因为那个全局计数变量已经不能正确跟踪真实的值了。其他的peer节点都计数到比如15K了,而这个节点突然从零开始计数,你的弹珠的ID又从零开始了。因此,当你将这个交易发送给排序节点(Orderer)并到达提交节点(Peer)时,提交节点上的验证系统(Validation System Chaincode)会比较所有背书交易的提议响应,同时检查是否有足够的签名存在,只要有一个提议响应不匹配,提交节点就会抛出一个ENDORSEMENT_POLICY_FAILURE异常。

第二个原因。现在让我们尝试解决上面的问题,在Fabric链码的最后添加如下的代码:

stub.PutState("marble_count", totalNumberOfMarbles)

这样会好一些吗?Noooooooooooooooooo!

想象一下,有两个并发交易都试图插入新的弹珠。

例如,一个交易要将marble_count的值更新为34,marble_count状态的新版本为10。而另一个交易则要将marble_count的值更新为35, 它也认为marble_count的新版本为10。记住,由于这两个交易是并发的,两个交易看到的都是current_version(marble_count) = 09。

现在其中一个交易将在另一个交易之前到达Fabric的排序节点,marble_count键已经更新到新的值,这时marble_count的版本已经是10,因此后到的交易将失败,因为marble_count的版本已经是10 ,而后续交易还认为它读的是版本09并且将更新到版本10。这是区块链中经典的双花问题(double spending)。

Hyperledger Fabric在提交交易时使用一种优化的锁模型。正如我已经解释过的,提议响应由客户端从背书节点采集,然后发送给排序节点并最终由排序节点将其分发给提交节点。着这个两步过程中,如果有些在背书阶段读取的键的版本发生了变化,你就会得到MVCC_READ_CONFLICT错误。当存在并发交易同时更新相同的键时,就有可能出现这个问题。

关于这一点的详细说明,可以参考这篇文章。

4、聪明地使用CouchDB查询

Couch DB查询(又称为Mongo查询)在搜索Fabric节点的键值库中的数据时非常有用,但是有一些坑你需要注意。

  • Couch DB查询不会修改交易的READ SET

Mongo查询仅用来查询节点的键值库也就是状态库。它不会修改交易的read set。这可能会在交易中 导致幻读(phantom reads)。

  • 只能搜索已经存入CouchDB的数据

不要试图用Mongo查询按键名搜索。虽然你可以访问CouchDB的Fauxton控制台,但你无法按键查询。例如,不允许查询 channelName\0000KeyName。更好的方法时将键作为你自己数据的属性保存。

5、编写确定性的Fabric链码

永远不要编写不确定的链码。意思是说如果我在多个不同的时间、不同的环境下执行链码,总应该得到相同的结果。例如,避免使用像rand.New(...)或t := time.Now() 这样的代码,或者依赖于某个没有在账本中持久化的变量。

这是因为,如果生成的读写集不一样,Hyperledger Fabric的验证系统链码(Validation System Chaincode)会拒绝交易并抛出ENDORSEMENT_POLICY_FAILURE异常。

6、调用其他通道的Fabric链码时要小心

在链码中调用同一个通道中的另一个链码没问题,但是要了解的是,如果是要调用另一个通道的链码,你只能得到链码方法的返回结果,而不会在另一个通道账本中有任何提交。目前,跨通道的链码调用不会修改数据,因此,一个交易一次只能写入一个通道。

7、记得设置Fabric链码的执行超时时间

在高负载的情况下,你的Hyperledger Fabric链码可能不会在30s内完成。因此一个好的实践是根据需求定制链码执行超时值。这是由core.yaml中的参数决定的。你可以在docker compose 文件中如下设置:

Example: CORE_CHAINCODE_EXECUTETIMEOUT=60s

8、避免从Fabric链码中访问外部资源

访问外部资源可能会暴露系统漏洞并给你的Hyperledger Fabric链码引入安全威胁。无论如何你不会希望外部资源中的恶意代码影响你的链码逻辑。因此请尽可能的避免再Fabric链码中访问区块链外部的资源。

感谢你能够认真阅读完这篇文章,希望小编分享的"Fabric链码开发的原则有哪些"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

交易 节点 查询 数据 开发 通道 版本 篇文章 问题 更新 代码 全局 资源 排序 搜索 两个 变量 同时 时间 系统 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 港股互联网科技股 华中科技大学互联网 远拓互联网科技 江苏南京365互联网科技 厦门比较好的科技互联网公司 银川新华互联网科技学校联系电话 天津腾达互联网科技有限公司 河南住房之家互联网科技 中和天地互联网科技有限公司 工业互联网山东科技大学 上海钢联属于互联网科技股吗 图游互联网科技 吉林省码上互联网科技电话 上海万顺科技互联网有限公司招聘 互联网金融运营模式中的金融科技 银川新华互联网科技学校是国营吗 悟空问答互联网科技 青岛易易互联网科技 互联网科技大佬云集 互联网科技创业有什么好项目 深圳九邦互联网科技有限公司 互联网科技有限公司图片 互联网高科技企业 中国互联网金融科技基金 互联网科技生活的内容 世界互联网领先科技成果获奖 互联网科技数字货币 互联网安防科技感 万物互联网智能科技 宁波允成互联网科技有限公司
0