译文出自:登链翻译计划[1] 译者:翻译小组[2] 校对:Tiny 熊[3]
概述
Solana 是一个新兴的区块链,旨在解决以太坊的可扩展性问题,这边文章将逐步介绍如何在 Solana 上创建一个 NFT。NFT 是 Non Fungible Token 的缩写,是一种非同质的 Token。当你创建一个 NFT 时,它类似于创建一个ERC20 代币[4];然而,关键的区别是 ERC20 永远只发行一种代币。在本指南中,我们将以编程方式创建 2 个独立的账户,一个账户用于铸造 NFT,另一个账户将接收 NFT。然后编写代码,在 Solana 上完成 NFT 的铸币和发送。如果你在任何时候被卡住了,请随时参考本指南末尾的完整代码。让我们开始铸币吧!
依赖条件:
- 已安装 NodeJS
- 熟悉终端命令/CLI
- 编辑器
- 已安装 TypeScript
什么是 Solana?
Solana 的目标很单一。目标是扩大区块链的规模,以便在全球范围内采用。Solana 实验室,Solana 协议的开发者,正在做一些不同的事情来实现这个梦想。
在调整性能方面,区块链技术有几个关键点。其中之一是共识机制。这就是节点如何一起沟通以得出相同的结论。比特币使用工作证明[5]或 PoW。币安智能链,也被称为 BSC,使用Staked Authority 证明[6]或 PoSA。而以太坊正在迁移到Proof of Stake[7]又称 PoS。正如你所知道的,当下共识绝不是一个已经解决了的游戏。
Solana 使用一种叫做历史证明[8]的共识。历史证明是通过时间戳解决方案来实现的;每笔交易都有一个时间戳,允许它在短短的几分之一秒内被网络的其他成员验证为合法交易。Solana 对八项技术[9]进行了解析,他们认为自己是最快、最具扩展性和最安全的区块链。
在本地创建项目
打开终端,导航到一个你想创建项目的文件夹。接下来,按照以下顺序运行命令:
代码语言:javascript复制mkdir SolanaNFT
npm install --prefix ./SolanaNFT @solana/web3.js @solana/spl-token
cd SolanaNFT
touch index.ts
第一个命令创建一个新的项目目录,名为SolanaNFT。用npm install --prefix ./SolanaNFT @solana/web3.js @solana/spl-token, 我们要安装 Solana 的 JavaScript API, @solana/web3.js 和 TypeScript 库 @solana/spl-token,用于与 SPL Token 程序交互。最后,通过touch index.ts,我们创建了一个 Typescript 文件, index.ts , 我们将在其中编写所有的代码。
连接到 Solana
在你选择的编辑器中打开SolanaNFT项目目录,让我们开始编写一些代码来连接到 Solana!
在index.ts文件中,我们首先要从 @solana/web3.js 和 @solana/spl-token导入所有我们需要的功能。添加以下两条导入语句:
代码语言:javascript复制import { clusterApiUrl, Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js";
import { createMint, getOrCreateAssociatedTokenAccount, mintTo, setAuthority, transfer } from "@solana/spl-token";
注意: 如果你在这几行代码中看到错误,那么你很可能没有安装库。确保你在正确的目录中,并再次安装它们。
在import语句下面,添加这个函数:
代码语言:javascript复制// 连接到SOLANA
(async () => {
// Connect to cluster
const connection = new Connection(clusterApiUrl('devnet'), "confirmed");
})
这里我们正在实例化一个新的连接实例。这需要两个参数,第一个参数是指向 Solana 网络的 URL 节点(端点)。在我们的例子中,_clusterApiUrl('devnet')_ 是一个方便的方法,指向 Solana Devnet 的公共节点,我们本教程中要使用 Devnet。Solana 有 3 个不同的网络:mainnet、testnet 和 devnet。devnet 是一个低风险的环境,你可以把 SOL air-drop
给自己。
随着连接的建立,我们现在可以创建 NFT 并执行其他相关步骤。
注意。我们往后写的每一个代码块都应该放在前一个代码块的正下方,都在顶层async函数的大括号内。在最后提供了完整的代码,可对照检查。
创建新钱包和 AIR-DROP SOL
我们需要完成的第一个任务是创建一个钱包账户,并为其提供资金。我们还需要确保每一步都成功完成,然后再继续下一步。下面是这段代码的样子:
代码语言:javascript复制//创建一个新的钱包并获取air-drop
const fromWallet = Keypair.generate();
const fromAirdropSignature = await connection.requestAirdrop(
fromWallet.publicKey,
LAMPORTS_PER_SOL
);
// 等待air-drop确认
await connection.confirmTransaction(fromAirdropSignature);
记住要在async函数中添加这段代码。现在让我们把它按行解析:
第 2 行:我们使用之前导入的Keypair类,通过调用generate() 方法来生成一个新的密钥对。这将创建一对新的公钥和私钥,并将其存储在 fromWallet。
第 4 行:请求向我们的钱包 air-drop 资金。requestAirdrop() 方法需要一个公钥和你想收到的 SOL 中的 lamports 数量。Lamports 相当于 Solana 的 Wei,是一个 SOL 可以被分割成的最小的数量。大多数需要数字的方法将默认是 lamport 的单位。在我们的例子中,LAMPORTS_PER_SOL是一个常数,代表 1 SOL 的 Lamports 数量。
第 9 行:为了确认 air-drop 是否成功,使用confirmTransaction方法并等待其成功。调用允许我们传入一个签名交易作为参数,并让程序等待,直到它被确认,然后再继续代码的其他部分。这很重要,因为我们下一步要支付费用,需要 air-drop 的资金。
创建 token 铸币器
我们现在需要创建铸币器,实现 token 铸币,并获取 Token 账户。
代码语言:javascript复制// 创建一个token铸币器
const mint = await createMint(
connection,
fromWallet, // Payer of the transact
fromWallet.publicKey, // Account that will control the minting
null, // Account that will control the freezing of the token
0 // Location of the decimal place );
createMint函数将用于创建实际代币,它需要以下参数:
- 与 Solana 网络的连接(connection)
- 将要支付费用的账户(fromWallet)
- 有权铸造此代币的账户的公钥(fromWallet.publicKey)
- 有权冻结此代币的账户的公钥。这个参数是可选的(null)
- token 的小数点位数。
关于这个函数及文章中使用的其他spl-token函数的更多信息,可访问Solana-labs.github.io 的文档页面[10]。
一旦创建了 token 铸币器,我们需要从fromWallet的 Solana 地址中获取 token 账户。如果它不存在就创建它。为此,我们将利用getorCreateAssociatedTokenAccount() 函数,传入之前的大部分参数,并将其存储在fromTokenAccount:
代码语言:javascript复制// Get the token account of the "fromWallet" Solana address. If it does not exist, create it.
const fromTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
fromWallet,
mint,
fromWallet.publicKey
);
译者注:Solana 合约(Programs)是无状态的,它们只是指令,而不存储任何数据/状态。数据存储被存储在独立的
账户
中,由账户持有数据。当调用 Solana 合约的函数时,你需要把持有数据账户传给函数。
你可以这样考虑监管权限:NFT 驻留在账户中,而你的钱包拥有这个账户。
密钥 -> 钱包 -> 账户 -> NFT (从上到下)
创建钱包及关联账户来接收 NFT
我们有一个账户来发送 NFT,现在还需要一个账户来接收 NFT。实现这一目标的代码应该非常熟悉,因为像我们之前那样,利用相同的函数和变量来生成一个新的账号。
代码语言:javascript复制// Generate a new wallet to receive the newly minted tokenconst
toWallet = Keypair.generate();
// Get the token account of the "toWallet" Solana address. If it does not exist, create it.
const toTokenAccount = await mint.getOrCreateAssociatedAccountInfo(
connection,
fromWallet,
mint,
toWallet.publicKey
);
上面的代码块用一组单独的密钥创建了一个钱包(toWallet),然后创建了一个账户,将mint变量链接到我们新创建的钱包。
铸造 NFT 并发送
现在是时候铸造一个 NFT 并将其发送给某人,花点时间看看下面的代码,以实现这一目标,并阅读注释以了解每个函数的作用:
代码语言:javascript复制// Minting 1 new token to the "fromTokenAccount" account we just returned/created.
let signature = await mintTo(
connection,
fromWallet, // 支付手续费
mint, // Mint for the account
fromTokenAccount.address, // 铸造到账号
fromWallet.publicKey, // 铸造权限
1 // 铸造数量
);
await setAuthority(
connection,
fromWallet, // 支付手续费
mint, // Account
fromWallet.publicKey, // 当前授权者
0, // 权限类型: "0" 表示铸造 Tokens
null // Setting the new Authority to null
);
signature = await transfer(
connection,
fromWallet, // 支付手续费
fromTokenAccount.address, // 源账号
toTokenAccount.address, // 目标账号
fromWallet.publicKey, // 源账号的Owner
1 // 转移数量
);
console.log("SIGNATURE", signature);
})();
我们将简要地谈谈setAuthority() 函数,因为它是最关键的部分之一。这个函数将撤销铸币权限,并确保我们不能再创建这种类型的代币。请注意,撤销动作不能被撤销。
要执行该程序,请相继运行以下命令:
代码语言:javascript复制tsc index.ts
node index.js
这两条命令将运行 TypeScript 文件,生成一个同名的 JavaScript 文件,并运行该文件。一段时间后,你应该看到终端中记录了一个交易签名。如果你访问Solana Explorer[11],你应该看到交易签名,它看起来会像这样:
区块链浏览器中显示的 Solana 交易
以下是完整代码(包含链接、铸造 NFT 及发送):
代码语言:javascript复制import { clusterApiUrl, Connection, Keypair, LAMPORTS_PER_SOL } from "@solana/web3.js";
import { createMint, getOrCreateAssociatedTokenAccount, mintTo, setAuthority, transfer } from "@solana/spl-token";
(async () => {
// Connect to cluster
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// Generate a new wallet keypair and airdrop SOL
const fromWallet = Keypair.generate();
const fromAirdropSignature = await connection.requestAirdrop(
fromWallet.publicKey,
LAMPORTS_PER_SOL
);
// Wait for airdrop confirmation
await connection.confirmTransaction(fromAirdropSignature);
// Create a new token
const mint = await createMint(
connection,
fromWallet, // Payer of the transaction
fromWallet.publicKey, // Account that will control the minting
null, // Account that will control the freezing of the token
0 // Location of the decimal place
);
// Get the token account of the fromWallet Solana address. If it does not exist, create it.
const fromTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
fromWallet,
mint,
fromWallet.publicKey
);
// Generate a new wallet to receive the newly minted token
const toWallet = Keypair.generate();
// Get the token account of the toWallet Solana address. If it does not exist, create it.
const toTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
fromWallet,
mint,
toWallet.publicKey
);
// Minting 1 new token to the "fromTokenAccount" account we just returned/created.
let signature = await mintTo(
connection,
fromWallet, // Payer of the transaction fees
mint, // Mint for the account
fromTokenAccount.address, // Address of the account to mint to
fromWallet.publicKey, // Minting authority
1 // Amount to mint
);
await setAuthority(
connection,
fromWallet, // Payer of the transaction fees
mint, // Account
fromWallet.publicKey, // Current authority
0, // Authority type: "0" represents Mint Tokens
null // Setting the new Authority to null
);
signature = await transfer(
connection,
fromWallet, // Payer of the transaction fees
fromTokenAccount.address, // Source account
toTokenAccount.address, // Destination account
fromWallet.publicKey, // Owner of the source account
1 // Number of tokens to transfer
);
console.log("SIGNATURE", signature);
})();
总结
恭喜你,从本教程中学到了一些东西,你已经成功地在 Solana 区块链上创建了一个 NFT。你要做的下一步是将这个独一无二的代币,与一些资产联系起来。在现在的市场上,它通常是一张随机生成的具有各种属性的图片,或者是一件独特的艺术品。如果你想了解如何做到这一点,你可以在这个教程[12]中了解如何做到这一点!
本翻译由 Duet Protocol[13] 赞助支持。
原文:https://www.quicknode.com/guides/web3-sdks/how-to-mint-an-nft-on-solana#
参考资料
[1]
登链翻译计划: https://github.com/lbc-team/Pioneer
[2]
翻译小组: https://learnblockchain.cn/people/412
[3]
Tiny 熊: https://learnblockchain.cn/people/15
[4]
ERC20代币: https://learnblockchain.cn/search/articles?word=ERC20
[5]
工作证明: https://learnblockchain.cn/search/articles?word=比特币
[6]
Staked Authority证明: https://academy.binance.com/en/articles/an-introduction-to-binance-smart-chain-bsc
[7]
Proof of Stake: https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/
[8]
历史证明: https://solana.com/news/proof-of-history---a-clock-for-blockchain
[9]
八项技术: https://solana.com/developers
[10]
Solana-labs.github.io的文档页面: https://solana-labs.github.io/solana-program-library/token/js/modules.html
[11]
Solana Explorer: https://explorer.solana.com/?cluster=devnet
[12]
这个教程: https://learnblockchain.cn/article/4149
[13]
Duet Protocol: https://duet.finance/?utm_souce=learnblockchain