# Message verification (https://docs.axelar.dev/gmp/how-it-works/message-verification)



Before a message is executed, the destination contract asks the gateway to validate it. Validation proves two things:

* **Axelar approved this message.** A message with this source chain, source address, destination and payload was verified on the source chain and approved on this gateway, signed by Axelar's validators or verifiers. See [Flow of Messages](https://docs.axelar.dev/llms.mdx/gmp/how-it-works/message-flow/content.md).
* **It runs once.** The gateway marks the message executed, so the same message can't be executed again.

It doesn't prove who sent it. Anyone can send a message to any contract from any connected chain, so a message that passes validation can still come from someone you don't trust. Unless your contract accepts messages from anyone, check the source chain and source address after validation.

## On each chain [#on-each-chain]

| Chain      | Validation                                                                      | Checking the sender                                                                                              |
| ---------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| EVM chains | `AxelarExecutable.execute` calls `validateContractCall` on the gateway          | [Check the sender](https://docs.axelar.dev/llms.mdx/gmp/integrations/evm/gmp-messages/content.md#check-the-sender)                                          |
| Solana     | `validate_message`, a CPI to the gateway                                        | [Check the sender](https://docs.axelar.dev/llms.mdx/gmp/integrations/solana/gmp-messages/content.md#check-the-sender)                                       |
| Sui        | `consume_approved_message` with your channel                                    | [Check the sender](https://docs.axelar.dev/llms.mdx/gmp/integrations/sui/gmp-messages/content.md#check-the-sender)                                          |
| Stellar    | The `execute` generated by `#[derive(AxelarExecutable)]`                        | [Check the sender](https://docs.axelar.dev/llms.mdx/gmp/integrations/stellar/gmp-messages/content.md#check-the-sender)                                      |
| Cosmos     | ibc-hooks calls your contract from an address derived from Axelar's GMP account | [Check where the message came from](https://docs.axelar.dev/llms.mdx/gmp/integrations/cosmos/send-and-receive/content.md#check-where-the-message-came-from) |

If your code fails after validation, the whole transaction reverts, including the validation. The message stays approved and can be executed again.

## Command ID [#command-id]

The destination gateway identifies each message by a command ID, a `bytes32` that your contract receives with the message on EVM chains.

* **Amplifier chains:** the command ID is derived from the message's source chain and message ID: `keccak256(sourceChain + "_" + messageId)`. The gateway's `messageToCommandId` computes it.
* **Consensus chains:** Axelar assigns the command ID when it approves the message, and it's in the gateway's `ContractCallApproved` event.

The message ID identifies a message across chains, e.g. `<transaction hash>-<log index>` for a message from an EVM chain, and is shown on Axelarscan. For the gateway functions that use them, see the [EVM contract reference](https://docs.axelar.dev/llms.mdx/gmp/integrations/evm/gmp-contracts/content.md#receive).


---

All pages of these docs, as Markdown: https://docs.axelar.dev/llms.txt