I am new to Rust.
I am writing a Solana contract and encountered this problem during a CPI (Cross-Program Invocation) call.
I don’t completely understand lifetimes.
I know this is a rust lifetimes issue, but I don’t know how to write the code.
When calling the invoke_signed function, it exceeds the scope of payer .
use borsh::BorshSerialize;
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
program::invoke_signed,
pubkey::Pubkey,
rent::Rent,
system_instruction,
sysvar::Sysvar,
};
use crate::state::user::User;
pub fn create_user(program_id: &Pubkey, accounts: &[AccountInfo], data: User) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
let target_account = next_account_info(accounts_iter)?;
let system_program = next_account_info(accounts_iter)?;
let account_span = (data.try_to_vec()?).len();
let lamports_required = (Rent::get()?).minimum_balance(account_span);
let (payer_pub_key, bump) = Pubkey::find_program_address(
&[User::SEED_PREFIX.as_bytes(), target_account.key.as_ref()],
program_id,
);
let mut lamports = 0;//6124800;
let mut payer_data = [];
let payer = AccountInfo::new(
&payer_pub_key,
false,
false,
&mut lamports,
&mut payer_data,
program_id,
false,
0,
);
invoke_signed(
&system_instruction::create_account(
payer.key,
target_account.key,
lamports_required,
account_span as u64,
program_id,
),
&[
payer.clone(),
target_account.clone(),
system_program.clone(),
],
&[&[User::SEED_PREFIX.as_bytes(), payer.key.as_ref(), &[bump]]],
)?;
data.serialize(&mut &mut target_account.data.borrow_mut()[..])?;
Ok(())
}
The error logs
error: lifetime may not live long enough
--> program/src/instructions/create_user.rs:30:17
|
14 | pub fn create_user(program_id: &Pubkey, accounts: &[AccountInfo], data: User) -> ProgramResult {
| - -------- has type `&[AccountInfo<'2>]`
| |
| let's call the lifetime of this reference `'1`
...
30 | let payer = AccountInfo::new(
| _________________^
31 | | &payer_pub_key,
32 | | false,
33 | | false,
... |
38 | | 0,
39 | | );
| |_____^ argument requires that `'1` must outlive `'2`
error[E0597]: `payer_pub_key` does not live long enough
--> program/src/instructions/create_user.rs:31:9
|
14 | pub fn create_user(program_id: &Pubkey, accounts: &[AccountInfo], data: User) -> ProgramResult {
| -------- has type `&[AccountInfo<'2>]`
...
22 | let (payer_pub_key, bump) = Pubkey::find_program_address(
| ------------- binding `payer_pub_key` declared here
...
30 | let payer = AccountInfo::new(
| _________________-
31 | | &payer_pub_key,
| | ^^^^^^^^^^^^^^ borrowed value does not live long enough
32 | | false,
33 | | false,
... |
38 | | 0,
39 | | );
| |_____- argument requires that `payer_pub_key` is borrowed for `'2`
...
59 | }
| - `payer_pub_key` dropped here while still borrowed
error[E0597]: `lamports` does not live long enough
--> program/src/instructions/create_user.rs:34:9
|
14 | pub fn create_user(program_id: &Pubkey, accounts: &[AccountInfo], data: User) -> ProgramResult {
| -------- has type `&[AccountInfo<'2>]`
...
27 | let mut lamports = 0;//6124800;
| ------------ binding `lamports` declared here
...
30 | let payer = AccountInfo::new(
| _________________-
31 | | &payer_pub_key,
32 | | false,
33 | | false,
34 | | &mut lamports,
| | ^^^^^^^^^^^^^ borrowed value does not live long enough
... |
38 | | 0,
39 | | );
| |_____- argument requires that `lamports` is borrowed for `'2`
...
59 | }
| - `lamports` dropped here while still borrowed
error[E0597]: `payer_data` does not live long enough
--> program/src/instructions/create_user.rs:35:9
|
14 | pub fn create_user(program_id: &Pubkey, accounts: &[AccountInfo], data: User) -> ProgramResult {
| -------- has type `&[AccountInfo<'2>]`
...
28 | let mut payer_data = [];
| -------------- binding `payer_data` declared here
29 |
30 | let payer = AccountInfo::new(
| _________________-
31 | | &payer_pub_key,
32 | | false,
33 | | false,
34 | | &mut lamports,
35 | | &mut payer_data,
| | ^^^^^^^^^^^^^^^ borrowed value does not live long enough
... |
38 | | 0,
39 | | );
| |_____- argument requires that `payer_data` is borrowed for `'2`
...
59 | }
| - `payer_data` dropped here while still borrowed
The source program is here create_user.rs, and I made simple modifications to reproduce the problem
I want to know how to write the correct code? Thank you.
I want to know how to write the correct code? Thank you.