0

I want to implement a Escrow service on Solana using the Anchor framework but I'm having huge difficulties on understanding how it works...

Even by starting from the creation of the Escrow, I cannot understand if I'm on the right way or not. This is the create_escrow function.

use anchor_lang::prelude::*;

declare_id!("CMSazRrJJUM1XtXKBbtvVxsTY5XirkQ7eQspKSQrb9rb");

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

    pub fn create_escrow(ctx: Context<CreateEscrow>, receiver: Pubkey, approver: Pubkey, amount: u64, approver_fees: u64, message: String) -> Result<()> {
        let escrow: &mut Account<Escrow> = &mut ctx.accounts.escrow;
        escrow.receiver = receiver;
        escrow.approver = approver;
        escrow.amount = amount;
        escrow.message = message.clone();
        escrow.approver_fees = approver_fees;   
        escrow.timestamp = Clock::get()?.unix_timestamp;

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

        msg!("Receiver: {}", escrow.receiver);
        Ok(())
    }
}

#[derive(Accounts)]
pub struct CreateEscrow<'info> {
    #[account(init, payer = user, space = 8 + 32 + 32 + 8 + 1024 + 8)]
    pub escrow: Account<'info, Escrow>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[account]
pub struct Escrow {
    pub receiver: Pubkey,
    pub approver: Pubkey,
    pub amount: u64,
    pub approver_fees: u64,
    pub message: String,
    pub timestamp: i64,
}

I want that when a user create an escrow, he passes the receiver, the approver, the amount a message and the approver fees. The amount will be moved from the sender to the program itself so that it will be locked until the approver will approve or reject it.

Does the code I wrote make any sense (excluding the approve/reject functions for the moment)?

Moreover, I get the error: cannot borrow 'ctx.accounts.escrow' as immutable because it is also borrowed as mutable immutable borrow occurs here at &ctx.accounts.escrow.key() and at ctx.accounts.escrow.to_account_info(). I cannot understand why and how to solve it.

Thank you in advanced!

1 Answer 1

3

You violated borrow checker rules.

You borrow the Escrow account as a mutable variable here let escrow: &mut Account<Escrow> = &mut ctx.accounts.escrow; but try to use it as an immutable reference here &ctx.accounts.escrow.key()

change your method to use the mutable account ref instead

        let escrow: &mut Account<Escrow> = &mut ctx.accounts.escrow;
        escrow.receiver = receiver;
        escrow.approver = approver;
        escrow.amount = amount;
        escrow.message = message.clone();
        escrow.approver_fees = approver_fees;
        escrow.timestamp = Clock::get()?.unix_timestamp;

        let ix = anchor_lang::solana_program::system_instruction::transfer(
            &ctx.accounts.user.key(),
            &escrow.key(),
            amount,
        );
        anchor_lang::solana_program::program::invoke(
            &ix,
            &[
                ctx.accounts.user.to_account_info(),
                escrow.to_account_info(),
            ],
        )?;
1
  • Thanks for the help!
    – Francesco
    Commented May 29 at 15:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.