快速掌握Solana SPL代币开发流程:从创建到发行(二)

470 阅读4分钟

前言

阅读本文之前,建议先查看我写的上一篇基础教程《Solana 核心概念:快速构建简单的dApp应用(一)》,这样阅读此篇文章更容易理解且上手操作。本教程提供了一个基于 Next.js 15、TypeScript 和 Tailwind CSS 的 Solana SPL 代币开发示例,实现了连接钱包、实时显示余额、创建代币、关联代币账户和铸造代币等功能,采用暗黑主题的前端 UI 设计。

部分效果图

image.png

image.png

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
    )
)

image.png

image.png

image.png

image.png

关联代币账户(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
    )
)

image.png

image.png

image.png

image.png

image.png

铸造代币

新创建的代币发行量是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,
    )
)

image.png

image.png

image.png

image.png

Solana RPC 节点推荐(提供免费额度)

具体代码实现

直接移步到github仓库下载查看:github.com/jackchen012…

总结

  1. 理解 SPL 代币标准及其在 Solana 中的应用
  2. 掌握 Token Mint 的创建和管理
  3. 学会使用 ATA 账户存储代币
  4. 实现代币的铸造