Skip to main content
replaced UncheckedAccount with SystemAccount in struct because it is safer
Source Link

Every Instruction receives Accounts as arguments, most accounts are passed in with Account<'info, Type> or Program<'info, ProgramType> in the anchor framework. This is because anchor expects you to do some checks on every account you pass in, if these checks are not properly done, you are at risk of a security flaw. Account<'info, Type> checks that the Account passed in is a program-owned account of the type Type. Type can be your custom type in your custom program or it can be a type of another program like Mint or TokenAccount. Program<'info, ProgramType> checks that the Account passed in is a program account(executable is set to true). ProgramType is usually used for System or Token or when performing cpi calls.

UncheckedAccount just means that you are not performing any implicit checks on that account by anchor. It is the same as AccountInfo but it was named UncheckedAccount to explicitly signify that you are aware you are blindly trusting this account. It should be avoided whenever possible as it can lead to security flaws easily. However, you can use it for a simple SOL transfer.

pub SendSol<'info>
{
   #[account(mut)]
   pub from: Signer<'info>, // UncheckedAccount can be used here but Signer checks that `from` signs the transaction

   #[account(mut)]
   pub to: UncheckedAccount<'info>SystemAccount<'info>, // UncheckedAccount or AccountInfo can also be used instead but UncheckedAccountSystemAccount is preferredused becauseto ofensure semanticsit is owned by the System Program

   pub system_program: Program<'info, System>, // UncheckedAccount can also be used here but Program checks that this Account is executable and owned by System

}

pub fn send_sol(ctx: Context<SendSol>, amount: u64) -> Result<()>
{
        let sol_transfer_ix = anchor_lang::solana_program::system_instruction::transfer(
            ctx.accounts.from.key,  
            ctx.accounts.to.key, 
            amount
        );

    invoke(
        &sol_transfer_ix, 
        &[
            ctx.accounts.from.to_account_info(),
            ctx.accounts.to.to_account_info(),
            ctx.accounts.system_program.to_account_info(),
        ]
    )?;

}

Every Instruction receives Accounts as arguments, most accounts are passed in with Account<'info, Type> or Program<'info, ProgramType> in the anchor framework. This is because anchor expects you to do some checks on every account you pass in, if these checks are not properly done, you are at risk of a security flaw. Account<'info, Type> checks that the Account passed in is a program-owned account of the type Type. Type can be your custom type in your custom program or it can be a type of another program like Mint or TokenAccount. Program<'info, ProgramType> checks that the Account passed in is a program account(executable is set to true). ProgramType is usually used for System or Token or when performing cpi calls.

UncheckedAccount just means that you are not performing any implicit checks on that account by anchor. It is the same as AccountInfo but it was named UncheckedAccount to explicitly signify that you are aware you are blindly trusting this account. It should be avoided whenever possible as it can lead to security flaws easily. However, you can use it for a simple SOL transfer.

pub SendSol<'info>
{
   #[account(mut)]
   pub from: Signer<'info>, // UncheckedAccount can be used here but Signer checks that `from` signs the transaction

   #[account(mut)]
   pub to: UncheckedAccount<'info>, // AccountInfo can also be used instead but UncheckedAccount is preferred because of semantics

   pub system_program: Program<'info, System>, // UncheckedAccount can also be used here but Program checks that this Account is executable and owned by System

}

pub fn send_sol(ctx: Context<SendSol>, amount: u64) -> Result<()>
{
        let sol_transfer_ix = anchor_lang::solana_program::system_instruction::transfer(
            ctx.accounts.from.key,  
            ctx.accounts.to.key, 
            amount
        );

    invoke(
        &sol_transfer_ix, 
        &[
            ctx.accounts.from.to_account_info(),
            ctx.accounts.to.to_account_info(),
            ctx.accounts.system_program.to_account_info(),
        ]
    )?;

}

Every Instruction receives Accounts as arguments, most accounts are passed in with Account<'info, Type> or Program<'info, ProgramType> in the anchor framework. This is because anchor expects you to do some checks on every account you pass in, if these checks are not properly done, you are at risk of a security flaw. Account<'info, Type> checks that the Account passed in is a program-owned account of the type Type. Type can be your custom type in your custom program or it can be a type of another program like Mint or TokenAccount. Program<'info, ProgramType> checks that the Account passed in is a program account(executable is set to true). ProgramType is usually used for System or Token or when performing cpi calls.

UncheckedAccount just means that you are not performing any implicit checks on that account by anchor. It is the same as AccountInfo but it was named UncheckedAccount to explicitly signify that you are aware you are blindly trusting this account. It should be avoided whenever possible as it can lead to security flaws easily. However, you can use it for a simple SOL transfer.

pub SendSol<'info>
{
   #[account(mut)]
   pub from: Signer<'info>, // UncheckedAccount can be used here but Signer checks that `from` signs the transaction

   #[account(mut)]
   pub to: SystemAccount<'info>, // UncheckedAccount or AccountInfo can also be used instead but SystemAccount is used to ensure it is owned by the System Program

   pub system_program: Program<'info, System>, // UncheckedAccount can also be used here but Program checks that this Account is executable and owned by System

}

pub fn send_sol(ctx: Context<SendSol>, amount: u64) -> Result<()>
{
        let sol_transfer_ix = anchor_lang::solana_program::system_instruction::transfer(
            ctx.accounts.from.key,  
            ctx.accounts.to.key, 
            amount
        );

    invoke(
        &sol_transfer_ix, 
        &[
            ctx.accounts.from.to_account_info(),
            ctx.accounts.to.to_account_info(),
            ctx.accounts.system_program.to_account_info(),
        ]
    )?;

}

Source Link

Every Instruction receives Accounts as arguments, most accounts are passed in with Account<'info, Type> or Program<'info, ProgramType> in the anchor framework. This is because anchor expects you to do some checks on every account you pass in, if these checks are not properly done, you are at risk of a security flaw. Account<'info, Type> checks that the Account passed in is a program-owned account of the type Type. Type can be your custom type in your custom program or it can be a type of another program like Mint or TokenAccount. Program<'info, ProgramType> checks that the Account passed in is a program account(executable is set to true). ProgramType is usually used for System or Token or when performing cpi calls.

UncheckedAccount just means that you are not performing any implicit checks on that account by anchor. It is the same as AccountInfo but it was named UncheckedAccount to explicitly signify that you are aware you are blindly trusting this account. It should be avoided whenever possible as it can lead to security flaws easily. However, you can use it for a simple SOL transfer.

pub SendSol<'info>
{
   #[account(mut)]
   pub from: Signer<'info>, // UncheckedAccount can be used here but Signer checks that `from` signs the transaction

   #[account(mut)]
   pub to: UncheckedAccount<'info>, // AccountInfo can also be used instead but UncheckedAccount is preferred because of semantics

   pub system_program: Program<'info, System>, // UncheckedAccount can also be used here but Program checks that this Account is executable and owned by System

}

pub fn send_sol(ctx: Context<SendSol>, amount: u64) -> Result<()>
{
        let sol_transfer_ix = anchor_lang::solana_program::system_instruction::transfer(
            ctx.accounts.from.key,  
            ctx.accounts.to.key, 
            amount
        );

    invoke(
        &sol_transfer_ix, 
        &[
            ctx.accounts.from.to_account_info(),
            ctx.accounts.to.to_account_info(),
            ctx.accounts.system_program.to_account_info(),
        ]
    )?;

}