0

I'm new in Solana and tries to reassign account's owner.

I do next:

  1. Deploy program
  2. Create account with owner = program deployed id
  3. 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.

Because from my point of view -- this should work well, because cross program invocation in this case doesn't require any signs, due to only signer is my program, listed above.

Nikita Duginets
  • 163
  • 1
  • 6
  • 1
    I’m voting to close this question because it's been asked on the Solana Stack Exchange at https://solana.stackexchange.com/questions/6450/got-error-cross-program-invocation-with-unauthorized-signer-or-writable-account/6456#6456 – Jon C Apr 23 '23 at 14:33
  • answered here: https://solana.stackexchange.com/a/6456/4596 – Nikita Duginets Apr 24 '23 at 20:46

0 Answers0