10 solana+anchor框架如何实现Token 创建、Mint?

use anchor_lang::prelude::*;
use anchor_lang::solana_program::system_instruction;
use anchor_spl::token::{
    self, InitializeAccount, InitializeMint, Mint, MintTo, Token, TokenAccount, Transfer,
};
// use std::collections::{BTreeMap, HashMap};

declare_id!("2n3qWKfeuatW2MZp75mQroiUS9nC9MbjX5bEK2uq7RZy");
#[program]
mod opool {
pub fn token_initialize(ctx: Context<TokenInitialize>) -> Result<()> {
        let state = &mut ctx.accounts.state;
        let (pda, bump) =
            Pubkey::find_program_address(&[b"authority", state.key().as_ref()], ctx.program_id);
        state.bump = bump;
        state.authority = pda;
        Ok(())
    }

    pub fn initialize_mint(ctx: Context<InitializeMintCtx>, decimals: u8) -> Result<()> {
        let mint = &ctx.accounts.mint;
        let cpi_accounts = InitializeMint {
            mint: mint.to_account_info(),
            rent: ctx.accounts.rent.to_account_info(),
        };
        let cpi_program = ctx.accounts.token_program.to_account_info();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::initialize_mint(cpi_ctx, decimals, &ctx.accounts.mint_authority.key(), None)?;
        Ok(())
    }

    //铸造测试Token
    pub fn mint_to(ctx: Context<MintToken>, amount: u64) -> Result<()> {
        let cpi_accounts = MintTo {
            mint: ctx.accounts.token_account.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 seeds = &[
            ctx.accounts.authority.key.as_ref(),
            &[ctx.accounts.state.bump],
        ];
        let signer_seeds = &[&seeds[..]];

        // let signer_seeds = &[&[
        //     b"authority",
        //     ctx.accounts.token_account.key().as_ref(),
        //     &[ctx.accounts.bump],
        // ]];
        let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer_seeds);
        token::mint_to(cpi_ctx, amount)?;

        emit!(MintToEvent {
            mint: ctx.accounts.token_account.key(),
            to: ctx.accounts.to.key(),
            amount: amount,
        });

        Ok(())
    }

    pub fn initialize_token_account(ctx: Context<InitializeTokenAccountCtx>) -> Result<()> {
        let cpi_accounts = InitializeAccount {
            account: ctx.accounts.token_account.to_account_info(),
            mint: ctx.accounts.mint.to_account_info(),
            authority: ctx.accounts.authority.to_account_info(),
            rent: ctx.accounts.rent.to_account_info(),
        };
        let cpi_program = ctx.accounts.token_program.to_account_info();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::initialize_account(cpi_ctx)?;
        Ok(())
    }

    #[derive(Accounts)]
    pub struct TokenInitialize<'info> {
        #[account(init, payer = user, space = 8 + 64+1)]
        pub state: Account<'info, State>,
        #[account(mut)]
        pub user: Signer<'info>,
        pub system_program: Program<'info, System>,
        pub rent: Sysvar<'info, Rent>,
    }

    #[derive(Accounts)]
    pub struct InitializeMintCtx<'info> {
        #[account(init, payer = user, mint::decimals = 6, mint::authority = mint_authority)]
        pub mint: Account<'info, Mint>,
        #[account(mut)]
        pub user: Signer<'info>,
        // #[account(seeds = [b"authority"], bump)]
        pub mint_authority: AccountInfo<'info>,
        pub token_program: Program<'info, Token>,
        pub rent: Sysvar<'info, Rent>,
        pub system_program: Program<'info, System>,
    }

    #[derive(Accounts)]
    pub struct MintToken<'info> {
        #[account(mut)]
        pub token_account: Account<'info, Mint>,
        pub to: Account<'info, TokenAccount>,
        #[account(seeds = [b"authority", state.key().as_ref()], bump=state.bump)]
        pub authority: AccountInfo<'info>,
        pub token_program: Program<'info, Token>,
        pub state: Account<'info, State>,
        #[account(mut)]
        pub user: Signer<'info>,
    }

    #[derive(Accounts)]
    pub struct InitializeTokenAccountCtx<'info> {
        #[account(init, payer = user, space = 8 + 165)]
        pub token_account: Account<'info, TokenAccount>,
        #[account(mut)]
        pub user: Signer<'info>,
        pub mint: Account<'info, Mint>,
        pub authority: AccountInfo<'info>,
        pub token_program: Program<'info, Token>,
        pub rent: Sysvar<'info, Rent>,
        pub system_program: Program<'info, System>,
    }

    #[account]
    pub struct State {
        pub bump: u8,
        pub authority: Pubkey,
    }

    #[event]
    pub struct MintToEvent {
        pub mint: Pubkey,
        pub to: Pubkey,
        pub amount: u64,
    }
}
请先 登录 后评论

最佳答案 2024-07-23 22:06

use anchor_lang::prelude::*;
use anchor_lang::solana_program::system_instruction;
use anchor_spl::token::{
    self, InitializeAccount, InitializeMint, Mint, MintTo, Token, TokenAccount, Transfer,
};

declare_id!("2n3qWKfeuatW2MZp75mQroiUS9nC9MbjX5bEK2uq7RZy");

#[program]
mod opool {
    use super::*;

    pub fn token_initialize(ctx: Context<TokenInitialize>) -> Result<()> {
        let state = &mut ctx.accounts.state;
        let (pda, bump) =
            Pubkey::find_program_address(&[b"authority", state.key().as_ref()], ctx.program_id);
        state.bump = bump;
        state.authority = pda;
        Ok(())
    }

    pub fn initialize_mint(ctx: Context<InitializeMintCtx>, decimals: u8) -> Result<()> {
        let mint = &ctx.accounts.mint;
        let cpi_accounts = InitializeMint {
            mint: mint.to_account_info(),
            rent: ctx.accounts.rent.to_account_info(),
        };
        let cpi_program = ctx.accounts.token_program.to_account_info();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::initialize_mint(cpi_ctx, decimals, &ctx.accounts.mint_authority.key(), None)?;
        Ok(())
    }

    pub fn mint_to(ctx: Context<MintToken>, amount: u64) -> Result<()> {
        let cpi_accounts = MintTo {
            mint: ctx.accounts.mint.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 seeds = &[
            b"authority",
            ctx.accounts.state.key().as_ref(),
            &[ctx.accounts.state.bump],
        ];
        let signer_seeds = &[&seeds[..]];

        let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer_seeds);
        token::mint_to(cpi_ctx, amount)?;

        emit!(MintToEvent {
            mint: ctx.accounts.mint.key(),
            to: ctx.accounts.to.key(),
            amount: amount,
        });

        Ok(())
    }

    pub fn initialize_token_account(ctx: Context<InitializeTokenAccountCtx>) -> Result<()> {
        let cpi_accounts = InitializeAccount {
            account: ctx.accounts.token_account.to_account_info(),
            mint: ctx.accounts.mint.to_account_info(),
            authority: ctx.accounts.authority.to_account_info(),
            rent: ctx.accounts.rent.to_account_info(),
        };
        let cpi_program = ctx.accounts.token_program.to_account_info();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::initialize_account(cpi_ctx)?;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct TokenInitialize<'info> {
    #[account(init, payer = user, space = 8 + 64 + 1)]
    pub state: Account<'info, State>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
    pub rent: Sysvar<'info, Rent>,
}

#[derive(Accounts)]
pub struct InitializeMintCtx<'info> {
    #[account(init, payer = user, mint::decimals = 6, mint::authority = mint_authority)]
    pub mint: Account<'info, Mint>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub mint_authority: AccountInfo<'info>,
    pub token_program: Program<'info, Token>,
    pub rent: Sysvar<'info, Rent>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct MintToken<'info> {
    #[account(mut)]
    pub mint: Account<'info, Mint>,
    #[account(mut)]
    pub to: Account<'info, TokenAccount>,
    #[account(seeds = [b"authority", state.key().as_ref()], bump = state.bump)]
    pub authority: AccountInfo<'info>,
    pub token_program: Program<'info, Token>,
    pub state: Account<'info, State>,
    #[account(mut)]
    pub user: Signer<'info>,
}

#[derive(Accounts)]
pub struct InitializeTokenAccountCtx<'info> {
    #[account(init, payer = user, space = 8 + 165)]
    pub token_account: Account<'info, TokenAccount>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub mint: Account<'info, Mint>,
    pub authority: AccountInfo<'info>,
    pub token_program: Program<'info, Token>,
    pub rent: Sysvar<'info, Rent>,
    pub system_program: Program<'info, System>,
}

#[account]
pub struct State {
    pub bump: u8,
    pub authority: Pubkey,
}

#[event]
pub struct MintToEvent {
    pub mint: Pubkey,
    pub to: Pubkey,
    pub amount: u64,
}

test

const anchor = require('@project-serum/anchor');
const { Token, TOKEN_PROGRAM_ID } = require('@solana/spl-token');

describe('opool', () => {
    const provider = anchor.AnchorProvider.env();
    anchor.setProvider(provider);

    const program = anchor.workspace.Opool;

    it('Creates and Mints a token', async () => {
        const mint = anchor.web3.Keypair.generate();
        const userTokenAccount = await Token.getAssociatedTokenAddress(
            mint.publicKey,
            provider.wallet.publicKey
        );

        await program.rpc.initializeMint(
            6, // decimals
            {
                accounts: {
                    mint: mint.publicKey,
                    user: provider.wallet.publicKey,
                    mintAuthority: provider.wallet.publicKey,
                    tokenProgram: TOKEN_PROGRAM_ID,
                    rent: anchor.web3.SYSVAR_RENT_PUBKEY,
                    systemProgram: anchor.web3.SystemProgram.programId,
                },
                signers: [mint],
                instructions: [
                    await program.account.mint.createInstruction(mint),
                ],
            }
        );

        await program.rpc.mintTo(
            new anchor.BN(1000000), // amount
            {
                accounts: {
                    mint: mint.publicKey,
                    to: userTokenAccount,
                    authority: provider.wallet.publicKey,
                    tokenProgram: TOKEN_PROGRAM_ID,
                    state: state.publicKey,
                    user: provider.wallet.publicKey,
                },
            }
        );

        const tokenAccountInfo = await provider.connection.getTokenAccountBalance(userTokenAccount);
        console.log('Token Account Balance:', tokenAccountInfo.value.uiAmount);
    });
});
请先 登录 后评论

其它 0 个回答

  • 1 关注
  • 0 收藏,1004 浏览
  • ? or ? 提出于 2024-07-19 18:24