1

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.

2 Answers 2

1

To reassign from your program back to another, you can't use system_instruction::assign, because the account belongs to your program, and not the system program. The system program can only assign from accounts that it owns.

To do this properly, you simply need to do:

account.assign(&solana_program::system_program::id());

Based on an example from the spl-token program: https://github.com/solana-labs/solana-program-library/blob/80624e7a1a996613e8266dbc7d72575740354687/token/program/src/processor.rs#L1015

0

https://docs.rs/solana-program/1.15.2/solana_program/system_instruction/fn.assign.html

It seems the to account must be a signer when you run the assiignInstruction 2.

1
  • No, I've tried with second account and got error -- SendTransactionError: failed to send transaction: Transaction simulation failed: This account may not be used to pay transaction fees Commented Apr 22, 2023 at 14:33

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.