Hyperledger Fabric 文档

4.7.2 Hyperledger Fabric - 应用程序开

2019-12-19  本文已影响0人  furnace

应用程序开发 - 应用程序设计元素 - 链码命名空间

链码命名空间允许它保持其世界状态与其他链码分离。具体来说,具有相同链码的智能合约共享对同一世界状态的直接访问,而具有不同链码的智能合约不能直接访问彼此的世界状态。如果智能合约需要访问另一个链码世界状态,则可以通过执行链码到链码的调用来做到这一点。最后,区块链可以包含与不同世界状态相关的交易。

在本主题中,我们将介绍:

1. 动机

命名空间是一个常见的概念。我们知道,纽约的公园街和西雅图的公园街虽然名称相同,但却是不同的街道。这个城市形成了公园街的命名空间,同时提供了自由和清晰。

在计算机系统中也是一样。命名空间允许不同的用户对共享系统的不同部分进行编程和操作,而不会互相干扰。许多编程语言都有命名空间,因此程序可以自由分配唯一的标识符,例如变量名,而不必担心其他程序会这样做。我们将看到 Hyperledger Fabric 使用命名空间来帮助智能合约将其帐本世界状态与其他智能合约区分开。

2. 场景

让我们使用下图检查账本世界状态如何组织对组织中重要组织的业务对象的事实。无论这些对象是商业票据,债券还是车辆登记证,以及它们在其生命周期中的任何位置,都将其维护为帐本世界状态数据库中的状态。智能合约通过与帐本 (世界状态和区块链) 进行交互来管理这些业务对象,在大多数情况下,这将涉及查询或更新帐本世界状态。

了解帐本世界状态是根据访问它的智能合约的链码进行分区的,这一点至关重要,对于架构师,管理员和程序员来说,这种分区或命名空间是重要的设计考虑因素。

image

账本世界状态根据访问它的链码分为不同的命名空间。在给定的通道内,相同链码中的智能合约共享相同的世界状态,而不同链码中的智能合约无法直接访问彼此的世界状态。同样,区块链可以包含与不同链码世界状态相关的交易。

在我们的示例中,我们可以看到在两个不同的链码中定义了四个智能合约,每个合约都在自己的链码容器中。 euroPaper 和 yenPaper 智能合约在 papers 链码中定义。对于 EuroBond 和 JPYBond 智能合约,情况也是如此 - 它们在 bonds 链码中定义。这种设计可以帮助应用程序程序员了解他们是在使用欧元还是日元定价的商业票据还是债券,并且由于每种金融产品的规则对于不同的货币并没有真正改变,因此有必要使用相同的链码来管理其部署。

该图 还显示了此部署选择的后果。数据库管理系统 (DBMS) 为 papersbonds 链码以及其中包含的智能合约创建不同的世界状态数据库。世界状态 A 和世界状态 B 分别保存在不同的数据库中;数据彼此隔离,因此单个世界状态查询 (例如) 无法访问两个世界状态。据说世界状态根据其链码进行了命名。

了解世界状态 A 如何包含两个商业票据列表 paperListEuropaperListYen。状态 PAP11 和 PAP21 是分别由 euroPaper 和 yenPaper 智能合约管理的每种票据的实例。因为它们共享相同的链码命名空间,所以它们的键 (PAPxyz) 在 papers 链码的命名空间内必须是唯一的,有点像街道名称在城镇中是唯一的。注意,有可能在 papers 链码中编写智能合约,从而对所有商业票据 (无论是欧元还是日元) 进行汇总计算,因为它们共享相同的命名空间。债券的情况与此类似 - 它们保存在世界状态 B 中,该状态映射到单独的债券数据库,并且其键必须唯一。

同样重要的是,命名空间意味着 euroPaper 和 yenPaper 无法直接访问世界状态 B,而 EuroBond 和 yenBond 无法直接访问世界状态 A。这种隔离非常有用,因为商业票据和债券是非常不同的金融工具;它们具有不同的属性,并遵循不同的规则。这也意味着票据和证券可以具有相同的键,因为它们位于不同的命名空间中。这很有帮助;它为命名提供了很大的自由度。使用这种自由来有意义地命名不同的业务对象。

最重要的是,我们可以看到区块链与在特定通道中运行的对端节点相关联,并且它包含影响世界状态 A 和世界状态 B 的交易。这是因为区块链是对端节点中包含的最基本的数据结构。可以始终从此区块链重新创建世界状态集,因为它们是区块链交易的累积结果。世界状态有助于简化智能合约并提高其效率,因为它们通常仅需要一个状态的当前值。通过命名空间将世界状态分开可以帮助智能合约将其逻辑与其他智能合约隔离,而不必担心对应于不同世界状态的交易。例如,债券合约不需要担心票据交易,因为它看不到它们产生的世界状态。

还值得注意的是,对端节点,链码容器和 DBMS 在逻辑上都是不同的进程。对端节点及其所有链码容器始终在物理上独立的操作系统进程中,但是根据其 类型,可以将 DBMS 配置为嵌入式或独立。对于 LevelDB,DBMS 完全包含在对端节点中,但是对于 CouchDB,它是一个单独的操作系统进程。

重要的是要记住,在此示例中,命名空间的选择是业务要求的结果,该业务要求共享不同货币的商业票据,但将它们与债券分开。考虑如何修改命名空间结构以满足业务需求,以使每个金融资产类别保持独立,或共享所有商业票据和债券?

3. 通道

如果对端节点加入了多个通道,则会为每个通道创建并管理一个新的区块链。而且,每次在新的通道中实例化一个链码时,都会为其创建一个新的世界状态数据库。这意味着通道还与世界状态的链码一起形成一种命名空间。

但是,相同的对端节点和链码容器进程可以同时加入多个通道 – 与区块链和世界状态数据库不同,这些进程不会随着加入的通道数量而增加。

例如,如果票据和债券链码在新的通道上实例化,则将创建一个完全独立的区块链,并创建两个新的世界状态数据库。但是,对端节点和链码容器不会增加;每个都将连接到多个通道。

4. 使用

让我们使用我们的商业票据 示例 来说明应用程序如何使用带有命名空间的智能合约。值得注意的是,应用程序与对端节点通信,并且对端节点将请求路由到适当的链码容器,然后容器可以访问 DBMS。该路由由图中所示的对端节点核心组件完成。

这是使用商业票据和债券的应用程序代码,以欧元和日元定价。该代码是不言自明的:

const euroPaper = network.getContract(papers, euroPaper);
paper1 = euroPaper.submit(issue, PAP11);

const yenPaper = network.getContract(papers, yenPaper);
paper2 = yenPaper.submit(redeem, PAP21);

const euroBond = network.getContract(bonds, euroBond);
bond1 = euroBond.submit(buy, BON31);

const yenBond = network.getContract(bonds, yenBond);
bond2 = yenBond.submit(sell, BON41);

查看应用程序如何:

了解智能合约如何与世界状态交互:

了解区块链如何捕获所有世界状态的交易:

5. 跨链码访问

正如我们在示例 场景 中看到的那样,euroPaper 和 yenPaper 无法直接访问世界状态 B。这是因为我们已经设计了链码和智能合约,因此这些链码和世界状态彼此分开保存。但是,让我们假设 euroPaper 需要访问世界状态 B。

为什么会发生这种情况?想象一下,当发行商业票据时,智能合约想要根据具有相似到期日的债券当前收益对票据定价。在这种情况下,euroPaper 合约必须能够查询处于世界状态 B 的债券的价格。请查看下图,看看我们如何构建这种交互。

image

链码和智能合约如何通过其链码间接访问另一个世界状态。

注意:

使用 invokeChaincode() API 在链码之间传递控制。该 API 将控制权从一个链码传递到另一个链码。

尽管我们仅在示例中讨论了查询交易,但是可以调用智能合约来更新被调用的链码的世界状态。请参阅以下注意事项。

6. 注意事项

Reference

项目源代码

项目源代码会逐步上传到 Github,地址为 https://github.com/windstamp

Contributor

  1. Windstamp, https://github.com/windstamp
上一篇下一篇

猜你喜欢

热点阅读