I'm new in Solana and tries to reassign account's owner.
I do next:
- Deploy program
- Create account with owner = program deployed id
- Call program, which change owner
But on step 3 I got error:
SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account
My entrypoint:
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
msg,
program::{invoke, invoke_signed},
program_error::ProgramError,
program_pack::{IsInitialized, Pack},
pubkey::Pubkey,
sysvar::{rent::Rent, Sysvar},
entrypoint
};
use std::str::FromStr;
use solana_program::system_instruction::SystemInstruction;
use spl_token::state::Account as TokenAccount;
use crate::{error::EscrowError, instruction::EscrowInstruction, state::Escrow};
use crate::processor::Processor;
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let iter = &mut accounts.iter();
let account = next_account_info(iter)?;
if account.owner != program_id {
return Err(ProgramError::IncorrectProgramId);
}
let str = "11111111111111111111111111111111";
let system_program: Pubkey = Pubkey::from_str(str).unwrap();
let instr = solana_program::system_instruction::assign(account.key, &system_program);
invoke_signed(
&instr,
&[account.clone()],
&[&[&program_id.as_ref()]]
)?;
Ok(())
}
My client code:
import {
Connection,
CreateAccountParams,
Keypair,
PublicKey,
SystemProgram,
Transaction,
sendAndConfirmTransaction, TransactionInstruction,
} from "@solana/web3.js";
//@ts-expect-error missing types
import * as BufferLayout from "buffer-layout";
import * as fs from "fs";
import {getPrivateKey} from "./utils";
const key = Keypair.fromSecretKey(getPrivateKey("my_key"));
const reassignFunc = async () => {
const connection = new Connection("http://127.0.0.1:8899", "confirmed");
const to = Keypair.generate();
console.log(to.publicKey.toString());
const createInstr = SystemProgram.createAccount({
fromPubkey: key.publicKey,
newAccountPubkey: to.publicKey,
lamports: 4_000_000,
space: 0,
programId: SystemProgram.programId,
});
let transaction = new Transaction().add(createInstr);
let res = await sendAndConfirmTransaction(connection, transaction, [key, to]);
console.log(res);
const assignInstr = SystemProgram.assign({
accountPubkey: to.publicKey,
programId: new PublicKey("FhNwgZtYLE87ugXmUEthdYEGs8KbYoLUhnYpy74gEr8s"),
});
transaction = new Transaction().add(assignInstr);
res = await sendAndConfirmTransaction(connection, transaction, [to]);
console.log(res);
const assignInstr2 = new TransactionInstruction({
programId: new PublicKey("FhNwgZtYLE87ugXmUEthdYEGs8KbYoLUhnYpy74gEr8s"),
keys: [{pubkey: to.publicKey, isSigner: false, isWritable: true}]
});
transaction = new Transaction().add(assignInstr2);
res = await sendAndConfirmTransaction(connection, transaction, [key]);
console.log(res);
};
reassignFunc();
How can I fix my code to fix third transaction.