Jacky Gu

Solana开发笔记: 使用spl-token发行并管理token

01 Jan 2025 Share to

使用spl-token程序发行并管理代币

Solana上的代币统称为spl代币,即:Solana program language Token,发行主要涉及以下几个模块:

  • 1- 初始化mint账户
  • 2- 铸造
  • 3- 转账
  • 4- 销毁
  • 5- 冻结
  • 6- 解冻

操作方式有:

  • 1- 通过spl-token程序实现
  • 2- 不通过anchor框架实现

Spl token有两个版本,一个是旧版,另一个是Spl token 2022版,也就是有扩展(extension)的版本。两个版本的源代码分别在:

  • Spl token旧版:https://github.com/solana-program/token
  • Spl token 2022版:https://github.com/solana-program/token-2022

使用spl-token程序实现代币发行

1- 发行代币:

spl-token create-token [FLAGS] [OPTIONS] [TOKEN_KEYPAIR]

创建一个代币,将返回mint的地址。

注意这个token是没有metadata的,也就是没有name,symbol等信息。

上述命令执行后,返回:

Address:  EWubm5eoqNqug1enZDeVn1fPRcDPabAo1vEnvUmXbeLg
Decimals:  9

Signature: 5Y6sCdX1aaUMkut8eVAGVBNXLWypdSG9KFSyqCKeTMzGrqbLUMc8zv34p1B2oTm6NS115dT41WhpnUUA4FAquLot

说明mint账户为:EWubm5eoqNqug1enZDeVn1fPRcDPabAo1vEnvUmXbeLg

注意:旧版spl-token的metadata需要使用mpl-token-metadata在程序中实现,无法使用命令行。如果想在spl-token中加载metadata,需要使用spl-token 2022版。

1.1- Mint authority

每个代币铸造厂(mint)有两个重要的属性,决定了谁有权铸造代币,以及谁有权冻结用户的token account。前者叫mint-authority, 后者叫freeze-authority

在用命令行创建代币时,使用--mint-authority指定。如果不指定,则为创建者自己;一般会指定到Mint账户自己,这个非常重要,因为大多数发币程序都会把mint权限设置为mint本身,以便在程序中执行铸造,而不能被其他人铸造。

如果要指定为Mint账户自己的话,需要先生成一个Keypair,然后在创建时,指定TOKEN_KEYPAIR,并同时使用--mint-authority指定到TOKEN_KEYPAIR的publicKey。

举例:

1- 执行

solana-keygen new -o ./111.json

执行后,创建了一个公钥地址为:E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi,私钥保存在当前目录的111.json文件中。(每次都会创建不同的keypair)

2- 执行

spl-token create-token --mint-authority E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi ./111.json

执行后,返回:

Creating token E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi under program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

Address:  E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi
Decimals:  9

Signature: 4YW7epGpyuyv2D8b9RKas83fz2eevM1QXtv4wikp1iCWoY696vGQBBDqyModUJioKbotvKUah1t6UCmu5kfPbnxK

执行:

spl-token display E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi

查看代币信息,会看到Mint authority: E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi,而不是之前指向用户的钱包地址。

1.2- Freeze authority

一般的freeze authority有两种设置,一是设为当前账户(也就是发币人账户),二是设置为mint账户。两种方法如下:

1.2.1- 把freeze authority设置成当前账户

执行指令:

spl-token create-token --enable-freeze

1.2.2- 把freeze authority设置成mint账户

同设置mint-authority时一样,先创建一个keypair,然后执行:

spl-token create-token --enable-freeze --mint-authority E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi ./111.json

也就是把mint账户同时设置为mint-authorityfreeze-authority,执行上述命令后,再执行spl-token display E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi,会发现:

Mint authority: E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi
Freeze authority: E5uvYf5qtpD3pvLh3GSm21mHSxnvwKARWKrTgGGfHBMi

如果把freeze-authority设置成mint账户,意味着程序外部无法冻结,只能在程序中实现对代币的冻结

1.3- 指定decimals

默认为9,可以指定为其他值,如:

spl-token create-token --decimals 6

2- 创建代币账户

代币账户即Associated token account,是用来存储spl-token的账户

spl-token create-account <Mint account>

得到mint account,如:i65fyKq25xRoXzKRzdfHkAACbdewhX5SsJS4sRMxsgd

3- 铸造代币

spl-token mint [FLAGS] [OPTIONS] <TOKEN_MINT_ADDRESS> <TOKEN_AMOUNT> [--] [RECIPIENT_TOKEN_ACCOUNT_ADDRESS]

如运行以下命令,将向账户i65fyKq25xRoXzKRzdfHkAACbdewhX5SsJS4sRMxsgd铸造1000个STT代币

spl-token mint EWubm5eoqNqug1enZDeVn1fPRcDPabAo1vEnvUmXbeLg 1000 i65fyKq25xRoXzKRzdfHkAACbdewhX5SsJS4sRMxsgd 

注意:mint的目标账户必须是token account,不能是EOA账户。

4- 转账

spl-token transfer <mint account> <amount> <recipient address> --fund-recipient

recipient address可以不是associated token account,而用接收方的主账号。

如果接收方没有associated token account不存在,则需要在命令行中添加--fund-recipient,用于创建接收方的ATA账户。

5- 查询余额

spl-token balance <token mint address>

6- 销毁代币

spl-token burn <token account> <amount>

7- 显示代币的数据

spl-token display <token mint address>

8- 冻结与解冻token account

这里的冻结(解冻)是针对用户的token account,这与以太坊上基于代币的冻结不同。Solana上执行冻结(或解冻)后,只有指定的token account被冻结(或恢复正常),以太坊上一般所有代币都会被冻结(或全部正常转币)。

另外,冻结(或解冻)的代币账户必须要有冻结权限(freeze-authority),如果freeze-authority为None,则无法冻结如何token account。

冻结(或解冻)的操作必须要由冻结权限账户进行操作。

注意:如果spl token的接收方也处于冻结状态,即使发送者没有被冻结,代币也无法被转移。

  • 冻结指令:
    spl-token freeze <token account>
    
  • 解冻指令:
    spl-token thaw <token account>
    

举例:

创建一个freeze-authoritymint-authority都为创建者帐号的代币,并完成铸造,转币,冻结,解冻等一系列操作。

执行以下指令:

spl-token create-token --enable-freeze // 执行后,随机创建的mint帐号为:AT5ypbhwh45eXqcMwerZvZb3dpzhvRPDEcWcfZq8S48A

spl-token display AT5ypbhwh45eXqcMwerZvZb3dpzhvRPDEcWcfZq8S48A // 查看创建的代币的数据

spl-token create-account AT5ypbhwh45eXqcMwerZvZb3dpzhvRPDEcWcfZq8S48A --owner Bit5xqnCWDvnM9HAcNAGHqqJ9WHkfZy15yhtojMU6VXS.json // 为账户 Bit5xqnCWDvnM9HAcNAGHqqJ9WHkfZy15yhtojMU6VXS 创建Token account,得到:DAQGeWuZhGnoyT9CNiZaWMsxdHYDQs9DAoFZ5DcLhc2U

spl-token mint AT5ypbhwh45eXqcMwerZvZb3dpzhvRPDEcWcfZq8S48A 1000 DAQGeWuZhGnoyT9CNiZaWMsxdHYDQs9DAoFZ5DcLhc2U // 铸造1000个代币

spl-token balance AT5ypbhwh45eXqcMwerZvZb3dpzhvRPDEcWcfZq8S48A --owner Bit5xqnCWDvnM9HAcNAGHqqJ9WHkfZy15yhtojMU6VXS.json // 查询spl-token代币余额,应该为1000

spl-token freeze DAQGeWuZhGnoyT9CNiZaWMsxdHYDQs9DAoFZ5DcLhc2U // 冻结token account

spl-token transfer AT5ypbhwh45eXqcMwerZvZb3dpzhvRPDEcWcfZq8S48A 100 Bit5xqnCWDvnM9HAcNAGHqqJ9WHkfZy15yhtojMU6VXS --owner Bit5xqnCWDvnM9HAcNAGHqqJ9WHkfZy15yhtojMU6VXS.json // 尝试转币(转给自己),应该失败

spl-token thaw DAQGeWuZhGnoyT9CNiZaWMsxdHYDQs9DAoFZ5DcLhc2U // 解冻token account

spl-token transfer AT5ypbhwh45eXqcMwerZvZb3dpzhvRPDEcWcfZq8S48A 100 Bit5xqnCWDvnM9HAcNAGHqqJ9WHkfZy15yhtojMU6VXS --owner Bit5xqnCWDvnM9HAcNAGHqqJ9WHkfZy15yhtojMU6VXS.json // 再次尝试转币(转给自己),应该成功

8- 指定owner

默认情况下,spl-token的所有操作都基于保存在~/.config/solana/id.json中的私钥。如果要指定owner,可以在命令行中添加--owner <owner keypair json file>参数,指定owner的keypair。

--owner参数适用于上面的所有命令。