You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Solana Anchor代码实现程序为铸币权限且用户付手续费?

Solana Anchor 铸币程序修改方案(PDA作为铸币权限+用户支付手续费)

核心修改要点

  • 生成程序专属的PDA作为代币的铸币权限,无需传入外部权限账户
  • 强制接收代币的用户(代币账户的所有者)作为签名者,同时提供其SOL账户承担交易手续费
  • 添加账户约束,验证代币的铸币权确实是程序的PDA,防止非法调用
  • 通过PDA签名种子完成铸币操作的CPI调用

修改后的完整代码

use anchor_lang::prelude::*;
use anchor_spl::token;
use anchor_spl::token::{Token, MintTo, Mint};

declare_id!("EcFTDXxknt3vRBi1pVZYN7SjZLcbHjJRAmCmjZ7Js3fd");

#[program]
pub mod solana_ubi {
    use super::*;

    pub fn mint_token(ctx: Context<MintToken>) -> Result<()> {
        // 构建PDA签名种子
        let sign_seeds = &[&[b"mint_authority", &[*ctx.bumps.get("mint_authority").unwrap()]]];
        
        // 组装铸币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(),
        };

        // 创建带PDA签名的CPI上下文
        let cpi_ctx = CpiContext::new_with_signer(
            ctx.accounts.token_program.to_account_info(),
            cpi_accounts,
            sign_seeds,
        );

        // 执行铸币操作(铸造10个代币,对应9位小数的10_000_000_000)
        token::mint_to(cpi_ctx, 10_000_000_000)?;

        Ok(())
    }
}

#[derive(Accounts)]
pub struct MintToken<'info> {
    // 代币铸币账户,验证其铸币权为程序PDA
    #[account(
        mut,
        constraint = mint.authority == mint_authority.key()
    )]
    pub mint: Account<'info, Mint>,

    // 程序专属的PDA铸币权限账户
    /// CHECK: 已通过seeds约束验证归属程序
    #[account(
        seeds = [b"mint_authority"],
        bump,
        seeds::program = program_id
    )]
    pub mint_authority: AccountInfo<'info>,

    // 用户的代币接收账户,验证所有者为付费用户
    #[account(
        mut,
        constraint = token_account.owner == payer.key()
    )]
    pub token_account: Account<'info, token::TokenAccount>,

    // 支付手续费的用户SOL账户,必须为签名者
    #[account(mut, signer)]
    pub payer: Signer<'info>,

    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
}

关键说明

  1. PDA铸币权限配置:需提前通过Solana CLI或工具将代币mint的authority更新为程序生成的PDA(通过find_program_address(&[b"mint_authority"], 程序ID)计算得到)
  2. 手续费承担逻辑:payer账户是用户的SOL账户,标记为mut和signer,确保用户签名并承担交易的SOL手续费
  3. 安全约束验证:通过账户约束确保代币铸币权归属程序PDA、代币接收账户的所有者为付费用户,避免非法调用
  4. PDA签名CPI:使用new_with_signer传入PDA签名种子,让程序以PDA身份完成铸币授权

内容的提问来源于stack exchange,提问作者Depa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:54:09