Functions & calls

Errors: assert, require & panic

Guard clauses roll the whole call back and refund unused gas. require! and env::panic_str are your revert.

A failing check should undo everything and hand the caller their gas back. Solidity spells that require / revert; NEAR spells it with a panic — require!, assert!, or env::panic_str.

Owner-guarded setter
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Guarded {
    address public owner;
    uint32 public value;

    constructor() {
        owner = msg.sender;
    }

    function setValue(uint32 v) external {
        require(msg.sender == owner, "not owner");
        require(v != 0, "zero not allowed");
        value = v;
    }
}
Rust
use near_sdk::{near, env, require, AccountId};

#[near(contract_state)]
pub struct Guarded {
    owner: AccountId,
    value: u32,
}

#[near]
impl Guarded {
    #[init]
    pub fn new() -> Self {
        Self {
            owner: env::predecessor_account_id(),
            value: 0,
        }
    }

    pub fn set_value(&mut self, v: u32) {
        require!(env::predecessor_account_id() == self.owner, "not owner");
        require!(v != 0, "zero not allowed");
        self.value = v;
    }
}
Coming from EVM

require(cond, "msg") ↔ require!(cond, "msg") (or assert!). On failure the call panics: every state change rolls back and the caller's unused gas is refunded — the same all-or-nothing semantics as a Solidity revert.

For an unconditional failure, env::panic_str("..."). You *can* return a typed error with Result + #[handle_result], but a panic is the idiomatic revert and needs no extra wiring.

There is no on-the-wire custom error type like revert MyError(). The failure surfaces as the panic message string in the transaction outcome, which is what wallets and explorers display.