交易模拟失败:该程序不能用于执行指令

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

我一直在研究 Solana 的 hello world,但我正在尝试使用 solana Python 模块执行用 Rust 编写的智能合约,以便真正理解过程如何进行。我已经成功地将以下智能合约部署到 localhost 测试验证器上:

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(())
}

这部署得很好,我已经成功创建帐户并使用下面的 Python 代码交易令牌:

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)))

但是,当我尝试使用 program_id 作为智能合约的 public 密钥执行智能合约时,在使用以下代码部署该合约后:

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)

但是,我收到错误消息:

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

我一直在阅读这个主题,我有点不知所措。我猜我必须为智能合约数据创建一个帐户。有谁知道让智能合约正常工作所需的步骤吗?

为了在程序上执行指令,程序数据帐户必须标记为executable

确保在 CLI 中使用 solana program deploy 部署程序并且部署成功。

您可以使用 getAccountInfo

检查在 publicKey 上部署的内容以及它是否被标记为可执行文件