首页 > 解决方案 > 编写 Hyperledger Fabric 链码时要遵循的最佳实践

问题描述

应该遵循哪些最佳实践来避免错误并编写高效的 Hyperledger Fabric 链码?

标签: hyperledger-fabricblockchainhyperledger

解决方案


编写 Hyperledger Fabric 链码的一般指南。

有关相同的详细说明,请参阅以下链接:

https://gist.github.com/arnabkaycee/d4c10a7f5c01f349632b42b67cee46db

一些步骤简述如下:

  1. 使用链码开发模式
  2. 使用链码记录

使用日志记录简单易行。使用 Fabric 的内置记录器。Fabric 提供的日志机制如下:

对于 Golanghttps ://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#ChaincodeLogger

对于 NodeJShttps ://fabric-shim.github.io/Shim.html#.newLogger__anchor

对于 Java:您可以使用任何标准的日志记录框架,例如 Log4J

  1. 避免使用全局密钥- Hyperledger Fabric 在提交事务时使用乐观锁定模型。在 endorsement 和 committment 的两阶段过程中,如果您在 Endorsement 中读取的某些版本的密钥发生更改,直到您的事务到达提交阶段,您会收到 MVCC_READ_CONFLICT 错误。这通常是一个或多个并发事务更新同一密钥时的概率。

  2. 明智地使用 Couch DB 查询

    • Couch DB 查询不会更改事务的 READ SET - Mongo 查询仅用于查询键值存储,即 StateDB。它不会改变事务的读取集。这可能会导致事务中的幻读。

    • 只有存储在 couchDB 中的 DATA 是可搜索的- 不要试图使用 MangoQuery 按名称搜索键。尽管您可以访问 CouchDB 的 Fauxton 控制台,但您无法通过查询存储在数据库中的密钥来访问密钥。示例:不允许通过channelName\0000KeyName查询。最好将密钥作为属性存储在数据本身中。

  3. 编写确定性链代码- 永远不要编写不确定的链代码。这意味着如果我在不同时间在 2 个或更多不同环境中执行链代码,结果应该始终相同,例如将值设置为当前时间或设置随机数。例如:避免使用诸如调用之类的语句rand.New(...)t := time.Now()或者甚至依赖未持久化到账本中的全局变量(检查)。这是因为,如果生成的读写集不同,验证系统链码可能会拒绝它并抛出 ENDORSEMENT_POLICY_FAILURE。

  4. 从您的链码调用其他链码时要小心。- 当两个链码在同一个通道上时,从另一个链码调用一个链码是可以的。但请注意,如果它在另一个通道上,那么您只能获得链码函数返回的内容(仅当当前调用者有权访问该通道上的数据时)。即使它尝试写入一些数据,也不会在另一个通道中提交任何数据。目前,跨通道链码链码调用不会更改另一个通道上的数据(更改写入集)。因此,每个事务一次只能写入一个通道。

  5. 记住设置链码执行超时- 通常情况下,在高负载期间,您的链码可能无法在 30 秒内完成执行。根据您的需要自定义设置超时是一个好习惯。这由 peer 的 core.yaml 中的参数控制。您可以通过在 docker compose 文件中设置环境变量来覆盖它:示例:CORE_CHAINCODE_EXECUTETIMEOUT=60s

  6. 避免访问外部资源- 访问外部资源 (http) 可能会暴露您的链代码的漏洞和安全威胁。您不希望来自外部来源的恶意代码以任何方式影响您的链代码逻辑。所以尽量远离外来电话。


推荐阅读