千家信息网

Fabric链码开发的原则有哪些

发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,这篇文章主要介绍了Fabric链码开发的原则有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、启用peer节点的开发模式使用开发
千家信息网最后更新 2025年12月03日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安全错误 数据库的锁怎样保障安全 财务软件要配备服务器吗 minemc服务器地址 长春游族网络技术有限公司 房配天下互联网科技有限公司 万由nas备份服务器数据 深圳豹变网络技术有限公司 马到成功网络技术服务部 苏州找大状互联网科技 工业信息网络安全应急预案 软件开发人员职级晋升答辩 关于科技未来互联网的文章 苹果watch服务器连接失败 数据库启动不了是什么原因是 手机网络安全问题解析 北京现代软件开发收费 网络安全手抄报 第一名 管家婆软件数据库清空 湖南长沙深蓝测绘软件开发公司 linux dns服务器配置 深入僧尼开展网络安全宣传活动 中交集团软件开发怎么样 数据库中update语句格式 足浴软件开发哪家好 电脑服务器数据库版本低 服务器网页打开慢 软件开发网站开发公司 数据库怎么弄系统界面 安卓软件开发项目代码和实现 网络安全等级保护线上会议 cmd连linux数据库
0