本文详细介绍了如何使用Sugar(Candy Machine)和Umi(Metaplex JS协议)在Solana上部署NFT收藏品,包括创建钱包、配置环境、上传资产、部署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 有一些显著改进:
在本指南中,你将使用 Solana CLI 创建一个新钱包,空投一些 SOL,并使用 Sugar 在 Solana 的开发网部署 Candy Machine。然后,你将使用 Solana dApp Scaffold 和 Metaplex 的新模块化 JS 框架 Umi 将 Candy Machine 部署到网络上。
在终端中创建一个新的项目目录,输入以下命令:
mkdir sugar-demo
cd sugar-demo
在安装过程中,系统会询问你想使用哪个版本。V1.x 是针对 Candy Machine v2,V2.x 是针对 Candy Machine v3。本指南假定你使用的是 V2.x(Candy Machine v3)。如果你正在使用旧版本,请查看我们的指南 这里。
在终端中输入:
bash <(curl -sSf https://sugar.metaplex.com/install.sh)
注意:安装后可能需要重新启动终端。
如果一切正常,你应该看到如下内容:
你可以通过在终端中输入 sugar --version
来验证你的 Sugar 安装。你应该看到类似的内容:
QuickNode % sugar --version
sugar-cli 2.5.0
Sugar 的一个酷新功能是它允许你使用 Solana CLI 设置钱包和 RPC 配置,从而不需要在每个 Sugar 命令中重新输入它们。
我们首先需要创建一个新钱包,专门用于开发网测试,输入以下命令:
solana-keygen new --no-bip39-passphrase --outfile ./wallet.json
我们可以通过运行以下命令确认我们刚生成的钱包是 Solana CLI 将使用的钱包:
solana config set --keypair ./wallet.json
注意:在这个例子中,我们使用钱包的相对路径,因为我们不会改变目录,但是如果你愿意,可以包括一个完整路径。
要在 Solana 上构建,你需要一个 API 端点以连接到网络。你可以使用公开节点或部署和管理自己的基础设施;但是,如果你希望获得 8 倍更快的响应时间,可以将重担留给我们。
配置你的 Solana 开发网端点后,你可以运行以下命令,将 YOUR_QUICKNODE_URL
替换为你复制的 HTTP URL:
solana config set --url YOUR_QUICKNODE_URL
现在,为了为你的钱包提供资金,你可以运行命令:
solana airdrop 1
如果命令成功,你应该看到如下内容:
你也可以在终端中运行 solana balance
看到 1 SOL 余额。
如果你以前使用过 Candy Machine,这个过程会很熟悉。我们必须为每个数字资产创建一个 .json 文件,使用从 0 开始并按顺序递增的简单数字格式,永远不要跳过数字(例如,0.json 映射到 0.png,然后 1.json 映射到 1.png)。我们还可以创建一个可选的 collection.json 和 collection.png,以使 Sugar 能够自动创建链上集合。
Metaplex 提供了一套 样本资产,我们可以下载并使用以保持一致。你可以编辑 json 以包含你希望的任何值,只要它符合 URI json schema。
下载样本集并将内容解压到项目目录中的 ./assets/
(Sugar 将查找你文件的默认目录)。
在项目根文件夹中创建一个新文件 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
注意:你可能会看到警告“缺少 properties.category
”。这是正常的,因为该属性未包含在 Metaplex 示例文件中。
我们一切就绪!太棒了。让我们构建我们的 Candy Machine。
由于我们已使用 Solana CLI 设置了我们的 RPC 和钱包,并将我们的 assets
和 config.json
保存到 Sugar 的默认目录,我们的命令将非常简单!
在终端中输入:
sugar upload
你应会看到如下内容:
在终端中输入:
sugar deploy
你应会看到如下内容:
如果你收到“未找到区块哈希”的错误,请重试命令。
确保在本地存储你终端提供的 Candy Machine ID。我们稍后会需要它。
让我们确认一切是否按照预期正常工作。在终端中输入:
sugar verify
你应会看到如下内容:
做得好!
尝试使用 sugar 铸造 NFT。在终端中输入:
sugar mint
你应会看到如下内容:
默认情况下,当你部署 Candy Machine 时,只有你可以铸造 NFT。你必须实施 candy guards,定义其他人铸造你的 NFT 的标准(例如,开始时间、付款金额、付款代币、白名单代币等)。由于我们已在 config.json
中定义了我们的 guards,因此可以运行以下命令:
sugar guard add
太棒了!让我们创建一个铸造页面,与世界分享这个项目!
为了快速部署,我们将使用 Solana dApp Scaffold,这是一个方便的工具,包含预集成 Solana 钱包适配器的 Next.JS 应用。
在项目目录的终端中输入:
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
在 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。首先,复制 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', 'Wallet not connected!');
notify({ type: 'error', message: 'error', description: 'Wallet not connected!' });
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>Mint NFT </span>
</button>
</div>
</div>
);
};
我们需要将 CandyMint
组件添加到我们的主页视图中。打开 ./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);
让我们使用 QuickNode 端点和 mplCandyMachine、mplTokenMetadata 插件创建一个记忆化的 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', 'Wallet not connected!');
notify({ type: 'error', message: 'error', description: 'Wallet not connected!' });
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', `Mint successful! ${txid}`)
notify({ type: 'success', message: 'Mint successful!', txid });
getUserSOLBalance(wallet.publicKey, connection);
} catch (error: any) {
notify({ type: 'error', message: `Error minting!`, description: error?.message });
console.log('error', `Mint failed! ${error?.message}`);
}
}, [wallet, connection, getUserSOLBalance, umi, candyMachineAddress, treasury]);
让我们逐步理解发生了什么:
fetchCandyMachine
和 safeFetchCandyGuard
函数获取 Candy Machine 和 Candy Guard。这些都是我们铸造交易所需的。generateSigner
函数生成一个签名者。这将用于铸造我们的 NFT。transactionBuilder
函数创建一个事务。这将用于铸造我们的 NFT:setComputeUnitLimit
指令添加到交易中。这个安全措施防止由于超出计算单位限制而导致的交易失败。mintV2
指令添加到交易中。这个指令将铸造我们的 NFT。我们传入我们的 umi 实例和一个具有以下属性的对象:
candyMachine
:Candy Machine 的公钥。candyGuard
:Candy Guard 的公钥。nftMint
:我们之前生成的签名者。collectionMint
:集合铸币的公钥。collectionUpdateAuthority
:集合更新授权的公钥。mintArgs
:一个对象,包含与你 Candy Guard 相关的铸造参数(这可能因 Candy Guard 而异)。对于 solPayment
guard,我们必须传递付款的 destination
(财政库的公钥)。getUserSOLBalance
(内置于 scaffold 的商店操作)以更新用户的 SOL 余额。做得好!我们的网站现在应该能够铸造 NFT。
现在我们已经添加了铸造逻辑,让我们启动并测试该网站。在终端中运行以下命令:
yarn dev
这将在 localhost:3000 打开浏览器,你可以连接你的钱包,并有能力铸造 NFT。请在继续之前确认你的 Phantom Wallet 设置为开发网而不是主网。
你需要在你的 Phantom 钱包中拥有开发网 SOL 才能铸造 NFT。你可以使用 Solana CLI 为你的 Phantom 钱包空投,输入以下命令:
solana airdrop 1 YOUR_PHANTOM_WALLET_ADDRESS
一切准备就绪后,点击“铸造”。如果成功,你应该会看到这样的网站:
如果你看到“铸造失败”的错误,你可能没有足够的资金。添加资金后再试一次。你可以在购买后在钱包中查看 NFT。Phantom 可能需要一段时间才能在你的钱包中渲染 NFT。我们的 NFT 看起来是这样的:
这真是太棒了!做得好。
恭喜你!你使用 Metaplex Sugar 和 Umi 创建了 Candy Machine。你现在拥有了运行你自己的 NFT 铸造所需的所有工具。我们很高兴看到你正在创建什么 NFT!加入我们的 Discord 或通过 Twitter 与我们联系,分享你的 NFT 项目。
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!