Solana:在链上创建 PDA 账户

Solana: Create PDA account on chain

我正在尝试编写一个 Solana 程序,在链上为我创建一个 PDA 帐户。我无法让它工作,老实说,不知道我做错了什么:/

我的 Solana 程序中有以下代码:

        let account_info_iter = &mut accounts.iter();
        let initializer = next_account_info(account_info_iter)?;

        if !initializer.is_signer {
            return Err(ProgramError::MissingRequiredSignature);
        }

        let (pda, bump_seed) = Pubkey::find_program_address(&[b"admin_account"], program_id);
        let admin_account = next_account_info(account_info_iter)?;

        
        if admin_account.key != &pda {
            return Err(CustomError::InvalidAdminAccount.into());
        }

        // we are checking if the account is rent exempt. In case it is, the account is already initialized
        if **admin_account.try_borrow_lamports()? > 0 {
            msg!("This account is already initialised. skipping");
            return Ok(())
        }

        let lamports = Rent::default().minimum_balance(1);

        let ix = solana_program::system_instruction::create_account(
            initializer.key,
            admin_account.key,
            lamports,
            1,
            program_id,
        );

        // Sign and submit transaction
        invoke_signed(
            &ix,
            &[initializer.clone(), admin_account.clone()],
            &[&[b"admin_account"], &[&[bump_seed]]]
        )?;

这是我的 Python 脚本:


    pda_account, nonce = PublicKey.find_program_address([b"admin_account"], PROGRAM_ID)
    
    init_ix = TransactionInstruction(
        data=bytes(1),
        keys=[
            AccountMeta(pubkey=ADMIN_KEYPAIR.public_key, is_signer=True, is_writable=False),
            AccountMeta(pubkey=pda_account, is_signer=False, is_writable=True),
        ],
        program_id=PROGRAM_ID,
    )

    transaction = Transaction()
    transaction.add(init_pantos_token_ix)

    utils.send_and_confirm_tx(CLIENT, transaction, ADMIN_KEYPAIR)

每当我执行交易时,我都会收到以下错误消息:

Transaction simulation failed: Error processing Instruction 0: An account required by the instruction is missing

但是缺少什么帐户?我尝试使用系统程序,但这给了我另一个错误:/ 有人有什么想法吗?

确实需要在top-level处传入系统程序,然后在invoke_signed处传入是可选的。所以你的 python 脚本应该做:

    init_ix = TransactionInstruction(
        data=bytes(1),
        keys=[
            AccountMeta(pubkey=ADMIN_KEYPAIR.public_key, is_signer=True, is_writable=True),
            AccountMeta(pubkey=pda_account, is_signer=False, is_writable=True),
            AccountMeta(pubkey=solana.system_program.SYS_PROGRAM_ID, is_signer=False, is_writable=False)
        ],
        program_id=PROGRAM_ID,
    )

请注意,您的 ADMIN_KEYPAIR 也需要可写才能将 lamports 从它移动到 pda 帐户。 client-side 上的这些更改应该可以工作。