浏览代码

mint authority

jpcaulfi 3 年之前
父节点
当前提交
7652992e80

+ 1 - 1
tokens/mint-to/anchor/Anchor.toml

@@ -1,7 +1,7 @@
 [features]
 seeds = false
 [programs.devnet]
-mint_token_to = "DDvuxbzPh3aSb67Kc7kvxb7SsU6bNmPBfqsqvQFHcqWu"
+mint_token_to = "86NFhnnuV8SNEuHdqNtjCFeGCknpjDXEbV7b3zBefJ11"
 
 [registry]
 url = "https://anchor.projectserum.com"

+ 33 - 14
tokens/mint-to/anchor/programs/mint-token-to/src/instructions/create_token_mint.rs

@@ -1,7 +1,7 @@
 use {
     anchor_lang::{
         prelude::*,
-        solana_program::program::invoke,
+        solana_program::program::invoke_signed,
         system_program,
     },
     anchor_spl::token,
@@ -14,9 +14,10 @@ pub fn create_token_mint(
     metadata_title: String, 
     metadata_symbol: String, 
     metadata_uri: String,
+    mint_authority_pda_bump: u8,
 ) -> Result<()> {
 
-    const MINT_SIZE: u64 = 82;
+    let mint_authority = &mut ctx.accounts.mint_authority;
 
     msg!("Creating mint account...");
     msg!("Mint: {}", &ctx.accounts.mint_account.key());
@@ -24,12 +25,12 @@ pub fn create_token_mint(
         CpiContext::new(
             ctx.accounts.token_program.to_account_info(),
             system_program::CreateAccount {
-                from: ctx.accounts.mint_authority.to_account_info(),
+                from: ctx.accounts.payer.to_account_info(),
                 to: ctx.accounts.mint_account.to_account_info(),
             },
         ),
-        (Rent::get()?).minimum_balance(MINT_SIZE as usize),
-        MINT_SIZE,
+        (Rent::get()?).minimum_balance(token::Mint::LEN),
+        token::Mint::LEN as u64,
         &ctx.accounts.token_program.key(),
     )?;
 
@@ -44,20 +45,20 @@ pub fn create_token_mint(
             },
         ),
         9,                                              // 9 Decimals
-        &ctx.accounts.mint_authority.key(),
-        Some(&ctx.accounts.mint_authority.key()),
+        &mint_authority.key(),
+        Some(&mint_authority.key()),
     )?;
 
     msg!("Creating metadata account...");
     msg!("Metadata account address: {}", &ctx.accounts.metadata_account.key());
-    invoke(
+    invoke_signed(
         &mpl_instruction::create_metadata_accounts_v2(
             ctx.accounts.token_metadata_program.key(),      // Program ID (the Token Metadata Program)
             ctx.accounts.metadata_account.key(),            // Metadata account
             ctx.accounts.mint_account.key(),                // Mint account
-            ctx.accounts.mint_authority.key(),              // Mint authority
-            ctx.accounts.mint_authority.key(),              // Payer
-            ctx.accounts.mint_authority.key(),              // Update authority
+            mint_authority.key(),              // Mint authority
+            ctx.accounts.payer.key(),              // Payer
+            mint_authority.key(),              // Update authority
             metadata_title,                                 // Name
             metadata_symbol,                                // Symbol
             metadata_uri,                                   // URI
@@ -71,10 +72,17 @@ pub fn create_token_mint(
         &[
             ctx.accounts.metadata_account.to_account_info(),
             ctx.accounts.mint_account.to_account_info(),
-            ctx.accounts.mint_authority.to_account_info(),
+            mint_authority.to_account_info(),
+            ctx.accounts.payer.to_account_info(),
+            mint_authority.to_account_info(),
             ctx.accounts.token_metadata_program.to_account_info(),
             ctx.accounts.rent.to_account_info(),
         ],
+        &[&[
+            b"mint_authority_", 
+            ctx.accounts.mint_account.key().as_ref(),
+            &[mint_authority_pda_bump],
+        ]]
     )?;
 
     msg!("Token mint created successfully.");
@@ -90,11 +98,22 @@ pub struct CreateTokenMint<'info> {
     pub metadata_account: UncheckedAccount<'info>,
     #[account(mut)]
     pub mint_account: Signer<'info>,
+    #[account(
+        init, 
+        payer = payer,
+        space = 8 + 32,
+        seeds = [b"mint_authority_", mint_account.key().as_ref()],
+        bump
+    )]
+    pub mint_authority: Account<'info, MintAuthorityPda>,
     #[account(mut)]
-    pub mint_authority: Signer<'info>,
+    pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
     pub system_program: Program<'info, System>,
     pub token_program: Program<'info, token::Token>,
     /// CHECK: Metaplex will check this
     pub token_metadata_program: UncheckedAccount<'info>,
-}
+}
+
+#[account]
+pub struct MintAuthorityPda {}

+ 22 - 6
tokens/mint-to/anchor/programs/mint-token-to/src/instructions/mint_to_wallet.rs

@@ -5,22 +5,26 @@ use {
         associated_token,
     },
 };
+use crate::create_token_mint::MintAuthorityPda;
 
 
 pub fn mint_to_wallet(
     ctx: Context<MintToWallet>, 
     amount: u64,
+    mint_authority_pda_bump: u8,
 ) -> Result<()> {
 
+    let mint_authority = &mut ctx.accounts.mint_authority;
+
     msg!("Creating token account...");
     msg!("Token Address: {}", &ctx.accounts.token_account.key());    
     associated_token::create(
         CpiContext::new(
             ctx.accounts.associated_token_program.to_account_info(),
             associated_token::Create {
-                payer: ctx.accounts.mint_authority.to_account_info(),
+                payer: ctx.accounts.payer.to_account_info(),
                 associated_token: ctx.accounts.token_account.to_account_info(),
-                authority: ctx.accounts.mint_authority.to_account_info(),
+                authority: ctx.accounts.payer.to_account_info(),
                 mint: ctx.accounts.mint_account.to_account_info(),
                 system_program: ctx.accounts.system_program.to_account_info(),
                 token_program: ctx.accounts.token_program.to_account_info(),
@@ -33,13 +37,18 @@ pub fn mint_to_wallet(
     msg!("Mint: {}", &ctx.accounts.mint_account.to_account_info().key());   
     msg!("Token Address: {}", &ctx.accounts.token_account.key());     
     token::mint_to(
-        CpiContext::new(
+        CpiContext::new_with_signer(
             ctx.accounts.token_program.to_account_info(),
             token::MintTo {
                 mint: ctx.accounts.mint_account.to_account_info(),
                 to: ctx.accounts.token_account.to_account_info(),
-                authority: ctx.accounts.mint_authority.to_account_info(),
+                authority: mint_authority.to_account_info(),
             },
+            &[&[
+                b"mint_authority_", 
+                ctx.accounts.mint_account.key().as_ref(),
+                &[mint_authority_pda_bump],
+            ]]
         ),
         amount,
     )?;
@@ -51,14 +60,21 @@ pub fn mint_to_wallet(
 
 
 #[derive(Accounts)]
+#[instruction(amount: u64, mint_authority_pda_bump: u8)]
 pub struct MintToWallet<'info> {
     #[account(mut)]
-    pub mint_account: Signer<'info>,
+    pub mint_account: Account<'info, token::Mint>,
+    #[account(
+        mut, 
+        seeds = [b"mint_authority_", mint_account.key().as_ref()],
+        bump = mint_authority_pda_bump
+    )]
+    pub mint_authority: Account<'info, MintAuthorityPda>,
     /// CHECK: We're about to create this with Anchor
     #[account(mut)]
     pub token_account: UncheckedAccount<'info>,
     #[account(mut)]
-    pub mint_authority: Signer<'info>,
+    pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
     pub system_program: Program<'info, System>,
     pub token_program: Program<'info, token::Token>,

+ 10 - 3
tokens/mint-to/anchor/programs/mint-token-to/src/lib.rs

@@ -5,7 +5,7 @@ pub mod instructions;
 use instructions::*;
 
 
-declare_id!("DDvuxbzPh3aSb67Kc7kvxb7SsU6bNmPBfqsqvQFHcqWu");
+declare_id!("86NFhnnuV8SNEuHdqNtjCFeGCknpjDXEbV7b3zBefJ11");
 
 
 #[program]
@@ -17,21 +17,28 @@ pub mod mint_token_to {
         metadata_title: String, 
         metadata_symbol: String, 
         metadata_uri: String,
+        mint_authority_pda_bump: u8,
     ) -> Result<()> {
 
         create_token_mint::create_token_mint(
             ctx, 
             metadata_title, 
             metadata_symbol, 
-            metadata_uri
+            metadata_uri,
+            mint_authority_pda_bump,
         )
     }
 
     pub fn mint_to_wallet(
         ctx: Context<MintToWallet>, 
         amount: u64,
+        mint_authority_pda_bump: u8,
     ) -> Result<()> {
 
-        mint_to_wallet::mint_to_wallet(ctx, amount)
+        mint_to_wallet::mint_to_wallet(
+            ctx, 
+            amount,
+            mint_authority_pda_bump,
+        )
     }
 }

+ 38 - 15
tokens/mint-to/anchor/tests/test.ts

@@ -14,14 +14,24 @@ describe("mint-token", () => {
   const payer = provider.wallet as anchor.Wallet;
   const program = anchor.workspace.MintTokenTo as anchor.Program<MintTokenTo>;
 
+  const testTokenTitle = "Solana Gold G";
+  const testTokenSymbol = "GOLDSOL";
+  const testTokenUri = "https://raw.githubusercontent.com/solana-developers/program-examples/main/tokens/token_metadata.json";
+
   const mintKeypair: anchor.web3.Keypair = anchor.web3.Keypair.generate();
   console.log(`New token: ${mintKeypair.publicKey}`);
 
-  const testTokenTitle = "Solana Gold";
-  const testTokenSymbol = "GOLDSOL";
-  const testTokenUri = "https://raw.githubusercontent.com/solana-developers/program-examples/main/tokens/token_metadata.json";
+  it("Create the mint", async () => {
 
-  it("Mint!", async () => {
+    const [mintAuthorityPda, mintAuthorityPdaBump] = await anchor.web3.PublicKey.findProgramAddress(
+      [
+        Buffer.from("mint_authority_"),
+        mintKeypair.publicKey.toBuffer(),
+      ],
+      program.programId,
+    );
+    console.log(`PDA: ${mintAuthorityPda}`);
+    console.log(`Bump: ${mintAuthorityPdaBump}`);
 
     const metadataAddress = (await anchor.web3.PublicKey.findProgramAddress(
       [
@@ -32,44 +42,57 @@ describe("mint-token", () => {
       TOKEN_METADATA_PROGRAM_ID
     ))[0];
 
-    // Transact with the "create_token_mint" function in our on-chain program
-    //
     await program.methods.createTokenMint(
-      testTokenTitle, testTokenSymbol, testTokenUri
+      testTokenTitle, testTokenSymbol, testTokenUri, mintAuthorityPdaBump
     )
     .accounts({
       metadataAccount: metadataAddress,
       mintAccount: mintKeypair.publicKey,
-      mintAuthority: payer.publicKey,
+      mintAuthority: mintAuthorityPda,
+      payer: payer.publicKey,
+      rent: anchor.web3.SYSVAR_RENT_PUBKEY,
       systemProgram: anchor.web3.SystemProgram.programId,
       tokenProgram: anchor.utils.token.TOKEN_PROGRAM_ID,
       tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
     })
-    .signers([payer.payer, mintKeypair])
+    .signers([mintKeypair, payer.payer])
     .rpc();
   });
 
   it("Mint to a wallet!", async () => {
 
+    const [mintAuthorityPda, mintAuthorityPdaBump] = await anchor.web3.PublicKey.findProgramAddress(
+      [
+        Buffer.from("mint_authority_"),
+        mintKeypair.publicKey.toBuffer(),
+      ],
+      program.programId,
+    );
+    console.log(`PDA: ${mintAuthorityPda}`);
+    console.log(`Bump: ${mintAuthorityPdaBump}`);
+
     const amountToMint = 1;
 
     const tokenAddress = await anchor.utils.token.associatedAddress({
         mint: mintKeypair.publicKey,
         owner: payer.publicKey
     });
+    console.log(`Token Address: ${tokenAddress}`);
 
-    // Transact with the "mint_to_wallet" function in our on-chain program
-    //
-    await program.methods.mintToWallet(new anchor.BN(amountToMint))
+    await program.methods.mintToWallet(
+      new anchor.BN(amountToMint), mintAuthorityPdaBump
+    )
     .accounts({
       mintAccount: mintKeypair.publicKey,
+      mintAuthority: mintAuthorityPda,
       tokenAccount: tokenAddress,
-      mintAuthority: payer.publicKey,
+      payer: payer.publicKey,
+      rent: anchor.web3.SYSVAR_RENT_PUBKEY,
       systemProgram: anchor.web3.SystemProgram.programId,
       tokenProgram: anchor.utils.token.TOKEN_PROGRAM_ID,
       associatedTokenProgram: anchor.utils.token.ASSOCIATED_PROGRAM_ID,
     })
-    .signers([payer.payer, mintKeypair])
+    // .signers([payer.payer])
     .rpc();
-});
+  });
 });