Reputation: 463
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
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