Solana - 如何使用Candy Machine V3和TypeScript创建Solana NFT集合

  • QuickNode
  • 发布于 2025-01-30 16:56
  • 阅读 16

本指南介绍如何使用 Metaplex 的新版本 JS SDK 在 Solana 上创建 NFT 收藏。尽管此指南使用了较旧的 SDK 版本,内容涵盖了创建 Candy Machine、添加项目、实施 Candy Guard、铸造 NFT 等重要步骤,并包含必要的代码示例和详细说明,适合希望在 Solana 上进行 NFT 开发的开发者。

废弃的依赖 - 请使用更新的指南

本指南使用了不再维护的旧版 Metaplex JS SDK。虽然我们会将此指南保留作为参考,但我们建议你参考我们的更新指南来使用 Candy Machines:

如果你有任何问题或反馈,请通过 DiscordTwitter 联系我们。

概述

你准备好在 Solana 上启动 NFT 收藏吗?如果是,那么你来对地方了!我们将探索 Metaplex 的新 JS SDK,它将 Candy Machine 的强大功能引入到你的 JavaScript 和 TypeScript 应用程序中,以实现快速和简单的铸造。Metaplex 添加了几项新功能,特别是 Candy Guards(用于限制或限制 NFT 铸造访问的工具),我们将在本指南中实现。

你将做些什么

在本指南中,你将通过自己的 TypeScript 应用程序创建一个新的 V3 Candy Machine。具体来说,你将:

  1. 创建一个 Candy Machine
  2. 向 Candy Machine 添加物品
  3. 为你的 Candy Machine 实施一个 Candy Guard
  4. 铸造一个 NFT!

你需要什么

设置你的项目

在终端中创建一个新的项目目录,使用以下命令:

mkdir cm-v3-demo
cd cm-v3-demo

为你的应用程序创建一个文件,app.ts

echo > app.ts

使用 "yes" 标志初始化你的项目,以便使用默认值创建新包:

yarn init --yes
#或
npm init --yes

创建一个启用 .json 导入的 tsconfig.json 文件:

tsc -init --resolveJsonModule true

安装 Solana Web3 依赖项

我们将需要添加 Solana Web3 和 SPL Token 库以进行此次练习。此外,我们将使用 Metaplex的 JS SDK。在终端中输入:

yarn add @solana/web3.js@1 @metaplex-foundation/js
#或
npm install @solana/web3.js@1 @metaplex-foundation/js

添加你的钱包并空投 SOL

在你选择的代码编辑器中打开 cm-v3-demo 目录(我们使用的是 VSCode)。为遵循本指南,你需要与你的 NFT 相关联的相同 Solana 文件系统钱包。你需要将此钱包存储在项目目录中的一个文件 guideSecret.json 中。

如果你没有纸钱包,你可以使用 这个脚本 创建一个新的。确保将你的钱包保存到项目目录中的 guideSecret.json

对于现有钱包,你可以使用下面的空投小部件向其发送一些 Devnet SOL:

🪂请求 Devnet SOL

空投 1 SOL(Devnet)

设置完成后,你的环境应如下所示:

设置你的应用

导入必要的依赖项

打开 app.ts,在 第 1 行 粘贴以下导入内容:

import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import { Metaplex, keypairIdentity, bundlrStorage, toMetaplexFile, toBigNumber, CreateCandyMachineInput, DefaultCandyGuardSettings, CandyMachineItem, toDateTime, sol, TransactionBuilder, CreateCandyMachineBuilderContext } from "@metaplex-foundation/js";
import secret from './guideSecret.json';

除了我们在上一步中创建的钱包外,我们还导入了一些来自 Solana Web3 和 Metaplex JS 库的必要方法和类。

设置你的 QuickNode 端点

要在 Solana 上构建,你需要一个 API 端点来连接到网络。你可以使用公共节点或部署和管理自己的基础设施;然而,如果你希望获得 8 倍更快的响应时间,可以将繁重的工作交给我们。

了解为什么超过 50% 的 Solana 项目选择 QuickNode,并在 这里 注册一个免费账户。我们将使用 Solana Devnet 节点。

复制 HTTP 提供程序链接:

app.ts 的导入语句下方,声明你的 RPC 并建立与 Solana 的 Connection 连接:

const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/'; // 👈 将其替换为你的 QuickNode Solana Devnet HTTP 端点
const SOLANA_CONNECTION = new Connection(QUICKNODE_RPC, { commitment: 'finalized' });

声明变量

你需要声明几个变量来运行你的脚本:

  • 你的源钱包(从你的私钥派生的密钥对)。
  • 资源 NFT 元数据 URL(注意:在本指南中,我们将重点研究 Candy Machine 的机制,因此我们将重用已经上传的 NFT 元数据和图像。你可以在此次练习中将图像和元数据上传纳入考量 - 有关如何使用 Metaplex JS SDK 上传到 Arweave 的更多信息,请查看我们的指南 如何使用 TypeScript 在 Solana 上铸造 NFT)。
  • 你想用作你的“收藏 NFT”的 NFT 铸造地址(这是你在钱包或交易所中可能看到的收藏的封面图像。有关更多信息,请访问 Metaplex.com)。
  • 你的 Candy Machine ID 占位符(我们将在后面更新此处)。
  • 一个 Metaplex 实例。

SOLANA_CONNECTION 下添加以下声明,以建立我们将使用的钱包、NFT 元数据和 Candy Machine ID 的占位符:

const WALLET = Keypair.fromSecretKey(new Uint8Array(secret));
const NFT_METADATA = 'https://mfp2m2qzszjbowdjl2vofmto5aq6rtlfilkcqdtx2nskls2gnnsa.arweave.net/YV-mahmWUhdYaV6q4rJu6CHozWVC1CgOd9NkpctGa2Q';
const COLLECTION_NFT_MINT = '';
const CANDY_MACHINE_ID = '';

通过调用我们在 Metaplex.make() 中书写的 SOLANA_CONNECTION 来建立新的 Metaplex 实例。我们的实例将使用我们刚创建的密钥对:

const METAPLEX = Metaplex.make(SOLANA_CONNECTION)
    .use(keypairIdentity(WALLET));

通过包含我们的网络连接和钱包,API 将使我们能够轻松提交交易到 Solana 网络。

注意:如果你打算上传自己的图像和元数据,则需要在此处加入额外的 .use() 调用来设置存储路线(本示例中没有必要):

    .use(bundlrStorage({
        address: 'https://devnet.bundlr.network',
        providerUrl: QUICKNODE_RPC,
        timeout: 60000,
    }))

创建集合 NFT

Candy Machine 利用一项功能,Metaplex 认证收藏,以验证链上的收藏。验证使第三方(例如交易所)能够对 NFT 集合进行分组和跟踪,并防止假冒。要创建我们的 Candy Machine,我们必须首先创建一个集合 NFT。这将作为你在交易所或钱包(如 Magic Eden 或 Phantom)中可能看到的“封面图像”。

我们所需做的就是使用 nfts().create() 创建一个新的 NFT。创建一个新函数 createCollectionNft

async function createCollectionNft() {
    const { nft: collectionNft } = await METAPLEX.nfts().create({
        name: "QuickNode Demo NFT Collection",
        uri: NFT_METADATA,
        sellerFeeBasisPoints: 0,
        isCollection: true,
        updateAuthority: WALLET,
      });

      console.log(`✅ - Minted Collection NFT: ${collectionNft.address.toString()}`);
      console.log(`     https://explorer.solana.com/address/${collectionNft.address.toString()}?cluster=devnet`);
}

确保将 isCollection 设置为 true,因为这将指明该 NFT 用于定义一个集合。

铸造你的 NFT。在应用末尾调用 createCollectionNft()

createCollectionNft();

然后,在终端中运行:

ts-node app

复制铸造 ID 并更新你的 COLLECTION_NFT_MINT 变量(对我们而言在第 11 行):

const COLLECTION_NFT_MINT = 'GWWhaWp7kJ3WKLkQTKyy5DEEGGF4TnCfHXXKxsBSbcwg';

在继续之前,请删除或注释掉你对 createCollectionNft() 的调用,因为我们将不再需要它。

启动 Candy Machine

Metaplex SDK 允许你仅通过一行代码启动 Candy Machine 🤯:

const { candyMachine } = await METAPLEX.candyMachines().create(candyMachineSettings);

然而,正如你所看到的,我们必须先为我们的 Candy Machine 设置一些设置。创建一个新函数 generateCandyMachine,在其中定义我们的 Candy Machine 设置,然后调用 candyMachines().create()

async function generateCandyMachine() {
    const candyMachineSettings: CreateCandyMachineInput<DefaultCandyGuardSettings> =
        {
            itemsAvailable: toBigNumber(3), // 收藏数量: 3
            sellerFeeBasisPoints: 1000, // 收藏的 10% 版权费
            symbol: "DEMO",
            maxEditionSupply: toBigNumber(0), // 不允许每个 NFT 的复制次数
            isMutable: true,
            creators: [\
                { address: WALLET.publicKey, share: 100 },\
            ],
            collection: {
                address: new PublicKey(COLLECTION_NFT_MINT), // 可以替换为你自己的 NFT 或上传一个新的
                updateAuthority: WALLET,
            },
        };
    const { candyMachine } = await METAPLEX.candyMachines().create(candyMachineSettings);
    console.log(`✅ - Created Candy Machine: ${candyMachine.address.toString()}`);
    console.log(`     https://explorer.solana.com/address/${candyMachine.address.toString()}?cluster=devnet`);
}

Candy Machine 设置定义了收藏的大小和每个 NFT 相同的关键数据点(例如版权费、创作者、符号、可变性)。我们在这个示例中定义了一些值 - 根据自己的需要稍作修改。有关 Candy Machine 设置的详细概述,请访问 Metaplex.com。请注意,你可以在此步骤中包括 Candy Guards - 我们将在下一个单独的步骤中添加它们,让你逐步了解如何更新 Candy Machine。

继续并启用你的 Candy Machine。在应用末尾调用 generateCandyMachine()

generateCandyMachine();

然后,在终端中运行:

ts-node app

你应该会看到一个 Candy Machine ID 和链接到它的 Solana Explorer:

复制 Candy Machine ID 并更新你的 CANDY_MACHINE_ID 变量(对我们而言在第 11 行):

const CANDY_MACHINE_ID = 'D2ARG7rXosZfnZwVBx3v7piG3H2tcYvWyw5YJCPuEpBU';

如果你遇到错误或有疑问,请在 Discord 上告诉我们,我们将乐意提供帮助。

在继续之前,请删除或注释掉你对 generateCandyMachine() 的调用,因为我们将不再需要它。

添加 Candy Guards

Candy Machine V3 包括一个新特性,称为 “Candy Guards”(或简称 Guards)。Guards 是可以限制对 Candy Machine 铸造的访问的模块化代码片段,甚至可以向其添加新功能!(来源:Metaplex.com)。截至 2022 年 11 月,Metaplex 具有 16 种不同的 Guards 可供选择:

  • 地址门:限制铸造为单个地址。
  • 白名单:使用钱包地址列表来确定谁被允许铸造。
  • 机器人税:可配置的税收以收取无效交易。
  • 结束日期:确定结束铸造的日期。
  • 网关:通过网关网络限制铸造,例如验证码集成。
  • 铸造限制:指定每个钱包铸造数量的限制。
  • NFT 销毁:限制铸造为指定收藏的持有者,要求销毁 NFT。
  • NFT 门:限制铸造为指定收藏的持有者。
  • NFT 支付:将铸造的价格设置为指定收藏的 NFT。
  • 赎回金额:根据铸造的总量确定铸造结束。
  • SOL 支付:将铸造的价格设置为 SOL。
  • 开始日期:确定铸造的开始日期。
  • 第三方签署人:需要交易上的额外签署人。
  • 代币销毁:限制铸造为指定代币的持有者,要求销毁代币。
  • 代币门:限制铸造为指定代币的持有者。
  • 代币支付:设置铸造的价格为代币数量。(来源:Metaplex.com

Metaplex 允许你组合、匹配和堆叠多个 Guards,以自定义 NFT 的铸造。你甚至可以创建各种“Guard Groups”,为不同用户创建自定义铸造体验。

对于我们的铸造,我们将设置一个 开始日期,一个 SOL 支付,以及每个用户 2 个铸造的限制。创建一个新函数 updateCandyMachine()

async function updateCandyMachine() {
    const candyMachine = await METAPLEX
        .candyMachines()
        .findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) });

    const { response } = await METAPLEX.candyMachines().update({
        candyMachine,
        guards: {
            startDate: { date: toDateTime("2022-10-17T16:00:00Z") },
            mintLimit: {
                id: 1,
                limit: 2,
            },
            solPayment: {
                amount: sol(0.1),
                destination: METAPLEX.identity().publicKey,
            },
        }
    })

    console.log(`✅ - Updated Candy Machine: ${CANDY_MACHINE_ID}`);
    console.log(`     https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);
}

我们的函数做了三件事:

  1. 获取我们的 Candy Machine:通过 ID 查找我们的 Candy Machine 并调用 .candyMachines().findByAddress() 返回一个 CandyMachine 对象。
  2. 通过调用 candyMachines().update() 更新我们的 Candy Machine。我们首先通过步骤 1 传递我们的 candyMachine,然后定义我们的 Guards。每个 Guard 具有特定的对象键和唯一的 GuardSettings。有关每个 Candy Guard 的设置,请查看 Metaplex.com

    • 开始日期:使用 Metaplex 的 toDateTime 方法输入开始 date
    • 铸造限制:传递此 Guard 的唯一 id(必要以便使用 Guard Groups 跟踪不同的限制)和一个 limit
    • SOL 支付:使用 Metaplex 的 sol 方法传递要收取的 SOL amount 以及 destination 公钥(你的铸造金库)。
  3. 记录指向 Solana Explorer 上交易的链接。

通过调用 updateCandyMachine()添加你的 Candy Guards。在应用末尾,添加以下内容:

updateCandyMachine();

然后,在终端中运行:

ts-node app

你应该在终端中看到类似内容:

做得好。在继续之前,请删除或注释掉你对 updateCandyMachine() 的调用,因为我们将不再需要它。

让我们向 Candy Machine 添加一些项目!

向 Candy Machine 添加项目

向你的 Candy Machine 添加项目的方法与更新非常相似。然而,我们需要调用 .insertItems() 而不是 .update()。创建一个新函数 addItems() 并添加以下代码:

async function addItems() {
    const candyMachine = await METAPLEX
        .candyMachines()
        .findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) });
    const items = [];
    for (let i = 0; i < 3; i++ ) { // 添加 3 个 NFT(我们的收藏大小)
        items.push({
            name: `QuickNode Demo NFT # ${i+1}`,
            uri: NFT_METADATA
        })
    }
    const { response } = await METAPLEX.candyMachines().insertItems({
        candyMachine,
        items: items,
      },{commitment:'finalized'});

    console.log(`✅ - Items added to Candy Machine: ${CANDY_MACHINE_ID}`);
    console.log(`     https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);
}

我们的函数做了三件事:

  1. 获取我们的 Candy Machine:通过 ID 查找我们的 Candy Machine 并调用 .candyMachines().findByAddress() 返回一个 CandyMachine 对象。
  2. 创建要添加的项目数组:insertItems() 方法要求我们传递一个包含每个要添加到 Candy Machine 的项目的 nameuriitems 数组。因为我们在“启动 Candy Machine”步骤中设置了 Candy Machine 的大小为 3,所以我们将使用简单的 for 循环添加 3 个项目。如果你添加的是独特的 NFTs,请在此处添加自定义逻辑。由于 Solana 交易大小是有限制的,因此每次调用只能传递有限数量的项目。“我们可以每次交易插入的项目数量将取决于配置行设置中定义的名称长度和 URI 长度属性。我们的名称和 URI 越短,我们在一笔交易中能够插入的项目就越多。”(Metaplex.com)。
  3. 通过调用 candyMachines().insertItems() 将项目插入 Candy Machine:我们首先传递步骤 1 中的 candyMachine,然后传递步骤 2 中定义的 items
  4. 记录指向 Solana Explorer 上交易的链接。

继续并通过调用 addItems() 添加你的项目。在应用末尾,添加以下内容:

addItems();

然后,在终端中运行:

ts-node app

你应该在终端中看到类似以下内容:

在继续之前,请删除或注释掉你对 addItems() 的调用,因为我们将不再需要它。

你现在应该有一个加载完毕的 Candy Machine,并设置了 Guards。让我们来进行测试吧!

铸造 NFT

与之前的步骤一样,我们需要获取我们的 Candy Machine 并调用一个新方法 candyMachines().mint()。创建一个新函数 mintNft()

async function mintNft() {
    const candyMachine = await METAPLEX
        .candyMachines()
        .findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) });
    let { nft, response } = await METAPLEX.candyMachines().mint({
        candyMachine,
        collectionUpdateAuthority: WALLET.publicKey,
        },{commitment:'finalized'})

    console.log(`✅ - Minted NFT: ${nft.address.toString()}`);
    console.log(`     https://explorer.solana.com/address/${nft.address.toString()}?cluster=devnet`);
    console.log(`     https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);
}

这段代码应该看起来相当熟悉 - 它的功能如下:

  1. 获取我们的 Candy Machine:通过 ID 查找我们的 Candy Machine 并调用 .candyMachines().findByAddress() 返回一个 CandyMachine 对象。
  2. 通过调用 candyMachines().mint() 铸造 NFT:我们首先传递步骤 1 中的 candyMachine,然后将我们的钱包公钥作为 collectionUpdateAuthority 传递(因为“这些信息不在 candyMachine 模型中,它是铸造指令所必须的” 来源:Metaplex.com)。
  3. 记录指向铸造和交易在 Solana Explorer 上的链接。

最后,通过调用 mintNft() 铸造一个 NFT。在应用的末尾添加以下内容:

mintNft();

然后,在终端中运行:

ts-node app

你应该在终端中看到类似内容:

做得好!让我们来测试一下滚动带上其中一个 Candy Guards。重新运行你的脚本。你应该会看到类似的结果,并向你的钱包铸造第二个 NFT。然后再试一次。

第三次尝试将会给你带来一些问题。为什么?如果深入到你的错误代码中,你应该会看到类似下面的内容:

  title: CandyGuardProgram > 达到允许的最大铸造数量,
  problem: 地址为 [Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g] 的程序 [CandyGuardProgram] 引发了代码 [6029] 的错误,表示达到允许的最大铸造数量。

如果你记得,我们创建了一个 mintLimit Candy Guard 限制任何钱包只能铸造 2 个 NFT,因此 Guard 阻止我们铸造第三个!相当酷,对吧?

下一步和总结

你现在拥有了一些有用的脚本,用于使用 TypeScript 与 Candy Machine 进行交互!我们期待看到你构建的内容。请加入 DiscordTwitter 共享你的项目!

寻找额外的挑战?尝试使用我们刚刚学习的脚本和 Solana dApp Scaffold 创建一个铸造网站!

我们❤️反馈!

如果你对本指南有任何反馈或问题,请 告诉我们。我们非常希望听取意见!

  • 原文链接: quicknode.com/guides/sol...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。