前言
阅读本文之前,建议先查看我写的上一篇基础教程《Solana 核心概念:快速构建简单的dApp应用(一)》,这样阅读此篇文章更容易理解且上手操作。本教程提供了一个基于 Next.js 15、TypeScript 和 Tailwind CSS 的 Solana SPL 代币开发示例,实现了连接钱包、实时显示余额、创建代币、关联代币账户和铸造代币等功能,采用暗黑主题的前端 UI 设计。
部分效果图
SPL 代币概述
什么是 SPL 代币?
- 定义:
Solana Program Library(SPL)
是 Solana 的代币标准,类似于以太坊的 ERC20 标准 - 代币类型:
- 同质化代币(如 SOL)
- 非同质化代币(如 NFT)
代币创建包含信息
- 代币符号、总发行量、精度、描述、图像
- 指定铸造权限和冻结权限
创建 Token Mint
首先需要安装依赖:@solana/spl-token,它提供了绝大多数的 Solana 创建代币和操作代币过程中的工具和方法。
Token Mint 概念
- 定义:存储代币元数据的特殊账户
- 作用:管理代币的发行量、精度、铸造权限等
- 特点:每个代币都有唯一的 Token Mint 地址
const tokenMint = await createMint(
connection, // 它与Solana集群的JSON-RPC连接
payer, // 交易的付款人(需要提供密钥对的私钥才能完成,所以这个方法只适合在后端可以使用私钥的情况下运行)
mintAuthority, // 铸造权限账户
freezeAuthority, // 冻结权限账户(不需冻结设置NULL)
decimal // 小数精度
)
注意:如果是在开发dApp,就不能使用这个方法createMint()
,我们知道 Solana 中的所有交易都是由指令组成的。createMint 实际上也是由两个指令组成的,分别是 createAccount 和 createInitializeMintInstruction 组成的。两者的作用分别是创建一个 mint 账户和初始化 mint 账户。我们可以在前端去手动构建这个交易来完成相同的效果。
const tx = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: publicKey,
newAccountPubkey: mintKeypair.publicKey,
space: MINT_SIZE,
lamports,
programId: TOKEN_PROGRAM_ID,
}),
createInitializeMintInstruction(
mintKeypair.publicKey, // 创建临时密钥对生成的公钥地址
decimals, // 小数位数默认9位
publicKey, // mintAuthority
publicKey, // freezeAuthority
TOKEN_PROGRAM_ID, // SPL Token program account
)
)
关联代币账户(ATA)
在其他的区块链中,代币是直接存储在账户上的,而 Solana 中代币是存储在一个单独的账户上,这种账户也叫做 ATA 账户。ATA 是Associated Token Address
的缩写,也就是关联代币账户,这也是 Solana 中代币设计的独特之处。简单来说,ATA 是某个账户和某个代币之间的关联账户,它会记录这个账户中持有多少个代币。
在 Solana 中一个账户拥有多少种代币,就会创建多少个 ATA 账户。每个 ATA 账户都需要支付少量的 SOL 作为租金,这是为了防止有人创建大量的 ATA 账户来占用资源。
关联代币账户的概念
- 定义:记录钱包地址与特定代币的关联信息
- 特点:
- 每个代币都有单独的 ATA 账户
- ATA 账户需支付少量 SOL 作为租金
获取 ATA 账户是通过getOrCreateAssociatedTokenAccount()
这个方法来完成的。如果没有 ATA 账户这个方法,就会创建一个 ATA 账户。
// 获取 ATA 账户
const tokenAccount = await getOrCreateAssociatedTokenAccount(
connection, // 它与solana集群的JSON RPC连接
payer, // 交易的付款人
mint, // 新代币账户所需要关联的代币地址
payer.publicKey // owner新地址的所有人
)
在 dApp 中我们通常会使用getAssociatedTokenAddress()
方法来获取 ATA 账户的地址,然后再通过createAssociatedTokenAccountInstruction()
这个方法来创建 ATA 账户的指令。
const associatedToken = await getAssociatedTokenAddress(
mint,
owner,
false,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
const tx = new Transaction().add(
createAssociatedTokenAccountInstruction(
payer,
associatedToken,
owner,
mint,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
)
铸造代币
新创建的代币发行量是0,我们需要发行代币来让它流通,这个过程也叫做铸造代币。
铸造代币的概念
- 定义:将代币发行到指定账户中
- 默认情况:代币发行数量无上限
我们可以通过 SPL 库提供的mintTo()
方法来铸造代币,代码如下:
const txSignature = await mintTo(
connection, // 它与solana集群的JSON RPC连接
payer, // 交易的付款人
mint, // 新账户所需要关联的 Token Mint 账户
destination, // 收款人的 ATA 账户
authority, // 拥有权限的账户
amount, // 铸造的数量
)
在 dApp 中我们通常会使用createMintToInstruction()
方法来创建铸造代币的指令,在默认的情况下代币的发行总量是没有上限的。我们可以在铸造代币后,将铸币权限转移给其他账户或者程序,这样就可以控制代币的发行总量。
const tx = new Transaction.add(
createMintToInstruction(
mint,
destination,
authority,
amount,
)
)
Solana RPC 节点推荐(提供免费额度)
具体代码实现
直接移步到github仓库下载查看:github.com/jackchen012…
总结
- 理解 SPL 代币标准及其在 Solana 中的应用
- 掌握 Token Mint 的创建和管理
- 学会使用 ATA 账户存储代币
- 实现代币的铸造