简体   繁体   English

通过 system_instruction::create_account(带锚框架的链上程序)创建新帐户时,Solana CPI(运行时)调用失败

[英]Solana CPI (runtime) invoke fails when creating a new account by system_instruction::create_account (on-chain program with anchor framework)

I am trying to create a simple program that lets users mint SPL tokens.我正在尝试创建一个简单的程序,让用户铸造 SPL 令牌。 This program is bootstrapped by Anchor.该程序由 Anchor 引导。 Unfortunately, It failed on very first step creating a PDA account by CPI.不幸的是,它在通过 CPI 创建 PDA 帐户的第一步失败了。 Please see the detailed info below:请参阅以下详细信息:

----Processors------ ----处理器------

I tried to simplify the on-chain program's processor to create a simple PDA account using Solana system program.我尝试简化链上程序的处理器以使用 Solana 系统程序创建一个简单的 PDA 帐户。 The processor has only one CPI.处理器只有一个 CPI。

----Instructions----- - - 指示 - - -

I also tried to simplify the instruction by only inputting 4 accounts(See the screenshot or my code attached herewith): In typescript test code, it is also pretty simple.我还尝试通过仅输入 4 个帐户来简化指令(请参见屏幕截图或我随附的代码): 在 typescript 测试代码中,它也非常简单。 I just derive a PDA and then pass this PDA and the rest 3 accounts into the instruction.我只是导出一个PDA,然后将这个PDA和rest 3个账户传到指令中。 (two constraints 1. Assign a signer 2. Set mut for PDA account) (两个约束 1. 分配签名者 2. 为 PDA 帐户设置 mut)

-----Error----- - - -错误 - - -

But I still get the error但我仍然收到错误

Transaction simulation failed: Error processing Instruction 0: An account required by the instruction is missing 
    Program 6KA5onmgQN7gsBZ5whPCTVL4EQcRob6vw7TYYNvik8xb invoke [1]
    Program log: Instruction: Mintnft
    Program log: First line in MintNFT processor
    Instruction references an unknown account 11111111111111111111111111111111
    Program 6KA5onmgQN7gsBZ5whPCTVL4EQcRob6vw7TYYNvik8xb consumed 15319 of 200000 compute units
    Program 6KA5onmgQN7gsBZ5whPCTVL4EQcRob6vw7TYYNvik8xb failed: An account required by the instruction is missing
    1) is minted


  2 passing (2s)
  1 failing

  1) anchor_programs
       is minted:
     Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: An account required by the instruction is missing
      at Connection.sendEncodedTransaction (node_modules/@solana/web3.js/src/connection.ts:3961:13)
      at processTicksAndRejections (internal/process/task_queues.js:97:5)
      at Connection.sendRawTransaction (node_modules/@solana/web3.js/src/connection.ts:3918:20)
      at sendAndConfirmRawTransaction (node_modules/@solana/web3.js/src/util/send-and-confirm-raw-transaction.ts:27:21)
      at Provider.send (node_modules/@project-serum/anchor/src/provider.ts:118:18)
      at Object.rpc [as mintnft] (node_modules/@project-serum/anchor/src/program/namespace/rpc.ts:25:23)

It seems that I did not pass the correct accounts into the invoke body, but I have spent like a whole day checking but still not sure if there are any other missing accounts ( or AccountInfo).似乎我没有将正确的帐户传递到调用主体中,但我花了一整天的时间检查但仍然不确定是否还有其他丢失的帐户(或 AccountInfo)。 It will be super appreciated if anyone can give me a hint.如果有人能给我提示,我将不胜感激。 You can see the summary of my code attached in a screenshot format.您可以看到以屏幕截图格式附加的我的代码摘要。

.src/lib.rs .src/lib.rs

use anchor_lang::prelude::*;
use anchor_spl::token::Mint;
use solana_program::program::invoke;
use solana_program::system_instruction;


declare_id!("ArT6Hwus2hMwmNeNeJ2zGcQnvZsbrhz8vTbBdq35AdgG");

#[program]
pub mod anchor_programs {
    use super::*;
    pub fn initialize(ctx: Context<Initialize>, price: u64) -> ProgramResult {
        ctx.accounts.nft_creator.price = price;
        ctx.accounts.nft_creator.collection = vec![];
        
        Ok(())
    }    
    pub fn mintnft(ctx: Context<MintNFT>) -> ProgramResult {
        msg!("First line in MintNFT processor");
        let (mint_pda, _bump) = Pubkey::find_program_address(           // Calc PDA address from passed in nft_creater_program_id
            &[b"nft_creator"], 
            &ctx.accounts.nft_creater_program.key()
        );
        if mint_pda != ctx.accounts.mint_pda_acc.key()  {                         // Confirm if passed in PDA address is the same
            return Err(ProgramError::Custom(123))
        }
        let create_acc_ix = system_instruction::create_account(        // Try create account using system_instruction
            &ctx.accounts.minter.key(),
            &ctx.accounts.mint_pda_acc.key(),
            ctx.accounts.rent.minimum_balance(Mint::LEN),
            Mint::LEN as u64,
            &spl_token::ID,
        );
        invoke(&create_acc_ix, &[                          // Use invoke to call cross program invocation
            ctx.accounts.minter.clone(),
            ctx.accounts.mint_pda_acc.clone(),
        ])?;        
        Ok(())
    }
    
}
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init, payer=initializer, space=500)] 
    pub nft_creator: Account<'info, NftCreator>,
    #[account(mut, signer)]
    pub initializer: AccountInfo<'info>,
    pub system_program: AccountInfo<'info>,
    pub rent: Sysvar<'info, Rent>
}
#[derive(Accounts)]
pub struct MintNFT<'info> {
    #[account(mut, signer)]
    pub minter: AccountInfo<'info>,
    pub nft_creater_program: AccountInfo<'info>,
    #[account(mut)]
    pub mint_pda_acc: AccountInfo<'info>,
    pub rent: Sysvar<'info, Rent>
}
#[account]
pub struct NftCreator {
    collection: Vec<Pubkey>,
    price: u64
}



./tests/anchor_programs.ts ./tests/anchor_programs.ts

...

  it('is minted', async () => {
    let [mint_pda, _bump] = await anchor.web3.PublicKey.findProgramAddress(               // Use findProgram Address to generate PDA
        [Buffer.from(anchor.utils.bytes.utf8.encode("nft_creator"))],
        program.programId
    )


    const tx = await program.rpc.mintnft({                                                // Call program mintnft instruction
        accounts: {                                                                       /**@ACCOUNTS */
            // tokenProgram: TOKEN_PROGRAM_ID,
            minter: initializerMainAccount.publicKey,                                       // 1. minter as the initializer
            // nftCreater: nftCreatorAcc.publicKey,
            nftCreaterProgram: program.programId,                                           // 2. this program id
            mintPdaAcc: mint_pda,                                                           // 3. The mint_pda just generated
            // mintPdaAcc: mint_pda.publicKey,
            rent: anchor.web3.SYSVAR_RENT_PUBKEY,                                           // 4. sysVar 
        },
        signers: [initializerMainAccount]
    });
    console.log("Your transaction signature", tx);    
  });
});

Or refer to the full anchor project code in the github repo或者参考github repo中的完整锚点项目代码

I realized the issue:我意识到了这个问题:

  1. I did not pass the system_program into instruction.我没有将 system_program 传递给指令。
pub system_program: Program<'info, System>
  1. Need to use invoke_signed to also let pda to sign需要使用 invoke_signed 也让 pda 签名
invoke_signed(                                                            
            &create_acc_ix,                                             
            &[                          
                self.minter.clone(),
                self.mint_pda_acc.clone(),
            ],
            &[&[ &mint_seed.as_ref(), &[*bump_seed] ]]
        )?;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 交易模拟失败:错误处理指令0:使用未经授权的签名者或可写帐户进行跨程序调用 - Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account 在 Solana Anchor 框架中初始化 PDA 的正确方法 - Proper way to initialize PDAs within the Solana Anchor framework 错误处理指令0:账户数据序列化或反序列化失败:未知 - Error processing Instruction 0: Failed to serialize or deserialize account data: Unknown 条纹:未知参数([object Object])。 在连接的帐户上创建新计划时出错 - Stripe: Unknown arguments ([object Object]). Error on creating a new plan on a connected account 是否可以在其他帐户中创建规则? - Is it possible to create a rule in a different account? 如何创建一个 pipe 来格式化帐号? - How to create a pipe to format account numbers? 是否可以使用 CDK 从不同帐户在代码管道中调用 lambda? - Is it possible to invoke a lambda in code pipeline from a different account using CDK? 为 Solana 锚测试加载工作区 IDL 时出错 - Error loading workspace IDL for Solana Anchor Testing 成功调用函数后,如何从https可调用函数创建新帐户以及如何将浏览器的身份验证状态更改为登录状态 - How to create a new account from https callable function and change the auth state of browser to logged in after successful invocation of the function 部署跨账户 Sagemaker 端点时出错 - Error when deploying cross account Sagemaker Endpoints
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM