Solana - 如何在Solana上创建NFT - Quicknode

  • QuickNode
  • 发布于 2025-01-30 21:11
  • 阅读 13

本文是关于如何在Solana网络上创建一个NFT的详细指南。首先,它介绍了Solana的背景以及其共识机制Proof of History,然后逐步引导读者通过具体的命令和代码示例,完成从连接Solana网络到最终成功铸造NFT的全过程。文章结构清晰,含有必要的代码示例和注释,适合希望深入了解Solana和NFT创建过程的开发者。

介绍

你好,亲爱的读者!欢迎来到 Solana 的新指南。

Solana 是一个区块链,承诺在解决我们可以在其他区块链(例如以太坊)中看到的可扩展性问题时做出很大贡献。

在本指南中,我们将一步步解释如何在 Solana 网络上创建一个 NFT。

要求:

  • 已安装 NodeJS
  • 熟悉使用终端 / CLI
  • 文本编辑器

什么是 Solana?

Solana 有一个非常独特的目标,即扩展区块链技术以实现全球采用。Solana Labs,即 Solana Protocol 背后的开发者,正在做一些事情,以实现这个梦想。

当谈到提高性能时,区块链技术有一些解决方案。其中之一是共识机制,这是节点之间相互通信并达成一致结论的方式。比特币使用一种称为 Proof of Work(工作量证明)的机制或 POW,BNB 智能链,也被称为 BSC,则使用 Proof of Staked Authority 或 PoSA,以太坊则正在向 Proof of Stake(权益证明)迁移。正如你所看到的,当前历史阶段的共识仍然没有被解决。

Solana 使用一种称为 Proof of History 的共识机制,这一机制通过时间戳的方式运作,每笔交易都有一个时间戳,可以在几分之一秒内允许网络其他部分验证为合法交易。

Solana 包含 八项主要技术,他们自己指出这些技术使他们有能力成为所有现存区块链中最快、最可扩展和最安全的。

连接到 Solana

我们将在本指南中使用 Solana Devnet。Solana 有 3 个不同的网络,主网(mainnet)、测试网(testnet)和一个开发网络(devnet)。最后一个,devnet 是一个非常低风险的环境,你可以自己获得 SOL(SOLANA 的代币)。

在连接到 devnet 之前,我们需要执行一些步骤来创建目录并安装主要库。

mkdir SolanaNFT
cd SolanaNFT
touch index.js
npm i @solana/web3.js@1 @solana/spl-token

这段命令将创建一个名为 SolanaNFT 的新文件夹,进入该新文件夹,创建一个名为 index.js 的文件,并安装两个库: @solana/web3.js 和 @solana/spl-token。

完成这些后,我们可以开始编写一些 Javascript 来连接到 Solana!在下面的代码中,可以看到如何连接到 Solana。

var web3 = require('@solana/web3.js');
var splToken = require('@solana/spl-token');
(async () => {
  // 连接到集群
  var connection = new web3.Connection(
    web3.clusterApiUrl("devnet"),
    'confirmed',
  );
})

在前两行中,我们正在导入最初安装的库。

在该函数中,你可以看到我们创建了一个新的实例 connection,它接受两个参数,第一个是指向 Solana 网络的 URL。在这种情况下,我们使用一个非常便捷的方法 web3.clusterApiUrl("devnet") 来指向 Solana 的 devnet。

连接建立后,我们现在可以创建 NFT 并执行其他必要的步骤。

创建 NFT

这一部分很有意思!这是席卷整个社区的创新,独一无二且不可比较的 NFT!NFT,即不可替代代币(Non Fungible Token),是一个独特且无法复制的加密哈希。当创建 NFT 时,这与创建 ERC20 非常相似。然而,根本的区别在于,这个 NFT 只能创建一次。

要创建我们自己的 NFT,我们需要复制一系列步骤。我们可以现在查看这个列表,然后逐步了解如何编程。

我们需要做的事情:

  1. 创建一个钱包账户来创建 NFT。
  2. 创建一个钱包账户来接收 NFT。
  3. 创建 NFT 并发送它。

注意:每个代码块都将放在前一个代码块的下面,所有代码都在异步函数内。

通常来说,从创建钱包开始是一个好的起点,接着就是创建 NFT。

// 生成一个新的钱包并为该钱包生成新的 SOL。
  var fromWallet = web3.Keypair.generate();
  var fromAirdropSignature = await connection.requestAirdrop(
    fromWallet.publicKey,
    web3.LAMPORTS_PER_SOL,
  );
  // 等待 SOL 生成到钱包的确认
  while (true) {
        const { value: statuses } = await connection.getSignatureStatuses([fromAirdropSignature]);
        if (statuses[0] && statuses[0].confirmationStatus === 'confirmed' || statuses[0].confirmationStatus === 'finalized') {
            break;
        }
        await new Promise(resolve => setTimeout(resolve, 1000));
  }
  // 创建一个新 NFT
  let mint = await splToken.Token.createMint(
    connection,
    fromWallet,
    fromWallet.publicKey,
    null,
    9,
    splToken.TOKEN_PROGRAM_ID,
  );
  // 从 fromWallet 变量获取代币账户,代表 Solana 中的地址,如果不存在则创建
  let fromTokenAccount = await mint.getOrCreateAssociatedAccountInfo(
    fromWallet.publicKey,
  );

我在代码每部分中进行了注释,但我们将逐一审查每个方法并深入了解到每个参数及其功能。

  1. fromWallet - 使用方法 Keypair.generate() 创建一对新的公私钥。
  2. fromAirDropSignature - 方法 requestAirdrop() 获取一个公钥,要请求 SOL 的数量。Lamports 是 Solana 中的基本单位,相当于以太坊中的 wei,是可以拆分 SOL 的最小单位。大多数需要数量的方法将以 lamports 进行操作。在我们的案例中,LAMPORTS_PER_SOL 是一个常量,表示 1 SOL 等于多少 lamports。期望在继续之前确认交易。
  3. mint - 函数 createMint 负责创建我们的代币。它接受 6 个参数。

    • 与 Solana 网络的连接 (connection)
    • 付款账户 (fromWallet)
    • 拥有铸造(生成)此类代币的权限的账户公钥 (fromWallet.publicKey)
    • 拥有冻结此类代币权限的账户的公钥。这个参数是可选的 (null)
    • 代币的 'program id',你可以在 这里 阅读更多有关这些 'program id' 的信息。
  4. fromTokenAccount - 这将创建或请求与公钥 fromWallet.publicKey 关联的账户。可以将保管链视为:NFT 存在于账户中,而你的钱包(wallet)是该账户的所有者。

保管链:钥匙 -> 钱包 -> 账户

了解了这些后,我们可以移动到第 2 步!

我们已经有了一个账户用于发送 NFT,现在我们需要一个账户来接收 NFT。

接下来是代码实现:

// 生成一个新的钱包以接收新创建的代币
 var toWallet = web3.Keypair.generate();
// 获取 "toWallet" 地址的代币账户,如果不存在则创建
var toTokenAccount = await mint.getOrCreateAssociatedAccountInfo(
  toWallet.publicKey,
);

在这些步骤中,我们没有做太多工作。我们重复了之前使用的方法,因此在这里我不会深入细节。之前的代码块创建了一个拥有一对独立公私钥的钱包,并为我们变量 mint 创建了一个新的账户。

完成这两个步骤后,我们可以继续到第 3 步。

是时候铸造 NFT 并发送它了!

// 向 "fromTokenAccount" 账户铸造 1 个新代币
await mint.mintTo(
  fromTokenAccount.address, // 去向
  fromWallet.publicKey, // 谁有创造代币的权限
  [], // multisig
  1000000000, // 多少
);
await mint.setAuthority(
  mint.publicKey,
  null,
  "MintTokens",
  fromWallet.publicKey,
  []
)
// 创建交易
var transaction = new web3.Transaction().add(
  splToken.Token.createTransferInstruction(
    splToken.TOKEN_PROGRAM_ID,
    fromTokenAccount.address,
    toTokenAccount.address,
    fromWallet.publicKey,
    [],
    1,
  ),
);
// 签署交易,广播并确认已成功执行
var signature = await web3.
sendAndConfirmTransaction(
  connection,
  transaction,
  [fromWallet],
  {commitment: 'confirmed'},
);
console.log('SIGNATURE', signature);

太棒了!两个新方法负责创建 NFT 和代币的权限。方法 sendAndConfirmTransaction() 和 Transaction().add() 在之前的指南中已做过说明,如果你对那篇指南不熟悉,这里我留给你:如何在 Solana 发送交易,你可能想看看这篇指南以了解其内容。

那么,有两个方法需要解释,我们开始吧:

  1. mintTo() - 该方法接受已创建的代币并制造出一些新的代币。它接受 4 个参数:

  2. 目标:接收代币的账户地址 (fromTokenAccount.address) b. 拥有代币权威的公钥 (fromWallet.publicKey) c. 如果你的代币设置为多签名,这里可以传递多个地址来签署交易。在我们的情况下不是这样,因此我们传递一个空数组。 d. 我们想发送多少代币。由于这个特定代币有 9 位小数,我们正好发送 1 个代币给目标地址 (1000000000)。

  3. setAuthority() - 这是这个过程中最关键的部分。该函数将撤销创建更多代币的权限,确保不会再创建此类代币。此操作无法撤回,它接受 5 个参数:

  4. 代币账户 (mint.publicKey) b. 新的权限 (null) c. 该账户当前拥有的权限类型 (MintTokens) d. 当前持有代币的公钥 (fromWallet.publicKey) e. 一组可以签署的账户。在我们的情况下,是一个空数组。 ([])

覆盖了所有这些后,我们唯一剩下的动作就是查看 Solana Devnet 浏览器

如果你稍微往下看,可以看到账户现在正好有 1 个代币,并且我们已禁用创建新代币的能力,它现在代表一个 NFT。它正式成为一个独特的代币!

为了避免复制每个代码块,我将包含一个整合的代码块,以防万一你在组合时遇到不便。

var web3 = require('@solana/web3.js');
var splToken = require('@solana/spl-token');
(async () => {
  // 连接到集群
  var connection = new web3.Connection(
    web3.clusterApiUrl("devnet"),
    'confirmed',
  );
  // 生成一个新的钱包密钥对并空投 SOL
  var fromWallet = web3.Keypair.generate();
  var fromAirdropSignature = await connection.requestAirdrop(
    fromWallet.publicKey,
    web3.LAMPORTS_PER_SOL,
  );
  //等待空投确认
  while (true) {
        const { value: statuses } = await connection.getSignatureStatuses([fromAirdropSignature]);
        if (statuses[0] && statuses[0].confirmationStatus === 'confirmed' || statuses[0].confirmationStatus === 'finalized') {
            break;
        }
        await new Promise(resolve => setTimeout(resolve, 1000));
  }
  //创建新的代币铸造
  let mint = await splToken.Token.createMint(
    connection,
    fromWallet,
    fromWallet.publicKey,
    null,
    9,
    splToken.TOKEN_PROGRAM_ID,
  );
  //获取来自 fromWallet Solana 地址的代币账户,如果它不存在,则创建它
  let fromTokenAccount = await mint.getOrCreateAssociatedAccountInfo(
    fromWallet.publicKey,
  );
   // 生成一个新钱包以接收新铸造的代币
   var toWallet = web3.Keypair.generate();
  //获取来自 toWallet Solana 地址的代币账户,如果它不存在,则创建它
  var toTokenAccount = await mint.getOrCreateAssociatedAccountInfo(
    toWallet.publicKey,
  );
  //向 "fromTokenAccount" 账户铸造 1 个新代币
  await mint.mintTo(
    fromTokenAccount.address, // 发送到
    fromWallet.publicKey, // 代币权威
    [], // multisig
    1000000000, // 多少
  );
  await mint.setAuthority(
    mint.publicKey,
    null,
    "MintTokens",
    fromWallet.publicKey,
    []
  )
  // 向交易添加代币转移指令
  var transaction = new web3.Transaction().add(
    splToken.Token.createTransferInstruction(
      splToken.TOKEN_PROGRAM_ID,
      fromTokenAccount.address,
      toTokenAccount.address,
      fromWallet.publicKey,
      [],
      1,
    ),
  );
  // 签署交易,广播并确认
  var signature = await web3.sendAndConfirmTransaction(
    connection,
    transaction,
    [fromWallet],
    {commitment: 'confirmed'},
  );
  console.log('SIGNATURE', signature);
})();

总结

如果你读到这里,你已经从这篇教程中学到了一些东西,并在我们的 Solana 指南中玩得很开心,恭喜你!通过遵循这篇指南,你已经成功在 Solana 区块链上创建了一个 NFT。接下来的步骤是将这个独特且不可重复的代币与某个特定的东西链接起来。在当前市场上,通常是一些随机生成的带有多种属性的图片或一件独特的艺术品。如果你想学习如何确切地做到这一点,可以在 这个教程 中学习!

订阅我们的 新闻通讯 以获取更多关于以太坊的文章和指南。如果你有任何评论,请随时在我们的 Twitter 上评论。你也可以在我们的 Discord 服务器与我们交谈,那里有一些最优秀的开发者。

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

0 条评论

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