功能

铸造资产

正如我们在 Token Metadata 概述中讨论的那样,Solana 上的数字资产由几个链上账户和描述代币的链下数据组成。在本页面上,我们将介绍铸造这些资产的过程。

铸造过程

无论我们想要铸造可替代、半可替代还是不可替代资产,整体过程都是相同的:

  1. 上传链下数据。 首先,我们必须确保我们的链下数据已准备就绪。这意味着我们必须在某处存储一个描述我们资产的 JSON 文件。该 JSON 文件的存储方式和位置无关紧要,只要它可以通过 URI 访问即可。
  2. 创建链上账户。 然后,我们必须创建将保存我们资产数据的链上账户。具体创建哪些账户取决于我们资产的代币标准,但在所有情况下,都会创建一个元数据账户,并将存储我们链下数据的 URI
  3. 铸造代币。 最后,我们必须铸造与所有这些账户关联的代币。对于不可替代资产,这只是意味着从 0 铸造到 1,因为不可替代性禁止我们拥有大于 1 的供应量。对于可替代或半可替代资产,我们可以铸造任意数量的代币。

让我们更详细地深入了解这些步骤,同时提供具体的代码示例。

上传链下数据

您可以使用任何服务上传链下数据,或者只需将其存储在自己的服务器上,但值得注意的是,Umi SDK 可以提供帮助。它使用插件系统,允许您选择您选择的上传器,并为您提供统一的界面来上传数据。

上传资产和 JSON 数据

const [imageUri] = await umi.uploader.upload([imageFile])
const uri = await umi.uploader.uploadJson({
name: 'My NFT',
description: 'This is my NFT',
image: imageUri,
// ...
})

现在我们有了 URI,我们可以继续下一步。

接下来的步骤显示如何分两步创建账户和铸造代币。在页面底部代码示例,这些辅助函数结合了这些步骤,使创建不同代币类型更容易。

创建铸造和元数据账户

要创建您选择的代币标准所需的所有链上账户,您可以简单地使用 Create V1 指令。它将适应请求的代币标准并相应地创建正确的账户。

例如,NonFungible 资产将创建一个 Metadata 账户和一个 MasterEdition 账户,而 Fungible 资产只会创建一个 Metadata 账户。

此外,如果提供的铸造账户不存在,它将为我们创建。这样,我们甚至不需要调用底层的 Token 程序来在向其添加元数据之前准备我们的代币。

此指令接受各种参数,我们的 SDK 尽最大努力为它们提供默认值,因此您不需要每次都填写所有参数。话虽如此,以下是您可能感兴趣的参数列表:

  • Mint:资产的铸造账户。如果它不存在,它必须作为签名者提供,因为它将被初始化。通常,我们为此目的生成一个新的密钥对。
  • Authority:铸造账户的权限。这是允许或将被允许从铸造账户铸造代币的账户。如果 SDK 支持,这将默认为"身份"钱包——即已连接的钱包。
  • NameURISeller Fee Basis PointsCreators 等:要存储在元数据账户上的资产数据。
  • Token Standard:资产的代币标准。

createV1 是一个辅助函数,可以初始化铸造账户并创建元数据账户。如果铸造已经存在,它将只创建元数据账户。如果您正在寻找如何使用 createMetadataAccountV3,您应该改用此函数。

1import { generateSigner, percentAmount } from '@metaplex-foundation/umi';
2import {
3 createV1,
4 TokenStandard,
5} from '@metaplex-foundation/mpl-token-metadata';
6
7// Assuming umi is set up with mplTokenMetadata plugin
8// See getting-started for full setup
9
10const mint = generateSigner(umi);
11
12// Create the onchain accounts (Mint + Metadata + MasterEdition for NFTs)
13await createV1(umi, {
14 mint,
15 authority: umi.identity,
16 name: 'My NFT',
17 uri: 'https://example.com/my-nft.json',
18 sellerFeeBasisPoints: percentAmount(5.5),
19 tokenStandard: TokenStandard.NonFungible,
20}).sendAndConfirm(umi);
21
22console.log('Created NFT accounts');
23console.log('Mint:', mint.publicKey);

请注意,在 Rust 中设置 mint 账户时,需要指定一个 bool 标志来指示账户是否为签名者——如果 mint 账户不存在,则需要是签名者。

铸造代币

一旦为我们的资产创建了所有链上账户,我们就可以为其铸造代币。如果资产是不可替代的,我们将简单地铸造其唯一的代币,否则我们可以铸造任意数量的代币。请注意,不可替代资产只有在铸造了其唯一代币后才有效,因此这是该代币标准的强制步骤。

我们可以使用 Token Metadata 程序的 Mint V1 指令来实现这一点。它需要以下参数:

  • Mint:资产的铸造账户地址。
  • Authority:可以授权此指令的权限。对于不可替代资产,这是元数据账户的更新权限,否则,这指的是铸造账户的铸造权限
  • Token Owner:接收代币的钱包地址。
  • Amount:要铸造的代币数量。对于不可替代资产,这只能是 1。
  • Token Standard:资产的代币标准(我们的 JavaScript SDK 需要)。程序不需要此参数,但我们的 SDK 需要它,以便它们可以为大多数其他参数提供适当的默认值。
1import { mintV1, TokenStandard } from '@metaplex-foundation/mpl-token-metadata';
2
3// Assuming umi is set up with mplTokenMetadata plugin
4// mint from createV1
5
6const mintPublicKey = mint.publicKey; // From the created mint
7const tokenOwner = umi.identity.publicKey; // Wallet to receive the token
8
9// Mint the NFT token
10await mintV1(umi, {
11 mint: mintPublicKey,
12 authority: umi.identity,
13 amount: 1,
14 tokenOwner,
15 tokenStandard: TokenStandard.NonFungible,
16}).sendAndConfirm(umi);
17
18console.log('Minted NFT to:', tokenOwner);

我们正在设置 master_edition,因为铸造 NonFungible 需要它;如果 token 账户不存在并且将初始化一个,则需要 token_owner

创建辅助函数

由于创建数字资产是 Token Metadata 的重要组成部分,我们的 SDK 提供了辅助方法来使该过程更容易。也就是说,这些辅助方法以不同的方式组合 Create V1Mint V1 指令,具体取决于我们想要创建的代币标准。

创建辅助函数