Sending solana transactions with python

Question:

I want to buy Solana coins and nfts with python and I am not sure, how transactions via the blockchain exactly work. Let’s say I want to do this transaction: https://solscan.io/tx/5fzuhifWuBFRPtRGHRRsWsJVHuoxcgEN4USzNBu3ZS8VxwL6Fdw8BFaqU4iAEGibQpEAJyG19QhB335K1HiRtQWX
and this is my code:

import solana.system_program as sp
from solana.publickey import PublicKey
from solana.account import Account
from solana.rpc.api import Client
from solana.transaction import Transaction, TransactionInstruction, AccountMeta

# keypair = your key pair
cli = Client('https://solana-api.projectserum.com')
account = Account(keypair[:32])
new_account = Account()
print(new_account.public_key())
print(new_account.keypair())
transaction = Transaction()
transaction.add(sp.create_account(sp.CreateAccountParams(
        from_pubkey=account.public_key(),
        new_account_pubkey=new_account.public_key(),
        lamports=cli.get_minimum_balance_for_rent_exemption(88).get('result'),
        space=88,
        program_id=PublicKey('CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz'),
    )))
send_tx = cli.send_transaction(transaction, new_account)
print(send_tx)

I know that I don’t have enough solana in my test wallet right now, but it’s more about the general way to send transactions and to interact with program ids. There is some Data shown in the sollet.io transaction, but I am not sure, if I have to send that too? And if I have to, where exactly and how do I include that? Does the data change for each transaction?
I get the error message:

{'code': -32602, 'message': 'invalid transaction: index out of bounds'}

Asked By: questionmaster69

||

Answers:

You’re on the right track here. If you want to mimic a similar transaction to the one referenced in Solscan, you’ll need to create the correct instruction, including the encoded data and accounts referenced. This will be a bit difficult without available Python bindings, but going off of the example, it would probably look a little bit like:

transaction = Transaction()
transaction.add(TransactionInstruction(
    [
        AccountMeta(
            PublicKey("3LdbrFBY7sZ71MtuZhrMzK4YLgxNcTrQ5wLNZHs7r85T"),
            False,
            False
        ),
        AccountMeta(
            PublicKey("FABkSFDkF3Wz3CpC5JTmw44jeKvXKQvXgXFCyxhAE46X"),
            False,
            False
        ),
        ...
    ],
    PublicKey("CJsLwbP1iu5DuUikHEJnLfANgKy6stB2uFgvBBHoyxwz"),
    bytearray.fromhex('050000000000000000')
))

The important things to note:

  • the first field is a list of AccountMetas, same as in that transaction you linked
  • the second field is the program’s public key
  • the last field is the "instruction data"

You’ll have to also provide a valid signer / payer for the transaction, but it should go though after that!

Answered By: Jon C
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.