简体   繁体   中英

Unable to Sign Solana Transaction using solana-py throws not enough signers

using solana library from pip

pip install solana

and then trying to perform withdraw_from_vote_account

txn = txlib.Transaction(fee_payer=wallet_keypair.pubkey())
# txn.recent_blockhash = blockhash
txn.add(
        vp.withdraw_from_vote_account(
            vp.WithdrawFromVoteAccountParams(
                vote_account_from_pubkey=vote_account_keypair.pubkey(),
                to_pubkey=validator_keypair.pubkey(),
                withdrawer=wallet_keypair.pubkey(),
                lamports=2_000_000_000,
            )
        )
    )
txn.sign(wallet_keypair)
txn.serialize_message()
solana_client.send_transaction(txn).value

This throw me an error

Traceback (most recent call last):
  File "main.py", line 119, in <module>
    solana_client.send_transaction(txn).value
  File "venv/lib/python3.8/site-packages/solana/rpc/api.py", line 1057, in send_transaction
    txn.sign(*signers)
  File "venv/lib/python3.8/site-packages/solana/transaction.py", line 239, in sign
    self._solders.sign(signers, self._solders.message.recent_blockhash)
solders.SignerError: not enough signers

I tried to workaround with adding more keypair to sign

txn.sign(wallet_keypair,validator_keypair)

Doing this it throws me an error on the sign method

self._solders.sign(signers, self._solders.message.recent_blockhash)
solders.SignerError: keypair-pubkey mismatch

not sure how to resolve this any help appreciated

when you are trying to send a transaction that's withdrawing money from a wallet, you need the wallet that's holding the assets to sign a transaction to send the assets to the withdrawer.

anyway, from what i see you are trying to withdraw from vote_account_keypair , and withdrawer os wallet_keypair , in the code that you wrote you have only one signer which is wallet_keypair but you also need vote_account_keypair to sign the transaction becuz you are withdrawing from their account.

i hope this helps

The error message isn't very useful, but you need a blockhash on the message in your transaction in order to properly sign it, ie:

blockhash = solana_client.get_latest_blockhash().value['blockhash']
txn = txlib.Transaction(recent_blockhash=blockhash, fee_payer=wallet_keypair.pubkey())

A few other notes: txn.serialize_message() doesn't modify the transaction in place, but rather returns the transaction bytes, so there's no need to call it at all.

And finally, send_transaction actually does the work of fetching the blockhash and signing the transaction, so you can simplify the whole thing to:

txn = txlib.Transaction(fee_payer=wallet_keypair.pubkey())
txn.add(
        vp.withdraw_from_vote_account(
            vp.WithdrawFromVoteAccountParams(
                vote_account_from_pubkey=vote_account_keypair.pubkey(),
                to_pubkey=validator_keypair.pubkey(),
                withdrawer=wallet_keypair.pubkey(),
                lamports=2_000_000_000,
            )
        )
    )
solana_client.send_transaction(txn, wallet_keypair).value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM