使用Anchor开发Solana USDC彩票金库编译报错求助
解决Anchor框架中TokenAccount/Mint与Discriminator trait不兼容的编译错误
问题描述
使用Anchor 0.30.1开发Solana上的USDC彩票金库时,编译出现多个错误,核心问题是anchor_spl::token::TokenAccount和Mint未实现Discriminator trait,且无法找到create_type/insert_types关联方法。
错误信息
error[E0599]: no function or associated item named `create_type` found for struct `anchor_spl::token::TokenAccount` in the current scope --> programs/milionary-fun/src/instructions/initialize_lottery.rs:7:10 | 7 | #[derive(Accounts)] | ^^^^^^^^ function or associated item not found in `TokenAccount` | = note: this error originates in the derive macro `Accounts` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `anchor_spl::token::TokenAccount: Discriminator` is not satisfied --> programs/milionary-fun/src/instructions/initialize_lottery.rs:25:45 | 25 | pub vault_token_account: Account<'info, TokenAccount>, | ^^^^^^^^^^^^ the trait `Discriminator` is not implemented for `anchor_spl::token::TokenAccount` | = help: the following other types implement trait `Discriminator`: __idl::IdlAccount anchor_lang::ProgramData anchor_lang::idl::IdlAccount instruction::InitializeLottery instruction::PushPicsou lottery::Lottery vault_pda::VaultPDA error[E0599]: no function or associated item named `insert_types` found for struct `anchor_spl::token::TokenAccount` in the current scope --> programs/milionary-fun/src/instructions/initialize_lottery.rs:7:10 | 7 | #[derive(Accounts)] | ^^^^^^^^ function or associated item not found in `TokenAccount` | = note: this error originates in the derive macro `Accounts` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no function or associated item named `create_type` found for struct `anchor_spl::token::Mint` in the current scope --> programs/milionary-fun/src/instructions/initialize_lottery.rs:7:10 | 7 | #[derive(Accounts)] | ^^^^^^^^ function or associated item not found in `Mint` | = note: this error originates in the derive macro `Accounts` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `anchor_spl::token::Mint: Discriminator` is not satisfied --> programs/milionary-fun/src/instructions/initialize_lottery.rs:27:35 | 27 | pub usdc_mint: Account<'info, Mint>, | ^^^^ the trait `Discriminator` is not implemented for `anchor_spl::token::Mint` | = help: the following other types implement trait `Discriminator`: __idl::IdlAccount anchor_lang::ProgramData anchor_lang::idl::IdlAccount instruction::InitializeLottery instruction::PushPicsou lottery::Lottery vault_pda::VaultPDA error[E0599]: no function or associated item named `insert_types` found for struct `anchor_spl::token::Mint` in the current scope --> programs/milionary-fun/src/instructions/initialize_lottery.rs:7:10 | 7 | #[derive(Accounts)] | ^^^^^^^^ function or associated item not found in `Mint` | = note: this error originates in the derive macro `Accounts` (in Nightly builds, run with -Z macro-backtrace for more info) Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`. error: could not compile `milionary-fun` (lib test) due to 6 previous errors Error: Building IDL failed
原实现代码
use anchor_lang::prelude::*; use anchor_spl::token::{Mint, Token, TokenAccount}; use anchor_spl::associated_token::AssociatedToken; use crate::states::VaultPDA; use crate::{errors::MilionaryFunError, states::Lottery}; #[derive(Accounts)] pub struct InitializeLottery<'info> { #[account(mut)] pub authority: Signer<'info>, #[account(init, payer = authority, space = Lottery::SIZE)] pub lottery: Account<'info, Lottery>, #[account( init, payer = authority, seeds = [VaultPDA::SEED, lottery.key().as_ref()], bump, space = VaultPDA::SIZE )] pub vault_pda: Account<'info, VaultPDA>, #[account(init_if_needed, payer = authority, associated_token::mint = usdc_mint, associated_token::authority = vault_pda)] pub vault_token_account: Account<'info, TokenAccount>, pub usdc_mint: Account<'info, Mint>, pub system_program: Program<'info, System>, pub token_program: Program<'info, Token>, pub associated_token_program: Program<'info, AssociatedToken>, } pub fn handle_intialize_lottery(ctx: Context<InitializeLottery>, authority: Pubkey) -> Result<()> { let lottery = &mut ctx.accounts.lottery; let vault_pda = &mut ctx.accounts.vault_pda; require!(lottery.is_active == false, MilionaryFunError::LotteryAlreadyInitialized); lottery.authority = authority; lottery.vault = ctx.accounts.vault_token_account.key(); lottery.picsou_address = Pubkey::default(); lottery.current_ticket_id = 0; lottery.total_amount = 0; lottery.is_active = true; vault_pda.usdc_mint = ctx.accounts.usdc_mint.key(); vault_pda.vault_token_account = ctx.accounts.vault_token_account.key(); Ok(()) }
依赖配置(Cargo.toml)
[package] name = "milionary-fun" version = "0.1.0" description = "Created with Anchor" edition = "2021" [lib] crate-type = ["cdylib", "lib"] name = "milionary_fun" [features] default = [] cpi = ["no-entrypoint"] no-entrypoint = [] no-idl = [] no-log-ix-name = [] idl-build = ["anchor-lang/idl-build", "anchor-lang/idl-build"] [dependencies] anchor-lang = { version = "0.30.1", features = ["init-if-needed"] } anchor-spl = { version = "0.30.1", features = ["associated_token", "metadata", "token"] }
解决方案
Anchor 0.20+版本重构了token模块,原anchor_spl::token::TokenAccount和Mint是底层结构体,未实现#[derive(Accounts)]所需的trait,需要改用interface子模块下的对应类型:
步骤1:修改导入语句
将token相关类型的导入替换为interface下的版本:
use anchor_spl::token::{interface::{Mint, TokenAccount}, Token};
步骤2:调整账户结构体中的字段类型
移除Account<'info, T>包装,直接使用interface类型:
#[account(init_if_needed, payer = authority, associated_token::mint = usdc_mint, associated_token::authority = vault_pda)] pub vault_token_account: interface::TokenAccount<'info>, pub usdc_mint: interface::Mint<'info>,
修改后的完整代码
use anchor_lang::prelude::*; use anchor_spl::token::{interface::{Mint, TokenAccount}, Token}; use anchor_spl::associated_token::AssociatedToken; use crate::states::VaultPDA; use crate::{errors::MilionaryFunError, states::Lottery}; #[derive(Accounts)] pub struct InitializeLottery<'info> { #[account(mut)] pub authority: Signer<'info>, #[account(init, payer = authority, space = Lottery::SIZE)] pub lottery: Account<'info, Lottery>, #[account( init, payer = authority, seeds = [VaultPDA::SEED, lottery.key().as_ref()], bump, space = VaultPDA::SIZE )] pub vault_pda: Account<'info, VaultPDA>, #[account(init_if_needed, payer = authority, associated_token::mint = usdc_mint, associated_token::authority = vault_pda)] pub vault_token_account: interface::TokenAccount<'info>, pub usdc_mint: interface::Mint<'info>, pub system_program: Program<'info, System>, pub token_program: Program<'info, Token>, pub associated_token_program: Program<'info, AssociatedToken>, } pub fn handle_intialize_lottery(ctx: Context<InitializeLottery>, authority: Pubkey) -> Result<()> { let lottery = &mut ctx.accounts.lottery; let vault_pda = &mut ctx.accounts.vault_pda; require!(lottery.is_active == false, MilionaryFunError::LotteryAlreadyInitialized); lottery.authority = authority; lottery.vault = ctx.accounts.vault_token_account.key(); lottery.picsou_address = Pubkey::default(); lottery.current_ticket_id = 0; lottery.total_amount = 0; lottery.is_active = true; vault_pda.usdc_mint = ctx.accounts.usdc_mint.key(); vault_pda.vault_token_account = ctx.accounts.vault_token_account.key(); Ok(()) }
原因说明
interface子模块下的TokenAccount和Mint实现了AccountDeserialize、Discriminator等必要trait,能被Anchor的Accounts派生宏正确解析,解决编译错误。
内容的提问来源于stack exchange,提问作者Nayrosk
相关产品推荐
相关产品推荐

