如何在 Solana 上使用 Sugar 和 Umi (Candy Machine) 部署一个 NFT 合集

本文提供了一份详细的教程,指导用户如何使用已弃用的Sugar V2(基于Candy Machine V3)和Metaplex的Umi框架在Solana开发网上部署NFT合集。内容涵盖钱包设置、资产准备、Candy Machine配置、部署,以及创建NFT铸造用户界面,旨在提供历史教育参考。

Sugar V2 / Candy Machine V3 已弃用

本指南使用 Sugar V2 和 Candy Machine V3,它们已被弃用。对于新的 NFT 项目,请参阅如何使用 Metaplex Core Candy Machine 启动 NFT 系列。本指南仅用于历史教育目的。

在开始本指南之前

本指南将深入讲解如何使用 Sugar (Candy Machine) 和 Umi (Solana 的 Metaplex JS 协议) 在 Solana 上部署 NFT 系列。如果你想更快地完成这项任务并由我们来承担繁重的工作,我们推荐使用 Crossmint NFT Mint API [mainnet] 插件。通过使用 Crossmint NFT Mint API [mainnet],你可以避免创建 Candy Machine。使用 NFT Mint API 来创建系列,降低前期成本,并轻松铸造 NFT!

试试 Crossmint NFT Mint API [mainnet]

概述

你准备好在 Solana 上启动你的 NFT 系列了吗?Metaplex 的 Candy Machine CLI 工具 Sugar 是你快速启动的利器。如果你使用过以前版本的 Candy Machine,你会注意到 Sugar 有一些显著改进:

  • 改进的上传性能
  • 简化的用户体验 (UX)
  • 改进的错误处理

你将做什么

在本指南中,你将使用 Solana CLI 创建一个新钱包,空投一些 SOL,并使用 Sugar 在 Solana 的 devnet 上部署一个 Candy Machine。然后,你将使用 Solana dApp Scaffold 和 Metaplex 新的模块化 JS 框架 Umi 将你的 Candy Machine 部署到网络上。

你将需要什么

  • 已安装 Node.js (版本 16.15 或更高)
  • 已安装 Solana CLI
  • 已安装 Phantom WalletSolflare 扩展
  • 已安装 Metaplex Sugar (最新版本, V2.x+) (安装说明见下文)
  • 一个文本编辑器
  • 已安装 npm 或 yarn (我们将使用 yarn 初始化项目并安装必要的包。如果你更喜欢 npm,也可以使用它。)

设置你的项目

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

mkdir sugar-demo
cd sugar-demo

安装 Sugar

在安装过程中,你将被问及要使用哪个版本。V1.x 用于 Candy Machine v2,V2.x 用于 Candy Machine v3。本指南假设你正在使用 V2.x (Candy Machine v3)。如果你使用的是旧版本,请查看我们的这里的指南。

Mac 安装

在你的终端中输入:

bash <(curl -sSf https://sugar.metaplex.com/install.sh)

注意:安装后你可能需要重启终端

Windows 安装

  1. 这里下载 Windows 安装程序。
  2. 以管理员身份运行安装程序(右键点击 -> 以管理员身份运行)。如果你收到关于不受信任的二进制文件的警告,请尝试点击 更多信息,然后点击 仍然运行。如果你没有此选项,请按照以下步骤操作:
    • 右键点击可执行文件并选择 属性
    • 如果你信任 Metaplex 开发团队,请勾选 解除阻止 按钮,如下图所示。这将允许你在计算机上运行此二进制文件,因为 Microsoft 不会自动信任它。
    • 点击 应用确定
    • 再次运行安装程序

如果一切正常,你应该会看到类似以下内容:

Successful Windows Install Confirmation

你应该可以通过在终端中输入 sugar --version 来验证你的 sugar 安装。你应该会看到类似以下内容:

Quicknode % sugar --version
sugar-cli 2.5.0

设置新钱包

Sugar 的一项很酷的新功能是它允许你使用 Solana CLI 设置你的钱包和 RPC 配置,这样你就不需要再在每个 Sugar 命令中重新输入它们了。

我们首先需要使用以下命令专门为 devnet 测试创建一个新钱包:

solana-keygen new --no-bip39-passphrase --outfile ./wallet.json

我们可以通过运行以下命令确认我们刚刚生成的钱包是 Solana CLI 将使用的钱包:

solana config set --keypair ./wallet.json

注意:在此示例中,我们使用了钱包的相对路径,因为我们不会更改目录,但如果你愿意,可以包含完整路径。

建立与你的 Quicknode RPC 的连接

使用你的 Quicknode Endpoint 连接到 Solana 集群

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

请查看为什么超过 50% 的 Solana 项目选择 Quicknode 并在此处开始你的免费试用 here。我们将使用一个 Solana Devnet 端点。

复制 HTTP Provider 链接:

设置好 Solana Devnet 上的端点后,你现在可以运行此命令,将 YOUR_QUICKNODE_URL 替换为你复制的 HTTP URL:

solana config set --url YOUR_QUICKNODE_URL

现在要为你的钱包注资,你可以运行命令:

solana airdrop 1

如果命令成功,你应该会看到类似以下内容:

Airdrop success

你还可以在终端中运行 solana balance,查看其中是否有 1 SOL。

准备 NFT 资产

如果你以前使用过 Candy Machine,这个过程会很熟悉。我们必须为每个数字资产创建一个 .json 文件,使用一个简单的数字格式,从 0 开始并按顺序递增,绝不跳过任何数字(例如,0.json 映射到 0.png,然后 1.json 映射到 1.png)。我们还可以创建一个可选的 collection.jsoncollection.png,以使 Sugar 能够自动创建链上系列。

Metaplex 有一套示例资产,我们可以下载并使用它们以保持一致。你可以编辑 json 文件以包含你想要的任何值,只要它符合 URI json schema

下载示例集并将内容提取到你项目目录中的 ./assets/(Sugar 将查找文件的默认目录)。

配置 Candy Machine

在你的项目根文件夹中创建一个新文件 config.json

echo > config.json

打开文件并粘贴此配置:

{
    "number": 10,
    "symbol": "NB",
    "sellerFeeBasisPoints": 500,
    "isMutable": true,
    "isSequential": false,
    "ruleSet": null,
    "creators": [\
        {\
            "address": "YOUR_WALLET_ADDRESS",\
            "share": 100\
        }\
    ],
    "uploadMethod": "bundlr",
    "awsS3Bucket": null,
    "retainAuthority": true,
    "awsConfig": null,
    "nftStorageAuthToken": null,
    "shdwStorageAccount": null,
    "pinataConfig": null,
    "hiddenSettings": null,
    "guards": {
        "default": {
          "solPayment": {
            "value": 0.01,
            "destination": "YOUR_WALLET_ADDRESS"
          },
          "startDate": {
            "date": "2022-10-23T20:00:00Z"
          }
        }
      }
}

请务必将 YOUR_WALLET_ADDRESS 替换为你之前创建的钱包地址。

注意:你可以在终端中运行 solana address 以获取你刚刚创建的钱包地址。

现在,我们应该都准备好了。如果你一直跟着做到这一点,你的目录结构应该如下所示:

sugar-demo/
├── wallet.json
├── config.json
└── assets/
  ├── [0-9].png
  ├── [0-9].json
  ├── collection.png
  └── collection.json

Sugar 有一个内置的验证工具,可以让我们在继续之前检查错误。在终端中运行:

sugar validate

Sugar Validation Success

注意:你可能会看到警告“缺少 properties.category”。这没关系,因为该属性未包含在 Metaplex 示例文件中。

我们成功了!干得好。让我们构建我们的 Candy Machine。

创建 Candy Machine

因为我们已经使用 Solana CLI 设置了我们的 RPC 和钱包,并将我们的 assetsconfig.json 保存到 Sugar 的默认目录中,所以我们的命令将非常简单!

上传你的资产

在你的终端中输入:

sugar upload

你应该会看到类似以下内容:

Sugar Upload Success

部署 Candy Machine

在你的终端中输入:

sugar deploy

你应该会看到类似以下内容:

Sugar Deploy Success

如果你收到“Blockhash not found”错误,请尝试重新运行该命令。

请务必将终端中提供的 Candy Machine ID 本地存储。我们稍后会用到它。

验证 Candy Machine

让我们确保一切都按预期工作。在你的终端中输入:

sugar verify

你应该会看到类似以下内容:

Candy Machine Verified

干得漂亮!

测试你的 Candy Machine

尝试使用 sugar 铸造一个 NFT。在你的终端中输入:

sugar mint

你应该会看到类似以下内容:

Successful Sugar Mint

添加你的 Candy Guards

默认情况下,当你部署 Candy Machine 时,只有你可以铸造 NFT。你必须实施 candy guards 来定义其他人可以铸造你的 NFT 的标准(例如,开始时间、支付金额、支付 Token、白名单 Token 等)。由于我们已在 config.json 中定义了我们的 guards,我们可以运行以下命令:

sugar guard add

Successful Add Candy Guard

太棒了!让我们创建一个铸造页面来与世界分享这个项目!

设置铸造网站

为了快速部署,我们将使用 Solana dApp Scaffold,这是一个方便的工具,它包含一个已集成 Solana Wallet Adapter 的 Next.JS 应用程序。

克隆 dApp Scaffold

在你的项目目录中,在终端中输入:

git clone https://github.com/solana-labs/dapp-scaffold ./candy-machine-ui/
cd candy-machine-ui

安装依赖项

安装包含的依赖项。在你的终端中输入:

yarn

我们需要一些额外的 metaplex 包才能启动和运行我们的铸造网站。在你的终端中输入:

yarn add @metaplex-foundation/mpl-candy-machine@alpha @metaplex-foundation/mpl-token-metadata@alpha @metaplex-foundation/mpl-toolbox @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults @metaplex-foundation/umi-signer-wallet-adapters

创建 .env 文件

在 candy-machine-ui 文件夹中创建一个文件 .env

echo > .env

在新创建的 .env 文件中添加以下值(将值替换为你自己的):

NEXT_PUBLIC_RPC=<YOUR_QUICKNODE_URL>
NEXT_PUBLIC_CANDY_MACHINE_ID=<YOUR_CANDY_MACHINE_PUBKEY>
NEXT_PUBLIC_TREASURY=<YOUR_WALLET_ADDRESS>

如果你不记得你的 Candy Machine ID,你应该可以在 cache.json 文件的 program.candyMachine 字段中找到它。

所有信息都填写完毕后,你可以保存文件。

添加铸造 NFT 按钮

我们必须在铸造网站上添加一个按钮,以允许用户铸造 NFT。首先,复制 RequestAirdrop 组件并将其重命名为 CandyMint。在你的终端中,通过输入以下命令复制文件:

cp ./src/components/RequestAirdrop.tsx ./src/components/CandyMint.tsx

打开 CandyMint.tsx 并将导出的组件名称从 RequestAirdrop 更改为 CandyMint。你还应该将按钮中的文本从 <span>Airdrop 1 </span> 更改为 <span>Mint NFT </span>。 最后,让我们更新常量声明并清除 onClick 函数的内容,以便我们有一个干净的开始。你的文件应该如下所示:

//...默认导入(我们稍后会替换这些)

export const CandyMint: FC = () => {
    // 👇 更新这些常量声明
    const { connection } = useConnection();
    const wallet = useWallet();
    const { getUserSOLBalance } = useUserSOLBalanceStore();

    // TODO - 创建一个 Umi 实例

    // 👇 更新此 onClick 函数
    const onClick = useCallback(async () => {
      if (!publicKey) {
          console.log('error', '钱包未连接!');
          notify({ type: 'error', message: 'error', description: '钱包未连接!' });
          return;
      }
      // TODO - 在这里添加铸造逻辑
    }, []);

    return (
        <div className="flex flex-row justify-center">
            <div className="relative group items-center">
                <div className="m-1 absolute -inset-0.5 bg-gradient-to-r from-indigo-500 to-fuchsia-500
                    rounded-lg blur opacity-20 group-hover:opacity-100 transition duration-1000 group-hover:duration-200 animate-tilt"></div>
                <button
                    className="px-8 m-2 btn animate-pulse bg-gradient-to-br from-indigo-500 to-fuchsia-500 hover:from-white hover:to-purple-300 text-black"
                    onClick={onClick}
                >
                    <span>铸造 NFT </span>
                </button>
            </div>
        </div>
    );
};

我们需要将 CandyMint 组件添加到我们的 Home View。打开 ./sugar-demo/candy-machine-ui/src/views/home/index.tsx 并添加以下导入语句:

// 组件
import { RequestAirdrop } from '../../components/RequestAirdrop';
// 👇 添加此行
import { CandyMint } from '../../components/CandyMint';

并将 CandyMint 组件添加到 HomeView 组件中:

          <RequestAirdrop />
          {/* 👇 添加此行 */}
          <CandyMint />

干得好!你现在应该有一个新按钮,但在测试它之前,我们需要添加铸造功能。让我们开始吧。

添加铸造功能

返回 ./sugar-demo/candy-machine-ui/src/components/CandyMint.tsx 并将默认导入替换为以下内容:

import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { FC, useCallback, useMemo } from 'react';
import { notify } from "../utils/notifications";
import useUserSOLBalanceStore from '../stores/useUserSOLBalanceStore';
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { generateSigner, transactionBuilder, publicKey, some } from '@metaplex-foundation/umi';
import { fetchCandyMachine, mintV2, mplCandyMachine, safeFetchCandyGuard } from "@metaplex-foundation/mpl-candy-machine";
import { walletAdapterIdentity } from '@metaplex-foundation/umi-signer-wallet-adapters';
import { mplTokenMetadata } from '@metaplex-foundation/mpl-token-metadata';
import { setComputeUnitLimit } from '@metaplex-foundation/mpl-toolbox';
import { clusterApiUrl } from '@solana/web3.js';
import * as bs58 from 'bs58';

// 这些访问我们在 .env 文件中定义的环境变量
const quicknodeEndpoint = process.env.NEXT_PUBLIC_RPC || clusterApiUrl('devnet');
const candyMachineAddress = publicKey(process.env.NEXT_PUBLIC_CANDY_MACHINE_ID);
const treasury = publicKey(process.env.NEXT_PUBLIC_TREASURY);

创建 Umi 实例

让我们使用我们的 Quicknode Endpoint 和 mplCandyMachine 以及 mplTokenMetadata 插件创建一个 memoized Umi 实例。我们将用它来铸造我们的 NFT。将 // TODO - 创建 Umi 实例 替换为:

    const umi = useMemo(() =>
        createUmi(quicknodeEndpoint)
            .use(walletAdapterIdentity(wallet))
            .use(mplCandyMachine())
            .use(mplTokenMetadata()),
        [wallet, mplCandyMachine, walletAdapterIdentity, mplTokenMetadata, quicknodeEndpoint, createUmi]
    );

这将创建一个 Umi 实例,该实例使用通过钱包适配器连接的钱包、我们的 Quicknode 端点以及几个 Metaplex 插件。

添加铸造逻辑

让我们更新 onClick 函数以使用 Umi 的交易构建器铸造 NFT。将 onClick 函数替换为以下代码,然后我们将逐步解释发生了什么:

    const onClick = useCallback(async () => {
        if (!wallet.publicKey) {
            console.log('error', '钱包未连接!');
            notify({ type: 'error', message: 'error', description: '钱包未连接!' });
            return;
        }

        // 获取 Candy Machine。
        const candyMachine = await fetchCandyMachine(
            umi,
            candyMachineAddress,
        );
        // 获取 Candy Guard。
        const candyGuard = await safeFetchCandyGuard(
            umi,
            candyMachine.mintAuthority,
        );
        try {
            // 从 Candy Machine 铸造。
            const nftMint = generateSigner(umi);
            const transaction = await transactionBuilder()
                .add(setComputeUnitLimit(umi, { units: 800_000 }))
                .add(
                    mintV2(umi, {
                        candyMachine: candyMachine.publicKey,
                        candyGuard: candyGuard?.publicKey,
                        nftMint,
                        collectionMint: candyMachine.collectionMint,
                        collectionUpdateAuthority: candyMachine.authority,
                        mintArgs: {
                            solPayment: some({ destination: treasury }),
                        },
                    })
                );
            const { signature } = await transaction.sendAndConfirm(umi, {
                confirm: { commitment: "confirmed" },
            });
            const txid = bs58.encode(signature);
            console.log('success', `铸造成功!${txid}`)
            notify({ type: 'success', message: '铸造成功!', txid });

            getUserSOLBalance(wallet.publicKey, connection);
        } catch (error: any) {
            notify({ type: 'error', message: `铸造失败!`, description: error?.message });
            console.log('error', `铸造失败!${error?.message}`);
        }
    }, [wallet, connection, getUserSOLBalance, umi, candyMachineAddress, treasury]);

让我们逐步了解这里发生了什么:

  1. 首先,我们检查钱包是否已连接。如果没有,我们会通知用户并返回。
  2. 接下来,我们使用 mpl-candy-machine 包中的 fetchCandyMachinesafeFetchCandyGuard 函数获取 Candy Machine 和 Candy Guard。我们需要这些来进行铸造交易。
  3. 接下来,我们使用 Umi 的 generateSigner 函数生成一个 signer。这将用于铸造我们的 NFT。
  4. 接下来,我们使用 Umi 的 transactionBuilder 函数创建一个交易。这将用于铸造我们的 NFT:
    • 我们向交易添加了一个 setComputeUnitLimit 指令。这个安全措施可以防止交易因超出计算单元限制而失败。
    • 我们向交易添加了一个 mintV2 指令。这是将铸造我们的 NFT 的指令。我们传递了我们的 umi 实例和一个包含以下属性的对象:
      • candyMachine:Candy Machine 的公钥。
      • candyGuard:Candy Guard 的公钥。
      • nftMint:我们之前生成的 signer。
      • collectionMint:系列铸币的公钥。
      • collectionUpdateAuthority:系列更新权限的公钥。
      • mintArgs:一个包含与你的 Candy Guard 相关的铸造参数的对象(这可能因你的 Candy Guard 而异)。对于 solPayment guard,我们必须传递支付的 destination(即 treasury 的公钥)。
  5. 我们发送交易并通知用户结果。注意,umi 将交易签名返回为 Unit8Array,因此我们必须在显示给用户之前将其编码为 base58。
  6. 最后,我们调用 getUserSOLBalance(内置于脚手架中的存储操作)来更新用户的 SOL 余额。

干得好!我们的网站现在应该能够铸造 NFT 了。

铸造 NFT

现在我们已经添加了铸造逻辑,让我们启动并测试网站。在你的终端中,运行以下命令:

yarn dev

这将在 localhost:3000 打开浏览器,你可以在其中连接你的钱包并铸造 NFT。在继续之前,请确认你的 Phantom Wallet 已设置为 devnet 而非 mainnet。

你需要在 Phantom 钱包中拥有 devnet SOL 才能铸造 NFT。你可以使用 Solana CLI 将 SOL 空投到你的 Phantom 钱包,方法是在终端中输入此命令:

solana airdrop 1 YOUR_PHANTOM_WALLET_ADDRESS

准备就绪后,点击“铸造”。如果成功,你应该会看到一个像这样的网站:

Candy Machine Mint Page

如果你看到错误信息“铸造失败”,你可能没有足够的资金。在添加资金后请再试一次。你可以在购买后在你的钱包中查看 NFT。Phantom 可能需要一些时间才能在你的钱包中渲染 NFT。我们的看起来像这样:

Minted NFT in Wallet

真是甜蜜的 Sugar!干得好。

结论

恭喜!你使用 Metaplex Sugar 和 Umi 创建了一个 Candy Machine。你现在拥有运行自己 NFT 铸造所需的所有工具。我们很高兴看到你正在创建的 NFT!加入我们的 Discord 或通过 Twitter 联系我们分享你的 NFT 项目。

我们 ❤️ 反馈!

告诉我们你是否有任何反馈或对新主题的请求。我们很乐意听取你的意见。

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

0 条评论

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