应用程序开发 - 应用设计元素 - 合约名称
链码是用于将代码部署到 Hyperledger Fabric 区块链网络的通用容器。在一个链码中定义了一个或多个相关的智能合约。每个智能合约都有一个在链码中唯一标识它的名称。应用程序使用其合约名称在实例化的链码中访问特定的智能合约。
在本主题中,我们将介绍:
- 链码如何包含多个智能合约
- 如何分配智能合约名称
- 如何通过应用程序使用智能合约
- 默认智能合约
1. 链码
在 应用程序开发 主题中,我们可以看到 Fabric SDK 如何提供高级编程抽象,以帮助应用程序和智能合约开发人员专注于他们的业务问题,而不是如何与 Fabric 网络交互的底层细节。
智能合约是高级编程抽象的一个示例,可以在链码容器中定义智能合约。安装并实例化一个链码后,其中的所有智能合约都可用于相应的通道。
image可以在一个链码中定义多个智能合约。每个合约均由其链码中的名称唯一标识。
在上图中,链码 A 中定义了三个智能合约,而链码 B 中有四个智能合约。了解如何使用链码名称完全限定特定的智能合约。
帐本结构由一组已部署的智能合约定义。这是因为账本包含有关网络感兴趣的业务对象 (例如 PaperNet 中的商业票据) 的事实,并且这些业务对象通过智能合约中定义的交易功能在其生命周期 (例如发行,购买,赎回) 中移动。
在大多数情况下,一个链码中只会定义一个智能合约。但是,将相关智能合约保持在单个链码中是有意义的。例如,以不同货币计价的商业票据可能具有 EuroPaperContract
,DollarPaperContract
,YenPaperContract
合约,可能需要在其部署通道中保持彼此同步。
2. 名称
链码中的每个智能合约均由其合约名称唯一标识。智能合约可以在构造类时显式分配此名称,也可以让 Contract 类隐式分配默认名称。
检查 papercontract.js 链码 文件:
class CommercialPaperContract extends Contract {
constructor() {
// Unique name when multiple contracts per chaincode file
super('org.papernet.commercialpaper');
}
请参阅 CommercialPaperContract 构造函数如何将合约名称指定为 org.papernet.commercialpaper。结果是在 papercontract 链码中,此智能合约现在与合约名称 org.papernet.commercialpaper 关联。
如果未指定显式合约名称,则将分配默认名称 - 类的名称。在我们的示例中,默认合约名称为 CommercialPaperContract。
仔细选择你的名字。不仅每个智能合约都必须具有唯一的名称,一个精心选择的名字很有启发性。具体来说,建议使用显式的 DNS 样式命名约定,以帮助组织清晰且有意义的名称。 org.papernet.commercialpaper 传达了 PaperNet 网络已经定义了标准的商业票据智能合约。
合约名称还有助于消除给定链码中具有相同名称的不同智能合约交易功能的歧义。当智能合约紧密相关时,就会发生这种情况。它们的交易名称将趋于相同。我们可以看到,交易是通过链码和智能合约名称的组合在通道内唯一定义的。
合约名称在链码文件中必须唯一。某些代码编辑器将在部署之前检测相同类名的多个定义。无论是否显式或隐式指定具有相同协定名称的多个类,链码都将返回错误。
3. 应用程序
将链码安装到对端节点并在通道上实例化后,应用程序即可访问其中的智能合约:
const network = await gateway.getNetwork(`papernet`);
const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');
const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');
查看应用程序如何使用 contract.getContract()
方法访问智能合约。papercontract
链码名称 org.papernet.commercialpaper 返回一个合约引用,该合约引用可用于提交交易以使用 contract.submitTransaction() API 发行商业票据。
4. 默认合约
链码中定义的第一个智能合约称为默认智能合约。默认值很有用,因为链码通常会在其中定义一个智能合约。默认值允许应用程序直接访问这些交易,而无需指定合约名称。
image默认智能合约是链码中定义的第一个合约。
在此图中,CommercialPaperContract 是默认的智能合约。即使我们有两个智能合约,默认的智能合约也使我们前面的示例更容易编写:
const network = await gateway.getNetwork(`papernet`);
const contract = await network.getContract('papercontract');
const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');
之所以可行,是因为 papercontract 中的默认智能合约是 CommercialPaperContract,并且具有 issue
交易。请注意,只能通过显式寻址来调用 BondContract 中的 issue
交易。同样,即使 cancel
交易是唯一的,由于 BondContract 不是默认的智能合约,因此也必须对其进行明确处理。
在大多数情况下,链码将仅包含一个智能合约,因此,对链码进行仔细的命名可以减少开发人员将链码作为概念来考虑的需求。在上面的示例代码中,感觉 papercontract
是一个智能合约。
总之,合约名称是一种简单的机制,可以识别给定链码中的各个智能合约。合约名称使应用程序可以轻松找到特定的智能合约并使用它来访问账本。
Reference
- Docs » Developing Applications » Application design elements » Contract names, https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/contractname.html
- Docs » Developing Applications, https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/developing_applications.html
项目源代码
项目源代码会逐步上传到 Github,地址为 https://github.com/windstamp。
Contributor
- Windstamp, https://github.com/windstamp
网友评论