8. Anchor 框架集成

8. Anchor 框架集成

Anchor 是 Solana 上最流行的开发框架,它简化了程序开发流程。本章介绍如何在 Anchor 程序中集成代币操作。

8.1 Anchor 项目结构

创建新的 Anchor 项目:

bash
anchor init token-program cd token-program

项目结构:

token-program/ ├── Anchor.toml # 项目配置 ├── Cargo.toml ├── programs/ │ └── token-program/ │ ├── Cargo.toml │ └── src/ │ └── lib.rs # 主程序代码 ├── tests/ │ └── token-program.ts # 测试文件 └── migrations/

8.2 在 Anchor 中创建代币

更新 programs/token-program/Cargo.toml 添加依赖:

toml
[dependencies] anchor-lang = "0.30.1" anchor-spl = "0.30.1"

编写程序代码:

rust
// programs/token-program/src/lib.rs use anchor_lang::prelude::*; use anchor_spl::{ token_2022::{self, Token2022, MintTo, Transfer}, token_interface::{Mint, TokenAccount, TokenInterface}, associated_token::AssociatedToken, }; declare_id!("YOUR_PROGRAM_ID"); #[program] pub mod token_program { use super::*; /// 创建新代币 pub fn create_token( ctx: Context<CreateToken>, decimals: u8, ) -> Result<()> { msg!("代币创建成功!"); msg!("Mint 地址: {}", ctx.accounts.mint.key()); msg!("精度: {}", decimals); Ok(()) } /// 铸造代币 pub fn mint_tokens( ctx: Context<MintTokens>, amount: u64, ) -> Result<()> { let cpi_accounts = MintTo { mint: ctx.accounts.mint.to_account_info(), to: ctx.accounts.token_account.to_account_info(), authority: ctx.accounts.authority.to_account_info(), }; let cpi_program = ctx.accounts.token_program.to_account_info(); let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); token_2022::mint_to(cpi_ctx, amount)?; msg!("铸造 {} 代币到 {}", amount, ctx.accounts.token_account.key()); Ok(()) } /// 转账代币 pub fn transfer_tokens( ctx: Context<TransferTokens>, amount: u64, ) -> Result<()> { let cpi_accounts = Transfer { from: ctx.accounts.from.to_account_info(), to: ctx.accounts.to.to_account_info(), authority: ctx.accounts.authority.to_account_info(), }; let cpi_program = ctx.accounts.token_program.to_account_info(); let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); token_2022::transfer(cpi_ctx, amount)?; msg!("转账 {} 代币", amount); Ok(()) } } #[derive(Accounts)] #[instruction(decimals: u8)] pub struct CreateToken<'info> { #[account( init, payer = payer, mint::decimals = decimals, mint::authority = payer, mint::freeze_authority = payer, mint::token_program = token_program, )] pub mint: InterfaceAccount<'info, Mint>, #[account(mut)] pub payer: Signer<'info>, pub token_program: Interface<'info, TokenInterface>, pub system_program: Program<'info, System>, }

8.3 使用 PDA 作为权限

在实际应用中,常需要让程序自身控制代币的铸造或转账。这通过 PDA(程序派生地址)实现:

rust
use anchor_lang::prelude::*; use anchor_spl::{ token_2022::{self, MintTo}, token_interface::{Mint, TokenAccount, TokenInterface}, }; #[program] pub mod vault { use super::*; /// 程序控制的铸造 pub fn program_mint( ctx: Context<ProgramMint>, amount: u64, ) -> Result<()> { // 构建 PDA seeds let seeds = &[ b"mint_authority", ctx.accounts.mint.to_account_info().key.as_ref(), &[ctx.bumps.mint_authority], ]; let signer_seeds = &[&seeds[..]]; // 使用 PDA 签名进行 CPI 调用 let cpi_accounts = MintTo { mint: ctx.accounts.mint.to_account_info(), to: ctx.accounts.token_account.to_account_info(), authority: ctx.accounts.mint_authority.to_account_info(), }; let cpi_ctx = CpiContext::new_with_signer( ctx.accounts.token_program.to_account_info(), cpi_accounts, signer_seeds, ); token_2022::mint_to(cpi_ctx, amount)?; Ok(()) } }
Playground
EDITOR ACTIVE
Initializing RUST Environment...

Anchor Token 集成

Instruction
pub fn create_token(...) {
  // Anchor handles init
  Ok(())
}
Your Anchor Program
Logic Layer
Token Program
Execution Layer
MintSupply: 0
User ATA
0
Recipient ATA
0