创建和部署智能合同
为了创建智能合约,我们需要定义要在区块链中存储和管理的实体,如下图的实体模型所示。
插图 oracle-blockchain-cms-entity.png 的说明
所有这些实体及其关系、管理和与实体交互所需的所有逻辑,以及将它们保留到区块链分类账中的逻辑都在智能合同中定义。
文件夹表示为 NFT 令牌,因此将开发和初始化为 NFT。其他从属实体(文档和属性)是标准实体,是文件夹的子实体,因此将作为标准实体开发,而无需初始化。
一旦智能合约被创建,我们将安装并部署在我们创建的区块链网络中。
创建智能合同
配置 Oracle Blockchain App Builder 后,您可以创建规范文件。可以将规范文件创建为如下代码中所示的简单 YAML 文件。
注意:
您也可以从 GitHub 下载此文件:下载 YAML 文件。#
# Token asset to manage the complete lifecycle of a non-fungible token representing a folder to hold docuements.
# This specification file will generate an Smartcontract project with a non-fungible token for the folders to be maintained by the users.
#
assets:
- name: folderNFT
type: token
symbol: eDocs
standard: erc721+
anatomy:
type: nonfungible
unit: whole
behavior:
- indivisible
- singleton
- mintable:
- transferable
- burnable
- roles:
minter_role_name: minter
properties:
- name: folderHASH
type: string
- name: documents
type: document[]
metadata:
- name: folderID
type: string
mandatory: true
id: true
- name: folderType
type: string
mandatory: true
methods:
crud: [create, getById, update, delete]
others: [getHistoryById, getByRange]
- name: document
properties:
- name: docName
type: string
mandatory: true
id: true
- name: docURL
type: string
mandatory: true
- name: docHASH
type: string
mandatory: true
- name: docType
type: string
mandatory: true
- name: docProperties
type: docProperty[]
methods:
crud: [create, getById, update, delete]
others: [getHistoryById, getByRange]
- name: docProperty
type: embedded
properties:
- name: propName
type: string
mandatory: true
- name: propValue
type: string
mandatory: true
methods:
crud: [create, getById, update, delete]
others: [getHistoryById, getByRange]
customMethods:
- executeQuery
- "attachDocument(tokenId: string, docName: string, docURL: string, docHASH: string, docType: string, docProps: string[], docVals: string[])" # Attach a document to an existing folder.
- "retrieveDocuments(tokenId: string)" # Retrieve Documents of an folder.
- "transferFolder(tokenId: string, fromOrgId: string, fromUserId: string, toOrgId: string, toUserId: string)" # Transfer the folder among participants.
- "updateFolderHASH(tokenId: string, newHash: string)" # Update HASH folder
- "getFolderHASH(tokenId: string)" # Check HASH folder
在此规范文件中,在定义的第一个实体 (folderNFT ) 中,可以查看用于表示 NFT 令牌的所有节和属性。概述文件中定义的部分:
- 资产:定义不同资产(标准实体、财务交易、NFT)的位置。在每个资产中,我们可以区分不同的部分,这些部分可能因所表示资产的类型而异。对于 NFT 和 FT,这些是不同的子部分:
- 类型/符号/标准:指定此标记基于 ERC-721 标准,并为其指定唯一的符号标识符。
- 解剖学:指定它是一个 NFT,以及它是否细分为较小的分数(现在,“整体”是 NFT 令牌的唯一选项)。
- 行为:定义令牌是否可以铸造,在这种情况下,可最小化令牌的最大数量是多少。在这里,你还必须说明它是一个不可分割的标记,如果它是每个类的单例,可转移和可燃烧,类似于它的删除(但不会消失,所以它仍然存在,但根本不可用)。也可以在本节中将标记行为限制为特定角色。
- 元数据:定义在创建标记期间必须设置且将来无法更改的属性类型。因此,它的价值将在令牌的整个生命周期中保持不变。
- 属性:定义标记的标准属性,这些属性在标记的生命周期内可能会有所不同,例如组成文件夹的文档数组。
- customMethods:必须定义定制方法列表的位置。对于这些方法,Oracle Blockchain App Builder 将仅生成该方法的签名,而不会对其实施。这些方法的实现是开发人员可以实现的唯一代码。
以下链接介绍了如何根据您的业务需求配置任何类型的实体(NFT、FT 或标准实体):
- 标准实体,请参见 How to create an Input Specification File 。
- 表示为 NFT 的实体,请参见 Input Specification File for Non-Fungible Tokens 。
- 表示为 FT 的实体,请参见 Input Specification File for Fungible Tokens 。
创建规范文件后,我们可以要求 Oracle Blockchain App Builder 按照以下后续步骤创建项目的支架。
oracle-blockchain-nft-token-oracle.zip
此时,链代码可供使用,因此我们可以按照在本地超级账本架构网络上测试您的链代码中的说明在本地部署和测试链代码。
部署智能合同
在本地测试链代码后,通过以下方式将其部署到先前使用 Oracle Blockchain Service Console 创建的实际网络中:
- 打包链代码项目。
- 将链代码程序包安装并部署到单个实例(建立者)。
- 从链代码项目创建可部署程序包。在 Visual Studio 中,单击链代码项目名称顶部的右侧按钮,从弹出菜单中选择程序包选项,然后选择用于保存链代码程序包文件的目录。
- 访问 Oracle Blockchain Service Console,将链代码程序包安装并部署到创建者实例中。
- 导航到链代码选项卡,然后单击部署新链代码。
- 选择高级部署选项。
- 设置所有值以将链代码程序包安装到创建者实例中,然后单击下一步。
- 程序包标签:指定一个名称,该名称可以帮助您确定在不同的现有通道中安装的软件包。由于可以将同一智能合同的多个版本部署在不同的渠道中,因此最好设置如下软件包标签名称:
<smartContractName>_<channel>_<version>
- Chaincode Language(链代码语言):根据开发链代码时使用的语言在不同语言中进行选择。
- 目标对等节点:选择要安装链代码软件包的对等节点。
- 是否为打包链代码:如果要上载 zip 文件,请取消选中此复选框。选中
tar.gz
文件的复选框。 - 链代码源:单击上载链代码文件并选择链代码 zip 文件。
- 程序包标签:指定一个名称,该名称可以帮助您确定在不同的现有通道中安装的软件包。由于可以将同一智能合同的多个版本部署在不同的渠道中,因此最好设置如下软件包标签名称:
- 如果安装成功,我们将看到成功消息。下一步是在所选渠道中部署链代码,因此您必须设置与部署阶段相关的所有值,然后单击下一步。
- 渠道:选择要部署智能合同的渠道。
- 链代码名称:设置将在渠道上部署智能合同的名称。
- 版本:为此部署分配一个编号,该编号与先前安装的软件包保持一致。这样,您将能够将安装的软件包与部署在不同通道中的链代码相关联。
- 需要初始:如果在允许用户事务处理之前需要调用链代码的
init
方法,请选中此复选框。 - 背书策略:在部署期间指定背书策略。在此解决方案手册示例中,我们未使用背书策略。
- 专用数据收集:根据需要设置专用数据收集。在此解决方案手册示例中,我们不会设置专用数据收集。
初始化智能合同
处理 FT 和 NFT 令牌时,需要执行一组管理操作,然后才能执行业务方法。借助 Oracle Blockchain,所有管理任务都可以作为简单的 REST 调用来执行,大大减少了初始化智能合同所需的工作量。
注意:
在执行以下任何步骤之前,我们必须为被授予智能合同方法访问权限的用户在 REST 代理中创建 enrollmentIDs。注册是调用 REST API 的用户名与由区块链内部管理的账户之间的映射,代币将分配到这些账户,如在 REST 代理节点中创建注册主题中所述。使用以下 Postman 集合可以轻松初始化智能合同:下载 Postman 集合
在此 Postman 集合的 AdminSteps 文件夹中,有三个请求调用要为智能合同初始化执行。
Postman 集合已准备好使用,但有一组变量需要配置到您自己的环境中(密码、URL 等)。这些变量在 Postman 集合的 Variables(变量)选项卡中设置。下表显示了我们定义的所有变量,并且需要适应您的环境。
变量名称 | 变量值 |
---|---|
bc_founder_provider_url | https://org1-w.... |
bc_timeout | 60000 |
bc_nft_founder_userid1 | cmsleg001 |
bc_nft_founder_userid1_pwd | 口令 |
bc_nft_founder_userid2 | cmsfin001 |
bc_nft_founder_userid2_pwd | 口令 |
bc_nft_founder_userid3 | cmsrsk001 |
bc_nft_founder_userid4_pwd | 口令 |
bc_channel_name | 婚礼 |
bc_chaincode_name | 婚礼 |
查找可从区块链服务控制台访问 REST API 的端点。
- 智能合同初始化(初始管理用户帐户)。
- 为可以拥有 NFT 令牌的用户创建钱包。
- 为应具有该权限的用户分配 minter 角色。
AdminSteps
文件夹的调用。
- 初始化链代码 ( Step-0:Init Admin User Account ),指示允许哪些用户帐户执行管理任务。必须正确设置
init
方法的 args:args: Scaped array of user_ids with their org_ids
。{ "chaincode": "{{bc_nft_chaincode_name}}", "args": [ "init", "[{\"orgId\":\"org1\",\"userId\":\"cmsleg001\"},{\"orgId\":\"org1\",\"userId\":\"cmsfin001\"},{\"orgId\":\"org1\",\"userId\":\"cmsrsk001\"}]" ], "timeout": {{bc_timeout}}, "isInit": true, "sync": true }
- 为所有用户创建用户账户,这些用户可以是表示实物资产的 NFT 资产的托管人。可以通过执行 Step-1:Create account Postman 请求来完成。对于我们用例的细节,只有三个用户与属于网络的同一个组织相关。此调用必须执行次数与我们要为其创建帐户的用户相同。在本例中,每个参数有三次:
"createAccount", "org1", "cmsleg001", "nonfungible"
"createAccount", "org1", "cmsfin001", "nonfungible"
"createAccount", "org1", "cmsrsk001", "nonfungible"
{ "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name "args": [ "createAccount", "org1","cmsleg001","nonfungible" //Method, OrgID, UserID, fungible for FT / nonfungible for NFT ], "timeout": 60000, "sync": true }
- 设置允许哪个用户 mint 标记,在本例中,mint a token 表示创建一个新文件夹以存储一组新文档,因此您可以决定三个现有用户(cmsleg001 、cmsfin001 或 cmsrsk001 )中的哪个用户可以执行这些操作,对于这些用户,则从 Postman 集合执行请求 Step-2:AddRole 。
{ "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name "args": [ "addRole", //Method name "minter","org1","cmsleg001" //Role, OrgId, UserID ], "timeout": 60000, "sync": true }