Как перенести SOL в инструкцию смарт-контракта привязки

Я создаю децентрализованное приложение, в котором несколько пользователей могут вносить SOL в учетную запись события, и в зависимости от того, кто выиграет мероприятие, они могут выкупить SOL обратно в свой кошелек.

Как я могу передать SOL (а не любой другой spl-токен) непосредственно в адрес хранилища учетной записи события в инструкции смарт-контракта привязки?

5 ответов

Чтобы отправить собственный SOL с помощью Anchor, вы можете использовать следующий код внутри инструкции:

          let ix = anchor_lang::solana_program::system_instruction::transfer(
        &ctx.accounts.from.key(),
        &ctx.accounts.to.key(),
        amount,
    );
    anchor_lang::solana_program::program::invoke(
        &ix,
        &[
            ctx.accounts.from.to_account_info(),
            ctx.accounts.to.to_account_info(),
        ],
    );

Где сумма — это число (u64), представляющее Лэмпортс (0,000000001 SOL).

Вы можете проверить функцию Transfer в документации по программе Solana и в разделе Solana Cookbook вSending SOL .

К сожалению, все ответы до сих пор относятся к простой Солане, а не к Якорю.

Якорь уже поставляется с дополнительными удобствами, облегчающими переводы. Вы были на правильном пути с кодом в вопросе:

      use anchor_lang::system_program;

let cpi_context = CpiContext::new(
    ctx.accounts.system_program.to_account_info(), 
    system_program::Transfer {
        from: ctx.accounts.account_a.clone(),
        to: ctx.accounts.account_b.clone(),
    });
system_program::transfer(cpi_context, bid_amount)?;

Это предполагает эту структуру учетных записей:

      #[derive(Accounts)]
pub struct MyInstruction<'info> {
    account_a: AccountInfo<'info>,
    account_b: AccountInfo<'info>,
}

Конечно, если вы используетеAccount<>обертки, просто заменитеclone()сto_account_info().

Вы должны сделать что-то вроде этого

      let lamports: u64  = 1000000;

let sol_transfer = anchor_lang::solana_program::system_instruction::transfer(
    &ctx.accounts.from.key,
    &ctx.accounts.to.key,
    lamports,
);
invoke(
    &sol_transfer,
    &[
        ctx.accounts.from.clone(),
        ctx.accounts.to.clone(),
        ctx.accounts.system_program.clone(),
    ],
)?;

Также не забудьте передать system_program вашей программе. Например

       #[derive(Accounts)]
pub struct SolSend<'info> {
    #[account(mut, signer)]
    /// CHECK: This is not dangerous because we don't read or write from this account
    pub from: AccountInfo<'info>,       
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub to: AccountInfo<'info>,        
    /// CHECK: This is not dangerous because we don't read or write from this account
    pub system_program: AccountInfo<'info>,
}

Надеюсь это поможет.

Для собственного SOL вам придется сделать что-то немного другое, вызвав system_instruction::transferс системной программой, а не с программой токена SPL.

В Anchor нет удобной оболочки (которую я могу найти), поэтому вот пример без Anchor: https://github.com/solana-labs/solana-program-library/blob/78cb32435296eb258ec3de76ee4ee2d391f397ee/associated- токен-счет/программа/src/tools/account.rs#L29

Чтобы отправить собственный SOL с привязкой

      #[program]
pub mod learn_solana_anchor {
    use super::*;

    pub fn transfer_native_sol(ctx: Context<Transfer>) -> Result<()> {
        let amount_of_lamports = 42; // could be an argument ;-)
        let from = ctx.accounts.from.to_account_info();
        let to = ctx.accounts.to.to_account_info();

        // Debit from_account and credit to_account
        **from.try_borrow_mut_lamports()? -= amount_of_lamports;
        **to.try_borrow_mut_lamports()? += amount_of_lamports;

        Ok(())
    }

}

#[derive(Accounts)]
pub struct Transfer<'info> {
    #[account(mut)]
    /// CHECK: This is not dangerous because its just a stackoverflow sample o.O
    pub from: AccountInfo<'info>,
    #[account(mut)]
    /// CHECK: This is not dangerous because we just pay to this account
    pub to: AccountInfo<'info>,
    #[account()]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

Ссылка

https://solanacookbook.com/references/programs.html#how-to-transfer-sol-in-a-program

Другие вопросы по тегам