Assert / Assert_eq
Leo provides assert and assert_eq for runtime checks. If an assertion fails, the entire transaction is rejected - no state changes take effect.
leo
assert(amount > 0u64); // Fails if amount is zero
assert_eq(std::ctx::signer(), owner); // Fails if the signer isn't the owner
assert_neq(sender, receiver); // Fails if sender equals receiver
These are your primary tools for access control, input validation, and invariant enforcement.
Where the assertion sits changes what it costs. An assertion in the off-chain proof half simply fails to produce a valid proof, so nothing is broadcast and nothing is charged. An assertion inside a final { } block runs on-chain after the proof has verified, so a failure rejects the whole transaction and the fee is still consumed. Check what you can before finalization.