ERC-721 的脚手架 TypeScript NFT 项目
Blockchain App Builder 从 NFT 规范文件中获取输入并生成一个功能齐全的脚手架链代码项目。
该项目自动生成 NFT 生命周期类和函数,包括 CRUD 和非 CRUD 方法以及标记化 SDK。自动支持参数验证、编集/编集和透明持久性功能。
有关脚手架项目以及与 NFT 不直接相关的方法的信息,请参见 Scaffolded TypeScript Chaincode Project 。
型号
每个标记化模型类都扩展 OchainModel
类。透明持久性功能或简化的 ORM 在 OchainModel
类中捕获。
import * as yup from 'yup';
import { Id, Mandatory, Validate, Default, Embedded, Derived, ReadOnly } from '../../lib/decorators';
import { OchainModel } from '../../lib/ochain-model';
import { STRATEGY } from '../../lib/utils';
import { EmbeddedModel } from '../../lib/ochain-embedded-model';
export class ArtCollectionMetadata extends EmbeddedModel<ArtCollectionMetadata> {
@Validate(yup.string())
public painting_name: string;
@Validate(yup.string())
public description: string;
@Validate(yup.string())
public image: string;
@Validate(yup.string())
public painter_name: string;
}
@Id('tokenId')
export class ArtCollection extends OchainModel<ArtCollection> {
public readonly assetType = 'otoken';
@Mandatory()
@Validate(yup.string().required().matches(/^[A-Za-z0-9][A-Za-z0-9_-]*$/).max(16))
public tokenId: string;
@ReadOnly('artcollection')
public tokenName: string;
@Validate(yup.string().trim().max(256))
public tokenDesc: string;
@ReadOnly('ART')
public symbol: string;
@ReadOnly('erc721+')
public tokenStandard: string;
@ReadOnly('nonfungible')
public tokenType: string;
@ReadOnly('whole')
public tokenUnit: string;
@ReadOnly(["indivisible","singleton","mintable","transferable","burnable","roles"])
public behaviors: string[];
@ReadOnly({minter_role_name: "minter"})
public roles: object;
@ReadOnly({max_mint_quantity: 20000})
public mintable: object;
@Validate(yup.string())
public owner: string;
@Validate(yup.string())
public createdBy: string;
@Validate(yup.string())
public transferredBy: string;
@Validate(yup.string())
public creationDate: string;
@Validate(yup.string())
public transferredDate: string;
@Validate(yup.bool())
public isBurned: boolean;
@Validate(yup.string())
public burnedBy: string;
@Validate(yup.string())
public burnedDate: string;
@Validate(yup.string().max(2000))
public tokenUri: string;
@Embedded(ArtCollectionMetadata)
public metadata: ArtCollectionMetadata;
@Validate(yup.number())
public price: number;
@Validate(yup.boolean())
public on_sale_flag: boolean;
}
主管
主控制器类扩展了 OchainController
类。只有一个主控制器。
export class DigiCurrCCController extends OchainController{
您可以创建任意数量的类、函数或文件,但只能调用在主控制器类中定义的方法。其他方法处于隐藏状态。
您可以使用令牌 SDK 方法为业务应用程序编写定制方法。
自动生成的 NFT 方法
Blockchain App Builder 自动生成支持 NFT 和 NFT 生命周期的方法。您可以使用这些方法来初始化 NFT、管理角色和账户,以及完成其他 NFT 生命周期任务,而无需任何额外编码。控制器方法必须具有可调用的 @Validator(...params)
修饰器。
访问控制管理方法
-
addTokenAdmin
- 此方法将用户添加为链代码的
Token Admin
。此方法只能由链代码的Token Admin
调用。 -
removeTokenAdmin
- 此方法将用户删除为链代码的
Token Admin
。此方法只能由链代码的Token Admin
调用。 -
isTokenAdmin
- 如果函数的调用方为
Token Admin
,则此方法返回布尔值true
,否则返回false
。Token Admin
可以对区块链网络中的任何其他用户调用此函数。其他用户只能在自己的账户中调用此方法。 -
getAllTokenAdmins
- 此方法返回链代码
Token Admin
的所有用户的列表。此方法只能由链代码的Token Admin
调用。
标记配置管理方法
-
init
- 实例化链代码时会调用此方法。每个
Token Admin
都由adminList
参数中的userId
和orgId
信息标识。userId
是实例所有者或登录到实例的用户的用户名或电子邮件 ID。orgId
是当前网络组织中用户的成员服务提供者 (member service provider,MSP) ID。首次部署链代码时,adminList
参数是必需的。如果要升级链代码,请传递空列表 ([]
)。升级期间将忽略adminList
参数中的任何其他信息。 -
getAllTokens
- 此方法返回保存在状态数据库中的所有标记资产。此方法只能由链代码的
Token Admin
调用。此方法使用 Berkeley DB SQL 丰富的查询,并且只能在连接到远程 Oracle Blockchain Platform 网络时调用。 -
getAllTokensByUser
- 此方法返回指定用户拥有的所有令牌资产。此方法使用 Berkeley DB SQL 丰富的查询,并且只能在连接到远程 Oracle Blockchain Platform 网络时调用。此方法只能由链代码的
Token Admin
或账户所有者调用。 -
getTokenById
- 如果标记存在于状态数据库中,则此方法将返回标记对象。此方法只能由链代码的
Token Admin
或令牌所有者调用。 -
getTokenHistory
- 此方法返回指定令牌 ID 的历史记录。这是异步方法。只能在连接到远程 Oracle Blockchain Platform 网络时调用此方法。任何人都可以调用此方法。
-
getTokenObject
- 这是一种实用程序方法,返回指定令牌 ID 的令牌实例。许多自动生成的方法都使用此方法来提取令牌对象。您可以根据需要从定制方法调用此方法。创建标记化资产或类时,使用相应的
Token
类更新切换用例以返回正确的标记对象。当在规范文件中创建标记化资产时,区块链应用程序构建器中的ochain sync
命令会自动创建切换用例。此方法没有@Validator()
方法修饰器,这意味着此方法不可直接调用,只能从其他方法调用。 -
ownerOf
- 此方法返回指定令牌 ID 所有者的帐户 ID。任何人都可以调用此方法。
-
name
- 此方法返回令牌类的名称。任何人都可以调用此方法。
-
symbol
- 此方法返回令牌类的符号。任何人都可以调用此方法。
-
tokenURI
- 此方法返回指定令牌的 URI。任何人都可以调用此方法。
-
totalSupply
- 此方法返回铸造标记的总数。此方法只能由链代码的
Token Admin
调用。 -
totalNetSupply
- 此方法返回铸造标记的总数减去刻录的标记数。此方法只能由链代码的
Token Admin
调用。
帐户管理方法
-
createAccount
- 此方法为指定的用户和令牌创建帐户。必须为在任何时候都具有令牌的任何用户创建账户。账户跟踪用户拥有的 NFT 数。用户必须在网络中有账户才能完成与令牌相关的操作。每个用户只能创建一个 NFT 账户。
帐户 ID 是字母数字字符集,前缀为
oaccount~
,后跟当前网络组织中用户的成员服务提供商 ID (orgId
) 的 SHA-256 散列、实例所有者或登录实例的用户的用户名或电子邮件 ID (userId
) 以及常量字符串nft
。此方法只能由链代码的Token Admin
调用。 -
balanceOf
- 此方法返回指定用户持有的 NFT 总数。此方法只能由链代码的
Token Admin
或账户所有者调用。 -
getAllAccounts
- 此方法返回所有帐户的列表。此方法只能由链代码的
Token Admin
调用。此方法使用 Berkeley DB SQL 丰富的查询,并且只能在连接到远程 Oracle Blockchain Platform 网络时调用。 -
getAccountByUser
- 此方法返回指定用户的帐户详细信息。此方法只能由链代码的
Token Admin
或帐户的Account Owner
调用。 -
getUserByAccountId
- 此方法返回指定帐户的用户详细信息。所有用户都可以调用此方法。
-
getAccountHistory
- 此方法返回指定用户的帐户历史记录。这是异步方法。此方法只能由链代码的
Token Admin
或账户所有者调用。
角色管理方法
-
addRole
- 此方法向指定用户添加角色。此方法只能由链代码的
Token Admin
调用。 -
removeRole
- 此方法将角色从指定用户中删除。此方法只能由链代码的
Token Admin
调用。 -
getAccountsByRole
- 此方法返回指定角色的所有帐户 ID 的列表。此方法只能由链代码的
Token Admin
调用。 -
getUsersByRole
- 此方法返回指定角色的所有用户的列表。此方法只能由链代码的
Token Admin
调用。 -
isInRole
- 此方法返回布尔值以指示用户是否具有指定的角色。此方法只能由链代码的
Token Admin
或帐户的Account Owner
调用。
事务处理历史记录管理方法
-
getAccountTransactionHistory
- 此方法返回指定用户的账户事务处理历史记录。这是异步方法。此方法只能由链代码的
Token Admin
或账户所有者调用。 -
getAccountTransactionHistoryWithFilters
- 此方法返回指定用户的帐户事务处理历史记录,按
PageSize
、Bookmark
、startTime
和endTime
过滤。这是异步方法。只能在连接到远程 Oracle Blockchain Platform 网络时调用此方法。此方法只能由链代码的Token Admin
或账户所有者调用。 -
getTransactionById
- 此方法返回指定事务处理 ID 的事务处理历史记录。这是异步方法。此方法只能由链代码的
Token Admin
或账户所有者调用。 -
deleteHistoricalTransactions
- 此方法删除状态数据库中早于指定时间戳的事务处理。这是异步方法。此方法只能由链代码的
Token Admin
调用。
令牌行为管理方法 - 最小行为
-
create<Token Name>Token
- 此方法创建 (mint) NFT。资产和关联的属性保存在状态数据库中。此事务处理的调用方必须具有令牌账户。此事务处理的调用方将成为 NFT 的所有者。如果令牌规范文件包括
behaviors
的roles
部分和roles
的minter_role_name
属性,则事务处理的调用方必须具有 minter 角色。否则,任何调用方都可以 mint NFT。 -
update<Token Name>Token
- 此方法更新令牌属性。此方法只能由作为令牌的所有者或创建者的用户调用。创建令牌资产后,只有令牌所有者可以更新令牌定制属性。如果用户既是令牌所有者,又是令牌的创建者,他们还可以更新
TokenDesc
属性。无法更新令牌元数据。必须将所有令牌属性传递到此方法,即使您只想更新某些属性也是如此。
令牌行为管理方法 - 可转移行为
-
safeTransferFrom
- 这是一个异步函数。此方法将指定 NFT 的所有权从调用方转移到其他账户。此方法包括以下验证:
- 标记存在且未刻录。
- 发件人账户和接收者账户存在且不是同一账户。
- 发件人账户拥有令牌。
- 函数的调用者是发送者。
-
transferFrom
- 这是一个异步函数。此方法将指定 NFT 的所有权从发件人账户转移到接收者账户。呼叫者有责任传递正确的参数。此方法可由任何用户调用,而不仅仅是令牌所有者。此方法包括以下验证:
- 标记存在且未刻录。
- 发件人账户和接收者账户存在且不是同一账户。
- 发件人账户拥有令牌。
令牌行为管理方法 - 可燃行为
-
burn
- 此方法从调用者的帐户中停用或刻录指定的 NFT。此方法的调用者必须有一个帐户。除非令牌规范文件包含
burnable
行为,否则无法刻录令牌。如果在规范文件的roles
部分中未指定burner_role_name
属性,则令牌的所有者可以刻录令牌。如果在roles
部分中指定了burner_role_name
属性,则分配了刻录器角色(也是令牌的 minter(创建者)或所有者)的用户可以刻录令牌。 -
burnNFT
- 此方法从调用者的帐户中停用或刻录指定的 NFT,并返回令牌对象和令牌历史记录。此方法的调用者必须有一个帐户。除非令牌规范文件包含
burnable
行为,否则无法刻录令牌。如果在规范文件的roles
部分中未指定burner_role_name
属性,则令牌的所有者可以刻录令牌。如果在roles
部分中指定了burner_role_name
属性,则分配了刻录器角色(也是令牌的 minter(创建者)或所有者)的用户可以刻录令牌。
定制方法
您可以使用令牌 SDK 方法为业务应用程序编写定制方法。
以下示例说明如何在定制方法中使用令牌 SDK 方法。调用 sell
方法时,它会以指定价格发布要销售的令牌。
@Validator(yup.string(), yup.number())
public async sell(token_id: string, selling_price: number) {
try {
const token = await this.Ctx.ERC721Token.get(token_id);
const t = new ArtCollection(token)
/** * price is a custom asset
attribute to set the price of a non-fungible token in the
marketplace */
t.price = selling_price;
/** * on_sale_flag is a
custom asset attribute that maintains non-fungible token selling status in the
marketplace */
t.on_sale_flag = true;
await this.Ctx.ERC721Token.updateToken(t);
let msg = `Token ID : '${token_id}' has been posted for selling in the marketplace'`;
return {msg}
} catch(error) {
throw new Error(error.message);
}
}
NFT SDK 方法
访问控制管理方法
Token Admin
或 Account Owner
调用。您可以使用此功能来确保操作仅由目标用户执行。任何未经授权的访问都会导致错误。要使用访问控制函数,请从 ../lib/erc721-auth
模块导入 Authorization
类。import { ERC721Authorization } from '../lib/erc721-auth';
-
checkAuthorization
- 使用此方法可将访问控制检查添加到操作。这是一个异步函数。大多数自动生成的方法包括访问控制。对于具有多个帐户的用户,某些令牌方法只能由令牌的
ERC721Admin
或Account Owner
运行,也可以由MultipleAccountOwner
运行。checkAuthorization
方法是Authorization
类的一部分,您可以通过Ctx
对象访问该类。访问控制映射在../lib/constant.ts
文件中进行了介绍,如以下文本所示。可以通过编辑../lib/constant.ts
文件来修改访问控制。要使用您自己的访问控制或禁用访问控制,请从自动生成的控制器方法和定制方法中删除访问控制代码。export const TOKENACCESS = { ADMIN: { isUserTokenAdmin: ['Admin', 'MultipleAccountOwner'], addAdmin: ['Admin'], removeAdmin: ['Admin'], getAllAdmins: ['Admin'], }, TOKEN: { save: ['Admin'], getAllTokens: ['Admin'], get: ['Admin'], update: ['Admin'], getDecimals: ['Admin'], getTokensByName: ['Admin'], addRoleMember: ['Admin'], removeRoleMember: ['Admin'], isInRole: ['Admin', 'AccountOwner'], getTotalMintedTokens: ['Admin'], getNetTokens: ['Admin'], }, ROLE: { getAccountsByRole: ['Admin'], getUsersByRole: ['Admin'], }, TRANSACTION: { deleteTransactions: ['Admin'], }, ACCOUNT: { createAccount: ['Admin'], getAllAccounts: ['Admin'], getAccountsByUser: ['Admin', 'MultipleAccountOwner'], getAccount: ['Admin', 'AccountOwner'], history: ['Admin', 'AccountOwner'], getAccountTransactionHistory: ['Admin', 'AccountOwner'], getAccountBalance: ['Admin', 'AccountOwner'], getAccountOnHoldBalance: ['Admin', 'AccountOwner'], getOnHoldIds: ['Admin', 'AccountOwner'], }, ERC721ADMIN: { isUserTokenAdmin: ['Admin'], addAdmin: ['Admin'], removeAdmin: ['Admin'], getAllAdmins: ['Admin'], }, ERC721TOKEN: { getAllTokens: ['Admin'], getAllTokensByUser: ['Admin', 'AccountOwner'], get: ['Admin', TOKEN_OWNER], getTokensByName: ['Admin'], addRoleMember: ['Admin'], removeRoleMember: ['Admin'], isInRole: ['Admin', 'AccountOwner'], totalSupply: ['Admin'], totalNetSupply: ['Admin'], history: ['Admin'], }, ERC721ROLE: { getAccountsByRole: ['Admin'], getUsersByRole: ['Admin'], }, ERC721TRANSACTION: { deleteTransactions: ['Admin'], }, ERC721ACCOUNT: { createAccount: ['Admin'], getAllAccounts: ['Admin'], getAccountsByUser: ['Admin', 'MultipleAccountOwner'], history: ['Admin', 'AccountOwner'], getAccountTransactionHistory: ['Admin', 'AccountOwner'], getAccountTransactionHistoryWithFilters: ['Admin', 'AccountOwner'], balanceOf: ['Admin', 'MultipleAccountOwner'], } }
-
isUserTokenAdmin
- 如果函数的调用方为
Token Admin
,则此方法返回布尔值true
。否则,方法返回false
。这是一个异步静态函数。 -
addAdmin
- 此方法将用户添加为令牌链代码的
Token Admin
。 -
removeAdmin
- 此方法将用户删除为令牌链代码的
Token Admin
。 -
getAllAdmins
- 此方法返回所有
Token Admin
用户的列表。
标记配置管理方法
令牌配置管理方法基于 ERC-721 标准。要使用令牌配置管理方法,请从 ../lib/erc721-token
模块导入 Token
类。
-
totalSupply
- 此方法返回铸造的 NFT 总数。这是一个异步函数。
-
get
- 如果指定的令牌对象存在于状态数据库中,则此方法将返回该对象。这是一个异步静态函数。
-
isTokenType
- 此方法指示是否存在具有指定 ID 的令牌资产。这是一个异步静态函数。
-
createToken
- 此方法创建令牌并将其属性保存在状态数据库中。此方法只能由具有 minter 角色的用户调用。这是一个异步函数。
-
updateToken
- 此方法更新令牌属性。此方法只能由令牌的所有者或创建者调用。创建令牌资产后,只有令牌所有者可以更新令牌定制属性。如果用户既是令牌所有者,又是令牌的创建者,他们还可以更新
TokenDesc
属性。无法更新令牌元数据。必须将所有令牌属性传递到此方法,即使您只想更新某些属性也是如此。这是一个异步函数。 -
getByRange
- 此方法在内部调用网状结构网络
getStateByRange
方法。即使从分类账返回具有给定 ID 的任何资产,此方法也会将资产转换为调用方资产类型。这是一个异步静态函数。@validator(yup.string(), yup.string()) public async getDigiCurrGetByRange(startId: string, endId: string) { return await this.Ctx.ERC721TOken.getByRange(startId, endId, PaintingNft); }
-
history
- 此方法返回指定令牌的历史记录。这是一个异步静态函数。
-
getAllTokens
- 此方法返回保存在状态数据库中的所有标记资产。此方法使用 Berkeley DB SQL 丰富的查询,并且只能在连接到远程 Oracle Blockchain Platform 网络时调用。这是一个异步静态函数。
-
getAllTokensByUser
- 此方法返回指定帐户 ID 拥有的所有标记。这是一个异步静态函数。
-
ownerOf
- 此方法返回指定令牌所有者的帐户 ID。这是一个异步静态函数。
-
tokenUri
- 此方法返回指定令牌的 URI。这是一个异步静态函数。
-
getTokenUri
- 此方法返回指定令牌的 URI。这是一个异步静态函数。
-
symbol
- 此方法返回令牌类的符号。
帐户管理方法
-
generateAccountId
- 此方法返回帐户 ID,通过连接成员服务提供商 ID (
orgId
) 和用户名或电子邮件 ID (userId
) 并创建 SHA-256 散列来形成帐户 ID。 -
createAccount
- 此方法为指定的用户和令牌创建帐户。必须为在任何时候都具有令牌的任何用户创建账户。账户跟踪用户拥有的 NFT 数。用户必须在网络中有账户才能完成与令牌相关的操作。每个用户只能创建一个 NFT 账户。
帐户 ID 是字母数字字符集,前缀为
oaccount~
,后跟当前网络组织中用户的成员服务提供商 ID (orgId
) 的 SHA-256 散列、实例所有者或登录实例的用户的用户名或电子邮件 ID (userId
) 以及常量字符串nft
。此方法只能由链代码的Token Admin
调用。 -
getAllAccounts
- 此方法返回所有帐户的列表。此方法使用 Berkeley DB SQL 丰富的查询,并且只能在连接到远程 Oracle Blockchain Platform 网络时调用。
-
history
- 此方法返回指定帐户的帐户历史记录详细信息数组。
-
getUserByAccountId
- 此方法返回指定帐户的用户详细信息。
-
getAccountWithStatusByUser
- 此方法返回指定账户的用户详细信息,包括账户状态。此方法只能由链代码的
Token Admin
或帐户的Account Owner
调用。 -
getAccountByUser
- 此方法返回指定账户的用户详细信息。此方法只能由链代码的
Token Admin
或帐户的Account Owner
调用。 -
balanceOf
- 此方法返回指定用户保留的 NFT 总数。
角色管理方法
-
addRoleMember
- 此方法将角色添加到指定的用户和令牌。通过创建串联成员服务提供者 ID (
orgId
) 和用户名或电子邮件 ID (userId
) 的 SHA-256 散列来形成帐户 ID。这是一个异步函数。 -
removeRoleMember
- 此方法从指定用户和令牌中删除角色。通过创建串联成员服务提供者 ID (
orgId
) 和用户名或电子邮件 ID (userId
) 的 SHA-256 散列来形成帐户 ID。这是一个异步函数。 -
isInRole
- 此方法返回布尔值,以指示用户和令牌是否具有指定的角色。通过创建串联成员服务提供者 ID (
orgId
) 和用户名或电子邮件 ID (userId
) 的 SHA-256 散列来形成帐户 ID。这是一个异步函数。 -
getAccountsByRole
- 此方法返回指定角色的所有帐户 ID 的列表。
-
getUsersByRole
- 此方法返回指定角色的所有用户的列表。
事务处理历史记录管理方法
-
getAccountTransactionHistory
- 此方法返回指定帐户的事务处理历史记录详细信息数组。
-
getAccountTransactionHistoryWithFilters
- 此方法返回指定用户的帐户事务处理历史记录,按
PageSize
、Bookmark
、startTime
和endTime
过滤。只能在连接到远程 Oracle Blockchain Platform 网络时调用此方法。 -
getTransactionById
- 此方法返回
Transaction
资产的历史记录。 -
deleteHistoricalTransactions
- 此方法从状态数据库中删除早于指定日期的事务处理。
令牌行为管理 - 最小行为
-
getMaxMintQuantity
- 此方法返回令牌的最大可最小数量。如果未在规范文件中配置
max_mint_quantity
行为,则缺省值为 0,并且可以铸造无限数量的标记。 -
getTotalMintedTokens
- 此方法返回系统中指定令牌的可用标记总数。可用令牌的净数量是铸造令牌总数减去烧毁令牌的数量。这是一个异步函数。
令牌行为管理 - 可转移行为
-
safeTransferFrom
- 这是一个异步函数。此方法将指定 NFT 的所有权从调用方转移到其他账户。此方法包括以下验证:
- 标记存在且未刻录。
- 发件人账户和接收者账户存在且不是同一账户。
- 发件人账户拥有令牌。
- 函数的调用者是发送者。
-
transferFrom
- 这是一个异步函数。此方法将指定 NFT 的所有权从发件人账户转移到接收者账户。呼叫者有责任传递正确的参数。此方法可由任何用户调用,而不仅仅是令牌所有者。此方法包括以下验证:
- 标记存在且未刻录。
- 发件人账户和接收者账户存在且不是同一账户。
- 发件人账户拥有令牌。
令牌行为管理 - 可燃行为