ERC-721 的鷹架式 TypeScript NFT 專案
Blockchain App Builder 會從您的 NFT 規格檔取得輸入,並產生功能完整的鷹架式鏈碼專案。
專案會自動產生 NFT 生命週期類別和函數,包括 CRUD 和非 CRUD 方法,以及權杖化 SDK。系統會自動支援引數驗證、封送處理 (Marshal) / 解除封送處理 (unmarshal) 以及透明保存功能。
如需鷹架式專案的資訊,以及與 NFT 無直接相關的方法,請參閱 Scaffolded TypeScript Chaincode Project 。
Model
每個權杖化模型類別都會擴充 OchainModel
類別。在 OchainModel
類別中擷取「通透保存功能 (Transparent Persistence Capability)」或簡化的 ORM。
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
是目前網路組織中使用者的成員服務提供者 (MSP) ID。第一次部署鏈碼時,adminList
參數是必要的。如果您要升級鏈碼,請傳送空白清單 ([]
)。升級時會忽略adminList
參數中的任何其他資訊。 -
getAllTokens
- 此方法會傳回儲存在狀態資料庫中的所有記號資產。鏈碼的
Token Admin
只能呼叫此方法。此方法使用 Berkeley 資料庫 SQL 豐富查詢,且只能在連線至遠端 Oracle Blockchain Platform 網路時呼叫。 -
getAllTokensByUser
- 此方法會傳回指定使用者擁有的所有權杖資產。此方法使用 Berkeley 資料庫 SQL 豐富查詢,且只能在連線至遠端 Oracle Blockchain Platform 網路時呼叫。此方法只能由鏈碼的
Token Admin
或帳戶擁有者呼叫。 -
getTokenById
- 如果記號存在於狀態資料庫中,這個方法就會傳回記號物件。此方法只能由鏈碼的
Token Admin
或記號擁有者呼叫。 -
getTokenHistory
- 此方法會傳回指定記號 ID 的歷史記錄。這是非同步方法。連線至遠端 Oracle Blockchain Platform 網路時才能呼叫此方法。任何人都可以呼叫此方法。
-
getTokenObject
- 這是傳回指定記號 ID 之記號執行處理的公用程式方法。許多自動產生的方法會使用此方法來擷取記號物件。您可以視需要從自訂方法呼叫此方法。建立權杖化資產或類別時,請使用對應的
Token
類別更新交換器案例,以傳回正確的權杖物件。區塊鏈 App 產生器中的ochain sync
命令會在規格檔案中建立權杖化資產時,自動建立交換器案例。此方法沒有@Validator()
方法修飾器,這表示此方法無法直接呼叫,而且只能從其他方法呼叫。 -
ownerOf
- 此方法會傳回指定記號 ID 之擁有者的帳戶 ID。任何人都可以呼叫此方法。
-
name
- 此方法會傳回記號類別的名稱。任何人都可以呼叫此方法。
-
symbol
- 這個方法會傳回記號類別的符號。任何人都可以呼叫此方法。
-
tokenURI
- 此方法會傳回指定記號的 URI。任何人都可以呼叫此方法。
-
totalSupply
- 此方法會傳回已轉換記號的總數。鏈碼的
Token Admin
只能呼叫此方法。 -
totalNetSupply
- 這個方法會傳回經過 minted 記號減去燒錄記號數目的總數。鏈碼的
Token Admin
只能呼叫此方法。
帳戶管理方法
-
createAccount
- 此方法會為指定的使用者和記號建立一個帳戶。必須為任何時候會有權杖的任何使用者建立帳戶。帳戶會追蹤使用者擁有的 NFT 數目。使用者必須在網路中擁有帳戶,才能完成權杖相關作業。每位使用者只能建立一個 NFT 帳戶。
帳戶 ID 是一組文數字字元,前面加上
oaccount~
,後面加上目前網路組織中使用者之成員服務提供者 ID (orgId
) 的 SHA-256 雜湊、執行處理擁有者的使用者名稱或電子郵件 ID (userId
)、登入執行處理的使用者,以及常數字串nft
。鏈碼的Token Admin
只能呼叫此方法。 -
balanceOf
- 此方法會傳回指定使用者持有的 NFT 總數。此方法只能由鏈碼的
Token Admin
或帳戶擁有者呼叫。 -
getAllAccounts
- 此方法會傳回所有帳戶的清單。鏈碼的
Token Admin
只能呼叫此方法。此方法使用 Berkeley 資料庫 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
- 此方法會建立 (提示) NFT。資產和關聯的特性會儲存在狀態資料庫中。此交易的呼叫者必須具有權杖帳戶。此交易的呼叫者會成為 NFT 的擁有者。如果記號設定檔案包含
behaviors
的roles
區段和roles
的minter_role_name
特性,則交易的呼叫者必須具有較小的角色。否則,任何呼叫者都可以提示 NFT。 -
update<Token Name>Token
- 此方法會更新記號特性。只有權杖的擁有者或建立者可以呼叫此方法。建立權杖資產之後,只有權杖擁有者可以更新權杖自訂特性。如果使用者同時是權杖擁有者和權杖建立者,他們也可以更新
TokenDesc
特性。無法更新記號描述資料。您必須將所有記號特性傳遞至此方法,即使您只想要更新特定特性也一樣。
記號行為管理方法 - 可傳輸行為
-
safeTransferFrom
- 這是非同步函數。此方法會將指定 NFT 的所有權從呼叫程式轉移到另一個帳戶。此方法包含下列驗證:
- 記號存在且未被燒錄。
- 寄件者帳戶與接收者帳戶存在且不是相同帳戶。
- 寄件者帳戶擁有權杖。
- 函數的呼叫者是寄件者。
-
transferFrom
- 這是非同步函數。此方法會將指定 NFT 的所有權從寄件者帳戶轉移至接收者帳戶。呼叫者必須負責傳送正確的參數。任何使用者都可以呼叫此方法,而不只是記號擁有者。此方法包含下列驗證:
- 記號存在且未被燒錄。
- 寄件者帳戶與接收者帳戶存在且不是相同帳戶。
- 寄件者帳戶擁有權杖。
記號行為管理方法 - 可燒錄行為
-
burn
- 此方法會從來電者的帳戶停用或燒錄指定的 NFT。這個方法的呼叫程式必須要有一個帳戶。除非記號規格檔案包含
burnable
行為,否則無法燒錄記號。如果規格檔案的roles
區段中未指定burner_role_name
特性,則記號的擁有者可燒錄記號。如果在roles
區段中指定了burner_role_name
特性,則被指派燃燒者角色的使用者,同時也是記號的礦工 (建立者) 或擁有者可燒錄記號。 -
burnNFT
- 此方法會從呼叫者的帳戶停用或燒錄指定的 NFT,並傳回記號物件和記號歷史記錄。這個方法的呼叫程式必須要有一個帳戶。除非記號規格檔案包含
burnable
行為,否則無法燒錄記號。如果規格檔案的roles
區段中未指定burner_role_name
特性,則記號的擁有者可燒錄記號。如果在roles
區段中指定了burner_role_name
特性,則被指派燃燒者角色的使用者,同時也是記號的礦工 (建立者) 或擁有者可燒錄記號。
自訂方法
您可以使用記號 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
- 此方法會傳回 Minted NFT 的總數。這是非同步函數。
-
get
- 此方法會傳回狀態資料庫中存在的指定記號物件。這是非同步靜態函數。
-
isTokenType
- 此方法指示是否有指定 ID 的權杖資產存在。這是非同步靜態函數。
-
createToken
- 此方法會建立記號,並將其特性儲存在狀態資料庫中。只有具備較小角色的使用者才能呼叫此方法。這是非同步函數。
-
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 資料庫 SQL 豐富查詢,且只能在連線至遠端 Oracle Blockchain Platform 網路時呼叫。這是非同步靜態函數。
-
getAllTokensByUser
- 此方法會傳回指定帳戶 ID 所擁有的所有記號。這是非同步靜態函數。
-
ownerOf
- 此方法會傳回指定記號之擁有者的帳戶 ID。這是非同步靜態函數。
-
tokenUri
- 此方法會傳回指定記號的 URI。這是非同步靜態函數。
-
getTokenUri
- 此方法會傳回指定記號的 URI。這是非同步靜態函數。
-
symbol
- 這個方法會傳回記號類別的符號。
帳戶管理方法
-
generateAccountId
- 此方法會傳回帳戶 ID,透過串連成員服務提供者 ID (
orgId
) 和使用者名稱或電子郵件 ID (userId
) 來形成,然後建立 SHA-256 雜湊。 -
createAccount
- 此方法會為指定的使用者和記號建立一個帳戶。必須為任何時候會有權杖的任何使用者建立帳戶。帳戶會追蹤使用者擁有的 NFT 數目。使用者必須在網路中擁有帳戶,才能完成權杖相關作業。每位使用者只能建立一個 NFT 帳戶。
帳戶 ID 是一組文數字字元,前面加上
oaccount~
,後面加上目前網路組織中使用者之成員服務提供者 ID (orgId
) 的 SHA-256 雜湊、執行處理擁有者的使用者名稱或電子郵件 ID (userId
)、登入執行處理的使用者,以及常數字串nft
。鏈碼的Token Admin
只能呼叫此方法。 -
getAllAccounts
- 此方法會傳回所有帳戶的清單。此方法使用 Berkeley 資料庫 SQL 豐富查詢,且只能在連線至遠端 Oracle Blockchain Platform 網路時呼叫。
-
history
- 此方法會傳回指定帳戶的帳戶歷史記錄詳細資料陣列。
-
getUserByAccountId
- 此方法會傳回指定帳戶的使用者詳細資訊。
-
getAccountWithStatusByUser
- 此方法會傳回指定帳戶的使用者詳細資訊,包括帳戶狀態。此方法只能由鏈碼的
Token Admin
或帳戶的Account Owner
呼叫。 -
getAccountByUser
- 此方法會傳回指定帳戶的使用者詳細資訊。此方法只能由鏈碼的
Token Admin
或帳戶的Account Owner
呼叫。 -
balanceOf
- 此方法會傳回指定使用者保留的 NFT 總數。
角色管理方法
-
addRoleMember
- 這個方法會將角色新增至指定的使用者和記號。帳戶 ID 是透過建立串連成員服務提供者 ID (
orgId
) 的 SHA-256 雜湊和使用者名稱或電子郵件 ID (userId
) 來形成。這是非同步函數。 -
removeRoleMember
- 此方法會從指定的使用者和記號移除角色。帳戶 ID 是透過建立串連成員服務提供者 ID (
orgId
) 的 SHA-256 雜湊和使用者名稱或電子郵件 ID (userId
) 來形成。這是非同步函數。 -
isInRole
- 此方法會傳回布林值,指示使用者和記號是否具有指定的角色。帳戶 ID 是透過建立串連成員服務提供者 ID (
orgId
) 的 SHA-256 雜湊和使用者名稱或電子郵件 ID (userId
) 來形成。這是非同步函數。 -
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 的所有權從寄件者帳戶轉移至接收者帳戶。呼叫者必須負責傳送正確的參數。任何使用者都可以呼叫此方法,而不只是記號擁有者。此方法包含下列驗證:
- 記號存在且未被燒錄。
- 寄件者帳戶與接收者帳戶存在且不是相同帳戶。
- 寄件者帳戶擁有權杖。
權杖行為管理 - 可燒錄行為