0

Below is the Python code I wrote to try to engage the logs of a deployed program.

I don't know why I keep getting the following error: An error occurred: 'solders.transaction.Transaction' object has no attribute 'recent_blockhash'

I've tried multiple ways, such as following:

transaction = Transaction([payer], message, recent_blockhash=recent_blockhash )
transaction = Transaction([payer], message, recent_blockhash )
transaction = Transaction([payer], message, Hash.from_string(recent_blockhash) )

None of the above works, what am I doing wrong here?

Full code:


import asyncio
import json
from solana.rpc.async_api import AsyncClient
from solders.pubkey import Pubkey
from solders.instruction import Instruction
from solders.hash import Hash
from solders.transaction import Transaction
from solders.signature import Signature
from solders.message import Message
from pathlib import Path
from solders.rpc.config import RpcSendTransactionConfig
from solders.commitment_config import CommitmentConfig
from solders.commitment_config import CommitmentLevel




async def send_transaction_and_get_logs(program_id_str, keypair_path):
    async with AsyncClient("https://api.devnet.solana.com") as client:
        res = await client.is_connected()
    print(res)  # True

    with Path(keypair_path).open() as f:
        keypair_data = json.load(f)
    from solders.keypair import Keypair
    payer = Keypair.from_bytes(bytes(keypair_data))
    
    # Alternatively, close the client explicitly instead of using a context manager:
    client = AsyncClient("https://api.devnet.solana.com")
    res = await client.is_connected()
    #blockhash = await client.get_latest_blockhash()
    blockhash_response = await client.get_latest_blockhash()
    print ( blockhash_response )
    recent_blockhash = blockhash_response.value.blockhash
    print(recent_blockhash)  # True
    
    program_id = Pubkey.from_string(program_id_str)
    ix = Instruction(program_id, bytes(), [])
    
    message = Message([ix], payer.pubkey())
   
    transaction = Transaction([payer], message, recent_blockhash=recent_blockhash )
    
    try:
        tx_sig = await client.send_transaction(transaction, [payer], RpcSendTransactionConfig(preflight_commitment=CommitmentLevel.Confirmed))
        print(f"Transaction sent successfully. Signature: {tx_sig}")

            # Fetching and printing logs is not directly supported here; see note below
    except Exception as e:
        print(f"An error occurred: {e}")
    
    await client.close()

program_id_str = "4E2F4XWygkcrZLLpnZnkV4bsAU7UfwfXpQ9Px7HGFiqP"
keypair_path = "/home/pythonstuff/.config/solana/id.json"
asyncio.run(send_transaction_and_get_logs(program_id_str, keypair_path))

1 Answer 1

1

It looks like you're very close. The Transaction type in solders seems to have a constructor that just takes the hash directly, ie:

    transaction = Transaction([payer], message, recent_blockhash)

So you'll just need to make sure that the blockhash is correct, so you might need to do:

recent_blockhash = Hash.from_string(blockhash_response.value.blockhash)

Before passing it in to the Transaction constructor.

I looked at the solders transaction tests to see how they were being constructed, ie. https://github.com/kevinheavey/solders/blob/b14a24010b1dd2e99fb5011e4e4503d3789a1e9c/tests/test_transaction.py#L398

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.