Jacky Gu

Solana开发笔记: 使用前端SDK转移代币

01 Jan 2025 Share to

使用前端SDK转移代币

前面一篇中,详细介绍了如何铸造代币,这篇介绍转移代币。

因为代币已经在用户的token account中,该token account的owner是用户自己,所以用户能够自由处置自己的代币的以下动作:

  • 1- 转移代币
  • 2- 燃烧代币

但是因为mint的权限和freeze的权限为mint账户,所以以下动作需要由程序完成:

  • 1- 冻结代币
  • 2- 解冻代币
  • 3- 丢弃冻结权限
  • 4- 丢弃解冻权限

因此,转移代币的动作无需写anchor程序指令,在前端即可完成。

创建转移代币指令

tests/legacy_token.ts中添加以下测试代码,完成转账,将100个代币从user1转给user2

  it("transfer tokens", async () => {
    // Get the source and destination token accounts
    const sourceAta = await getAssociatedTokenAddress(mintAccount, user1Account.publicKey, false, TOKEN_PROGRAM_ID);
    const destinationAta = await getAssociatedTokenAddress(mintAccount, user2Account.publicKey, false, TOKEN_PROGRAM_ID);

    // Create destination ATA if it doesn't exist
    const tx = new anchor.web3.Transaction();
    try {
      await provider.connection.getTokenAccountBalance(destinationAta);
    } catch {
      // if token accont the destination doesn't exist, create it
      const ix = createAssociatedTokenAccountInstruction(
        user1Account.publicKey,
        destinationAta,
        user2Account.publicKey,
        mintAccount
      );
      tx.add(ix);
      // await provider.sendAndConfirm(tx, [user1Account]);
      console.log("Created destination ATA:", destinationAta.toBase58());
    }

    // Transfer amount: 100 tokens (considering 9 decimals)
    const amount = 100 * Math.pow(10, 9);

    // Create transfer instruction
    const transferIx = createTransferInstruction(
      sourceAta,
      destinationAta,
      user1Account.publicKey,
      amount
    );

    // Send transaction
    tx.add(transferIx);
    const signature = await provider.sendAndConfirm(tx, [user1Account]);
    console.log("Transfer transaction signature:", signature);

    // Log balances
    const sourceBalance = await provider.connection.getTokenAccountBalance(sourceAta);
    const destBalance = await provider.connection.getTokenAccountBalance(destinationAta);
    console.log("Source balance after transfer:", sourceBalance.value.uiAmount);
    console.log("Destination balance after transfer:", destBalance.value.uiAmount);
  })

上述代码中,先创建一个tx = new anchor.web3.Transaction();,然后往tx里添加必要的指令。

首先,检查目标账户的token account是否存在,如果不存在,则在tx中添加一个由createAssociatedTokenAccountInstruction生成的指令(instruction),用于创建目标账户的Token account。

然后,在tx中添加一个由createTransferInstruction生成的代币转移指令。

最后,使用await provider.sendAndConfirm(tx, [user1Account]);完成交易指令的发送。

执行后,查看交易hash,如下图所示: