Anchor uses the sha256 of "namespace":"function_name" as a function identifier. When you are creating your instruction:
let instruction = Instruction {
program_id, // whatever the program key is
accounts: vec![
AccountMeta::new(ctx.accounts.whatever.key(), false),
],
data: get_function_hash("global", "do_something").to_vec(),
};
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
}
If the instruction also has args, you would need to serialize them and append them to the buffer for the function hash, e.g.
#[derive(AnchorSerialize, AnchorDeserialize)]
struct CpiArgs {
bump: u8,
}
fn get_ix_data(bump: u8, amount: Amount) -> Vec<u8> {
let hash = get_function_hash("global", "do_something");
let mut buf: Vec<u8> = vec![];
buf.extend_from_slice(&hash);
let args = CpiArgs { bump };
args.serialize(&mut buf).unwrap();
buf
}