本指南将全面介绍如何使用 OCAP Client 管理非同质化代币 (NFT),也称为资产的整个生命周期。您将学习如何从零开始创建新资产、更新其属性、建立用于标准化铸造的资产工厂,以及如何从该工厂获取新资产。
创建新资产
您可以使用 createAsset 方法在区块链上创建一个独立的唯一资产。每个资产都会被分配一个唯一的链上地址,该地址由其初始属性派生而来。
const { wallet } = getWallet(); // 用户的钱包对象
async function createNewAsset() {
try {
const [hash, address] = await client.createAsset({
moniker: 'My Unique Digital Artwork',
data: {
typeUrl: 'json',
value: {
description: 'A one-of-a-kind piece created by Artist X.',
imageUrl: 'https://example.com/path/to/image.png',
},
},
readonly: true,
transferrable: true,
wallet: wallet,
});
console.log(`Asset creation transaction sent: ${hash}`);
console.log(`New asset address: ${address}`);
return address;
} catch (error) {
console.error('Error creating asset:', error);
}
}
createNewAsset();参数
- moniker
string(required) — 资产的名称。 - parent
string(default:'') — 父资产的地址(如有)。 - data
object(required) — 资产的数据负载,必须包含 typeUrl 和 value。 - readonly
boolean(default:false) — 如果为 true,资产在创建后无法更新。 - transferrable
boolean(default:true) — 如果为 true,资产可以转移到另一个账户。 - ttl
number(default:0) — 资产首次消费后的存活时间(以秒为单位)。 - display
object— 包含资产显示信息的对象。 - endpoint
object— 包含资产端点详细信息的对象。 - tags
string[](default:[]) — 用于对资产进行分类的字符串数组。 - wallet
WalletObject(required) — 资产初始所有者的钱包对象。 - delegator
string(default:'') — 通过委托授权此交易的账户地址。
返回值
一个 Promise,它会解析为一个包含交易哈希和新资产链上地址的数组。
- response
Promise<[string, string]>— [交易哈希, 资产地址]
更新现有资产
如果资产创建时设置了 readonly: false,您可以使用 updateAsset 方法修改其 moniker 和 data 字段。通过资产的唯一地址来识别该资产。
const { wallet } = getWallet(); // 用户的钱包对象
const assetAddress = 'z362...'; // 要更新的资产地址
async function updateExistingAsset() {
try {
const hash = await client.updateAsset({
address: assetAddress,
moniker: 'My Updated Digital Artwork',
data: {
typeUrl: 'json',
value: {
description: 'An updated description for my unique piece.',
imageUrl: 'https://example.com/path/to/new_image.png',
},
},
wallet: wallet,
});
console.log(`Asset update transaction sent: ${hash}`);
} catch (error) {
console.error('Error updating asset:', error);
}
}
updateExistingAsset();参数
- address
string(required) — 要更新的资产的链上地址。 - moniker
string(required) — 资产的新名称。 - data
object(required) — 资产的更新数据负载。 - wallet
WalletObject(required) — 当前资产所有者的钱包对象。
返回值
一个 Promise,它会解析为交易哈希。
- response
Promise<string>— 交易哈希
创建资产工厂
资产工厂是用于创建多个相似资产的模板。它定义了铸造新资产的结构、规则和逻辑,比单独创建每个资产更高效。这对于发行活动门票、证书或收藏品等用例非常理想。
const { wallet } = getWallet(); // 工厂所有者的钱包
const factoryDefinition = {
name: 'Conference Ticket Factory',
description: 'Mints tickets for the 2024 Tech Conference.',
limit: 1000, // 最多可铸造 1000 张门票
input: {
// 定义铸造资产所需的数据
type: 'object',
properties: {
attendeeName: { type: 'string' },
ticketType: { type: 'string', enum: ['General', 'VIP'] },
},
},
output: {
// 定义铸造出的资产的结构
moniker: 'Ticket for {{attendeeName}}',
description: '{{ticketType}} admission for the 2024 Tech Conference.',
transferrable: false, // 门票不可转让
},
hooks: [],
};
async function createFactory() {
try {
const [hash, factoryAddress] = await client.createAssetFactory({
factory: factoryDefinition,
wallet: wallet,
});
console.log(`Factory creation transaction sent: ${hash}`);
console.log(`New factory address: ${factoryAddress}`);
} catch (error) {
console.error('Error creating asset factory:', error);
}
}
createFactory();参数
- factory
object(required) — 一个定义工厂属性和铸造逻辑的对象。- name
string(required) — 工厂的名称。 - description
string(required) — 工厂用途的描述。 - limit
number(default:0) — 可以从此工厂铸造的最大资产数量。0 表示无限制。 - trustedIssuers
string[]— 被授权从此工厂铸造资产的账户地址列表。 - input
object(required) — 定义铸造资产所需的输入数据。 - output
object(required) — 定义将被铸造的资产的结构和属性。 - hooks
object[]— 在铸造过程中执行的钩子列表。 - data
object— 与工厂一起存储的额外任意数据。
- name
- wallet
WalletObject(required) — 工厂所有者的钱包对象。
返回值
一个 Promise,它会解析为一个包含交易哈希和新工厂链上地址的数组。
- response
Promise<[string, string]>— [交易哈希, 工厂地址]
从工厂获取资产
从工厂获取资产是一个两步过程。首先,您准备铸造数据,这使您可以预览将要创建的资产。其次,您将交易提交到区块链以正式获取该资产。
这种分离很有用,因为它允许应用程序在用户签名并提交最终交易之前,向用户展示他们将要收到的东西。
步骤 1:准备资产数据
preMintAsset 方法接收工厂地址和用户提供的输入,以生成最终的资产数据。此过程在链下发生,不需要交易。
const factoryAddress = 'z2...'; // 先前创建的工厂地址
const { wallet: issuerWallet } = getIssuerWallet(); // 工厂所有者或受信任的发行方
const { wallet: userWallet } = getUserWallet(); // 将拥有新资产的用户的钱包
async function prepareAssetForMinting() {
try {
const mintingData = await client.preMintAsset({
factory: factoryAddress,
inputs: {
attendeeName: 'John Doe',
ticketType: 'VIP',
},
owner: userWallet.address,
wallet: issuerWallet,
});
console.log('Prepared asset data for minting:', mintingData);
return mintingData;
} catch (error) {
console.error('Error preparing asset:', error);
}
}步骤 2:发送交易
一旦铸造数据准备好,用户(未来的资产所有者)签名并发送 acquireAsset 交易。来自 preMintAsset 的 itx 对象将用作有效负载。
async function acquireNewAsset() {
// 首先,从步骤 1 获取铸造数据
const itx = await prepareAssetForMinting();
if (!itx) return;
try {
const hash = await client.acquireAsset({
itx: itx,
wallet: userWallet, // 用户的钱包签署交易
});
console.log(`Asset acquisition transaction sent: ${hash}`);
console.log(`New asset will be available at address: ${itx.address}`);
} catch (error) {
console.error('Error acquiring asset:', error);
}
}
acquireNewAsset();acquireAsset 的参数
- itx
object(required) — 从preMintAsset方法返回的内部交易对象。 - wallet
WalletObject(required) — 正在获取资产的用户的钱包。 - delegator
string(default:'') — 通过委托授权此交易的账户地址。
返回值
一个 Promise,它会解析为 acquireAsset 操作的交易哈希。
- response
Promise<string>— 交易哈希
从工厂铸造资产
除了用户主导的 acquireAsset 流程外,授权的发行方(例如工厂所有者或受信任的发行方)可以铸造一个资产并将其直接发送到用户的账户。此过程也使用 preMintAsset 来准备数据,但最终的交易是 mintAsset,由发行方签名。
此流程适用于空投、颁发证书或任何接收用户无需发起最终交易的情况。
步骤 1:准备资产数据
此步骤与获取流程相同。发行方调用 preMintAsset 在链下生成交易有效负载(itx)。
const factoryAddress = 'z2...'; // 工厂地址
const { wallet: issuerWallet } = getIssuerWallet(); // 工厂所有者或受信任的发行方
const userAddress = 'z1...'; // 将接收资产的用户的地址
async function prepareAssetForMinting() {
try {
const mintingData = await client.preMintAsset({
factory: factoryAddress,
inputs: {
attendeeName: 'Jane Smith',
ticketType: 'General',
},
owner: userAddress,
wallet: issuerWallet, // 此处使用发行方的钱包
});
console.log('Prepared asset data for minting:', mintingData);
return mintingData;
} catch (error) {
console.error('Error preparing asset:', error);
}
}步骤 2:发送铸造交易
发行方使用准备好的 itx 对象调用 mintAsset。交易由发行方的钱包签名,新创建的资产被分配给上一步中指定的所有者。
async function mintNewAsset() {
// 首先,从步骤 1 获取铸造数据
const itx = await prepareAssetForMinting();
if (!itx) return;
try {
// 发行方的钱包签署交易
const hash = await client.mintAsset({
itx: itx,
wallet: issuerWallet,
});
console.log(`Asset minting transaction sent: ${hash}`);
console.log(`New asset for ${userAddress} will be available at address: ${itx.address}`);
} catch (error) {
console.error('Error minting asset:', error);
}
}
mintNewAsset();mintAsset 的参数
- itx
object(required) — 从preMintAsset方法返回的内部交易对象。 - wallet
WalletObject(required) — 正在铸造资产的发行方的钱包。
返回值
一个 Promise,它会解析为 mintAsset 操作的交易哈希。
- response
Promise<string>— 交易哈希