跳到主要內容

管理資產 (NFT)

本指南將全面介紹如何使用 OCAP Client 管理非同質化代幣 (NFT) 的整個生命週期,NFT 也稱為資產。您將學習如何從頭開始建立新資產、更新其屬性、建立資產工廠以進行標準化鑄造,以及從該工廠獲取新資產。

建立新資產

您可以使用 createAsset 方法在區塊鏈上建立一個獨特的獨立資產。每個資產都會被分配一個獨一無二的鏈上地址,該地址由其初始屬性衍生而來。

javascript
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]> — [transactionHash, assetAddress]

更新現有資產

如果資產在建立時設定為 readonly: false,您可以使用 updateAsset 方法修改其 monikerdata 欄位。資產透過其唯一的地址來識別。

javascript
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> — transactionHash

建立資產工廠

資產工廠是建立多個相似資產的範本。它定義了鑄造新資產的結構、規則和邏輯,比單獨建立每個資產更有效率。這對於發行活動門票、證書或收藏品等使用場景非常理想。

javascript
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 — 與工廠一起儲存的額外任意資料。
  • wallet WalletObject (required) — 工廠擁有者的錢包物件。

返回值

一個 Promise,會解析為一個包含交易雜湊值和新工廠鏈上地址的陣列。

  • response Promise<[string, string]> — [transactionHash, factoryAddress]

從工廠獲取資產

從工廠獲取資產是一個兩步驟的過程。首先,您需要準備鑄造資料,這讓您可以預覽將要建立的資產。其次,您將交易提交到區塊鏈以正式獲取資產。

這種分離很有用,因為它允許應用程式在使用者簽署並提交最終交易之前,向使用者展示他們將要收到的內容。

步驟 1:準備資產資料

preMintAsset 方法會接收工廠地址和使用者提供的輸入,以產生最終的資產資料。此過程在鏈下發生,不需要交易。

javascript
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 交易。來自 preMintAssetitx 物件將用作負載。

javascript
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> — transactionHash

從工廠鑄造資產

除了由使用者主導的 acquireAsset 流程外,授權的發行者(如工廠擁有者或受信任的發行者)也可以鑄造資產並將其直接發送到使用者的帳戶。此過程同樣使用 preMintAsset 來準備資料,但最終的交易是 mintAsset,由發行者簽署。

此流程適用於空投、頒發證書或任何接收使用者無需發起最終交易的情況。

步驟 1:準備資產資料

此步驟與獲取流程相同。發行者呼叫 preMintAsset 在鏈下產生交易負載(itx)。

javascript
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。交易由發行者的錢包簽署,新建立的資產將分配給上一步驟中指定的所有者。

javascript
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> — transactionHash