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.
// 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;
}
}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;
}
}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.