In the code reproduced below from this link we have client code creating and sending instruction to create a new account:
describe("Create a system account", async () => {
const connection = new Connection(`http://localhost:8899`, 'confirmed');
const payer = createKeypairFromFile(require('os').homedir() + '/.config/solana/id.json');
const program = createKeypairFromFile('./program/target/so/program-keypair.json');
it("Create the account", async () => {
const newKeypair = Keypair.generate();
let ix = new TransactionInstruction({
keys: [
{pubkey: payer.publicKey, isSigner: true, isWritable: true},
{pubkey: newKeypair.publicKey, isSigner: true, isWritable: true},
{pubkey: SystemProgram.programId, isSigner: false, isWritable: false}
],
programId: program.publicKey,
data: Buffer.alloc(0),
});
await sendAndConfirmTransaction(
connection,
new Transaction().add(ix),
[payer, newKeypair]
);
});
});
here the new account to be created is represented by the public key newKeypair.publicKey
.
The Solana program that process the instruction, which can be found via this link looks thus:
fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
let payer = next_account_info(accounts_iter)?;
let new_account = next_account_info(accounts_iter)?;
let system_program = next_account_info(accounts_iter)?;
msg!("Program invoked. Creating a system account...");
msg!(" New public key will be: {}", &new_account.key.to_string());
invoke(
&system_instruction::create_account(
&payer.key, // From pubkey
&new_account.key, // To pubkey
1 * LAMPORTS_PER_SOL, // Lamports (1 SOL)
0, // Space
&system_program::ID, // Owner
),
&[
payer.clone(), new_account.clone(), system_program.clone() // Accounts involved
]
)?;
msg!("Account created succesfully.");
Ok(())
}
I understand when calling Solana programs we pass in, the accounts that the run time should retrieve that will be needed for executing the instructions. In the case above, where we are including an account that does not exist (the instruction we are passing in, is actually for it to be created) how then does the Solana program load a non-existing account?
Specifically this line:
let new_account = next_account_info(accounts_iter)?;
Why does not not error since the program does not exist until the &system_instruction::create_account
call is invoked?