1

I have a Tic Tac Toe game contract which looks like this:

#[program]
pub mod tic_tac_toe {
    use super::*;

    pub fn start_game(ctx: Context<StartGame>) -> Result<()> {
        start::start_game(ctx)
    }

    // two other instructions here
}

If I run cargo expand I se that instruction numbers are expanded to this:

match sighash {
    [249, 47, 252, 172, 184, 162, 245, 14] => {
        __private::__global::start_game(program_id, accounts, ix_data)
    }
    // two other instructions here
    _ => Err(anchor_lang::error::ErrorCode::InstructionFallbackNotFound.into()),
}

Questions:

  1. I have only three instructions. Why does Anchor generates 8 bytes per instruction? Why not one byte which would be enough to encode my three instruction numbers?
  2. How can I derive this byte array without having to run cargo expand? I want to use this instruction id in Java and I cannot use the Anchors JavaScript APIs.
  3. Can I give instructions predefined numbers? Let's say I want my instructions to be 1, 2 and 3.

1 Answer 1

3

Anchor uses the first 8 bytes of the sha256 of "namespace":"function_name" as the instruction identifiers. One byte would increase the risk of collision. At eight bytes, it's still possible for two different function names to generate the same 8 byte identifier, but very very unlikely.

You could rename your functions until the sha256 result is in the order you want, but you probably don't want to do that.

Here's a Rust function to compute the sighash:

pub fn get_function_hash(namespace: &str, name: &str) -> [u8; 8] {
    let preimage = format!("{}:{}", namespace, name);
    let mut sighash = [0u8; 8];
    sighash.copy_from_slice(
        &anchor_lang::solana_program::hash::hash(preimage.as_bytes()).to_bytes()
            [..8],
    );
    sighash
}

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.