1

For extra security I want to validate a transaction signature before further processing. I'm getting the TransactionSignature from get_transaction and the json looks similar to this..

{ 
    slot: 327, 
    transaction: EncodedTransactionWithStatusMeta(EncodedTransactionWithStatusMeta { 
        transaction: Json(UiTransaction { 
            signatures: ["39KgKCP..."],
            message: Raw(UiRawMessage { 
                ...,
                account_keys: [
                    "Ai1f6bfbWVfbmaiRciZanknE6U...", //user 
                    "AJc89876CYwrmN6dEHgMRBerw7...", //item Account
                    "7i57Rf9qHN16JukEh12iXDPaWo...", // <- Want to confirm this
                    "9KjfZKeCDeo8AU9pzxQZKskiTx...", //another account
                    "6ihFxDWJoA6f6bj9fdsfew33ohJ6n7kg", //program ID
                    "11111111111111111111111111111111", //system
                    "SysvarRent111111111111111111111111111111111" //rent
                ], 
                recent_blockhash: "9Uoo2fQ1BwMgF5ZSqHmbYhujF4cuQxtnbaWpMQu67Ffh", 
                ...
            }) 
        }), 
        
        meta: Some(UiTransactionStatus ....

I'm breaking down this JSON data to receive the account_keys array and I want to confirm account_keys[2] is a certain account. So my question is, will the order of these account keys change randomly or is this a static order?

I want to be able to verify account_keys[2] to always be a certain value so just want to make sure this will not change.

I should mention that the reason this began as a concern is because in the Anchor Program, this is not the order in which the accounts are listed and I was confused why the order was changed this way.

1 Answer 1

1

To put it briefly, even if people call into your program the same way, then this might be brittle. If possible, you should decompile the message into component instructions rather than try to read the raw message.

To put it less briefly, you should read through the "anatomy of a transaction" docs to see how we get to the final serialized transaction at https://solana.com/docs/core/transactions#anatomy-of-a-transaction

The most important bits for you are:

A message contains a header, followed by a compact-array of account addresses, followed by a recent blockhash, followed by a compact-array of instructions.

Account Addresses Format #

The addresses that require signatures appear at the beginning of the account address array, with addresses requesting read-write access first, and read-only accounts following. The addresses that do not require signatures follow the addresses that do, again with read-write accounts first and read-only accounts following.

Other than the ordering of signer pubkeys, writable pubkeys, then read-only pubkeys, there's no guarantee that keys will appear in a particular order in the transaction that you receive.

For example, if someone adds a transfer instruction before calling into your program, that could mess up your entire parsing scheme. It's better to fully deserialize the instructions from the message.

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.