【发布时间】:2019-01-01 08:14:48
【问题描述】:
为了避免错误和编写高效的 Hyperledger Fabric 链码,应该遵循哪些最佳实践?
【问题讨论】:
标签: hyperledger-fabric blockchain hyperledger
为了避免错误和编写高效的 Hyperledger Fabric 链码,应该遵循哪些最佳实践?
【问题讨论】:
标签: hyperledger-fabric blockchain hyperledger
编写 Hyperledger Fabric 链码的一般准则。
有关详细说明,请参阅以下链接:
https://gist.github.com/arnabkaycee/d4c10a7f5c01f349632b42b67cee46db
下面简述一些步骤:
使用日志记录简单易行。使用 Fabric 的内置记录器。 Fabric 提供的日志机制如下:
Go 语言:https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#ChaincodeLogger
对于 NodeJS:https://fabric-shim.github.io/Shim.html#.newLogger__anchor
对于 Java:您可以使用任何标准的日志框架,例如 Log4J
避免使用全局密钥 - Hyperledger Fabric 在提交事务时使用乐观锁定模型。在背书和提交的两阶段过程中,如果您在背书中读取的某些版本的密钥发生了变化,直到您的交易到达提交阶段,您会收到 MVCC_READ_CONFLICT 错误。这通常是一个或多个并发事务更新同一密钥时的概率。
明智地使用 Couch DB 查询
Couch DB 查询不会更改事务的 READ SET - Mongo 查询仅用于查询键值存储,即 StateDB。它不会改变事务的读取集。这可能会导致事务中的幻读。
只有您存储在 couchDB 中的 DATA 是可搜索的 - 不要试图使用 MangoQuery 按其名称搜索键。尽管您可以访问 CouchDB 的 Fauxton 控制台,但您无法通过查询存储在数据库中的密钥来访问密钥。示例:不允许通过 channelName\0000KeyName 进行查询。最好将密钥作为属性存储在数据本身中。
编写确定性链码 - 切勿编写不确定性链码。这意味着如果我在不同时间在 2 个或更多不同环境中执行链代码,结果应该始终相同,例如将值设置为当前时间或设置随机数。例如:避免调用rand.New(...)、t := time.Now() 或什至依赖未持久化到账本的全局变量(check)之类的语句。
这是因为,如果生成的读写集不同,验证系统链码可能会拒绝它并抛出 ENDORSEMENT_POLICY_FAILURE。
从您的链码调用其他链码时要小心。 - 当两个链码在同一个通道上时,从另一个链码调用一个链码是可以的。但请注意,如果它在另一个通道上,那么您只能获得链码函数返回的内容(仅当当前调用者有权访问该通道上的数据时)。即使它尝试写入一些数据,也不会在另一个通道中提交任何数据。目前,跨通道链码链码调用不会更改另一个通道上的数据(更改写入集)。因此,每个事务一次只能写入一个通道。
记得设置链码执行超时 - 通常情况下,在高负载期间,您的链码可能无法在 30 秒内完成执行。根据您的需要自定义设置超时是一个好习惯。这由 peer 的 core.yaml 中的参数控制。您可以通过在 docker compose 文件中设置环境变量来覆盖它:
示例:CORE_CHAINCODE_EXECUTETIMEOUT=60s
避免访问外部资源 - 访问外部资源 (http) 可能会暴露您的链代码的漏洞和安全威胁。您不希望来自外部来源的恶意代码以任何方式影响您的链代码逻辑。所以尽量远离外来电话。
【讨论】: