Skip to content

创建非同质化代币

作者 崔棉大师 X:@MasterCui Youtube: 崔棉大师

知识点

与 Ethereum 不同,在 solana 生态中,如果一个代币的精度为 0 就可以视为非同质化代币,而类似 ERC721 的代币合集型的 NFT 则是由一定数量的精度为 0 的 Solana token 组成,每一个 token 都拥有自己的地址,ERC721 一个合集拥有一个地址,每个 token 是合约中的一个 ID

课程

1.通过 cli 创建代币

创建代币时,通过参数指定精度为 0

sh
$ spl-token create-token --decimals 0
Creating token BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk under program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

Address:  BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk
Decimals:  0

Signature: xfPoxtX2Xqe447CzeSzupbiCLjRpXQhcW8wiWvDCBu5sMjXmCZSxf6TXucXh96Zjr5jaFowp6N9HR4pF4fUYSLj

然后创建一个代币帐户来持有这种新类型的代币:

sh
$ spl-token create-account BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk
Creating account eyqCgSPMziLJnR7ovWhnN6qgykJtarnnYmyaGpqBogM

Signature: 65mqmqeRPAFwDZLwvUQTAdX7pdH3dTJc4SmT5gCAaD7S4U1CS4KJ49MQsK2h3n7Tnz2Bcapi1cZdH3xe5XRm4KSU

现在只向账户中铸造一个代币

sh
$ spl-token mint BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk 1 eyqCgSPMziLJnR7ovWhnN6qgykJtarnnYmyaGpqBogM
Minting 1 tokens
  Token: BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk
  Recipient: eyqCgSPMziLJnR7ovWhnN6qgykJtarnnYmyaGpqBogM

Signature: fevtHYeJhahogeZvyWqvMB8X9n8z9dAJRKktK1Ehct1z9TCJ8d79iZ5G72vnDzD3n3nqqZBNE86dQHYG12N1da8

最后禁用未来的铸造:

sh
$ spl-token authorize BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk mint --disable
Updating BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk
  Current mint: CuiDdffKV38LjgRVtiA2QiMTKhnzkjX2LUxqSMbVnGjG
  New mint: disabled

Signature: 3PYXmykjPVhnFqQdUA8qqHR9qAX91w2fAehtKy3oN5YFunog4TuJC8pbPBJ8moGdxfenSoE6R53C6J5DE4SRP1n4

现在该eyqCgSPMziLJnR7ovWhnN6qgykJtarnnYmyaGpqBogM帐户拥有唯一的BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk代币:

sh
$ spl-token account-info BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk

SPL Token Account
  Address: eyqCgSPMziLJnR7ovWhnN6qgykJtarnnYmyaGpqBogM
  Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
  Balance: 1
  Decimals: 0
  Mint: BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk
  Owner: CuiDdffKV38LjgRVtiA2QiMTKhnzkjX2LUxqSMbVnGjG
  State: Initialized
  Delegation: (not set)
  Close authority: (not set)
sh
$ spl-token supply BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk
1

2.通过 javascript 创建代币

首先通过我们之前学过的 createMint 函数创建代币,最后一个参数精度为 0

js
const mint = await createMint(
  connection,
  wallet,
  wallet.publicKey,
  wallet.publicKey,
  0
);

然后创建一个代币帐户来持有这种新类型的代币:

js
const associatedTokenAccount = await getOrCreateAssociatedTokenAccount(
  connection,
  wallet,
  mint,
  wallet.publicKey
);

现在只向账户中铸造一个代币,最后一个参数的数量为 1 lamport:

js
await mintTo(
  connection,
  wallet,
  mint,
  associatedTokenAccount.address,
  wallet,
  1
);

最后通过createSetAuthorityInstruction函数禁用未来的铸造,在这个函数中,第四个参数为新的铸造权限账户地址,如果设置为null则代表关闭未来的铸造:

js
let transaction = new Transaction().add(
  createSetAuthorityInstruction(
    mint,
    wallet.publicKey,
    AuthorityType.MintTokens,
    null
  )
);

await web3.sendAndConfirmTransaction(connection, transaction, [wallet]);

查询账户状态:

js
const accountInfo = await getAccount(
  connection,
  associatedTokenAccount.address
);

console.log(accountInfo.amount);
// 1
const mintInfo = await getMint(connection, mint);

console.log(mintInfo);
/*
{
  address: "BNptJhNKo6Cs9KrjxcdwKCpmXtnQgqR9J2QD1WHgJNPk",
  mintAuthority: "CuiDdffKV38LjgRVtiA2QiMTKhnzkjX2LUxqSMbVnGjG",
  supply: 1,
  decimals: 0,
  isInitialized: true,
  freezeAuthority: "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
}
 */

挑战

  • 通过区块链浏览器查询每一笔交易
  • 为非同质化代币创建metadata