max89
max89

Reputation: 463

Transaction simulation failed: This program may not be used for executing instructions

I've been working through the hello world for Solana but I'm trying to get the smart contract written in Rust to be executed using the solana Python module in order to truly understand how the process goes. I've managed to deploy the following smart contract onto the localhost test validator:

use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
    account_info::{next_account_info, AccountInfo},
    entrypoint,
    entrypoint::ProgramResult,
    msg,
    program_error::ProgramError,
    pubkey::Pubkey,
};

/// Define the type of state stored in accounts
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct GreetingAccount {
    /// number of greetings
    pub counter: u32,
}

// Declare and export the program's entrypoint
entrypoint!(process_instruction);

// Program entrypoint's implementation
pub fn process_instruction(
    program_id: &Pubkey, // Public key of the account the hello world program was loaded into
    accounts: &[AccountInfo], // The account to say hello to
    _instruction_data: &[u8], // Ignored, all helloworld instructions are hellos
) -> ProgramResult {
    msg!("Hello World Rust program entrypoint");

    // Iterating accounts is safer than indexing
    let accounts_iter = &mut accounts.iter();

    // Get the account to say hello to
    let account = next_account_info(accounts_iter)?;

    // The account must be owned by the program in order to modify its data
    if account.owner != program_id {
        msg!("Greeted account does not have the correct program id");
        return Err(ProgramError::IncorrectProgramId);
    }

    // Increment and store the number of times the account has been greeted
    let mut greeting_account = GreetingAccount::try_from_slice(&account.data.borrow())?;
    greeting_account.counter += 1;
    greeting_account.serialize(&mut &mut account.data.borrow_mut()[..])?;

    msg!("Greeted {} time(s)!", greeting_account.counter);

    Ok(())
}

This is deployed fine and I've managed to create accounts and transact a token with the Python code below:

from solana.keypair import Keypair
from solana.publickey import PublicKey
from solana.rpc.api import Client
from solana.system_program import TransferParams, transfer
from solana.transaction import Transaction
import time

cli = Client('http://127.0.0.1:8899')
print("about to check connection")
print("here is the connection: ", cli.is_connected())

sender = Keypair()
print(sender.secret_key)
process_airdrop = Popen(f"solana --url http://127.0.0.1:8899 airdrop 1 {sender.public_key}", shell=True)
process_airdrop.wait()

receiver = Keypair()
process_airdrop = Popen(f"solana --url http://127.0.0.1:8899 airdrop 1 {receiver.public_key}", shell=True)
process_airdrop.wait()
        
time.sleep(20)

txn = Transaction().add(transfer(TransferParams(from_pubkey=sender.public_key, to_pubkey=receiver.public_key, lamports = int(5e6))))
cli.send_transaction(txn, sender)

time.sleep(20)
print("here is the sender balanace: ", self.get_account_balance(key_value=str(sender.public_key)))
print("here is the receiver balanace: ", self.get_account_balance(key_value=str(receiver.public_key)))

This works, however, when I try to execute the smart contract with the program_id being the public key of the smart contract after the deployment of that contract with the code below:

transaction = Transaction()
transaction.add(TransactionInstruction(
     [
          AccountMeta(sender.public_key, True, True),
     ],
     PublicKey(program_id),
     bytearray(0)
))

send_tx = cli.send_transaction(transaction, sender)
print("here is the transaction: ", send_tx)

However, I get the error:

Transaction simulation failed: This program may not be used for executing instructions

I've been reading around the subject and I'm a little overwhelmed. I'm guessing that I have to create an account for the smart contract data. Does anyone know the steps I need to get the smart contract working?

Upvotes: 1

Views: 3865

Answers (1)

Jacob Creech
Jacob Creech

Reputation: 2107

In order to execute instructions on a program, the program data account has to be marked executable.

Make sure you deploy your program with solana program deploy in the CLI and that the deployment is successful.

You can check what is deployed at the publicKey and if it is marked as executable with getAccountInfo

Upvotes: 1

Related Questions