Functions & calls
Access control (modifiers)
Rust has no modifier keyword. You write a small guard method and call it at the top of each protected method — same effect, plain code.
Solidity’s modifier onlyOwner wraps a function with a reusable check. Rust has no modifiers, and that is fine: you write a private guard method and call it as the first line of each protected method.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Config {
address public owner;
uint32 public value;
constructor() { owner = msg.sender; }
modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}
function setValue(uint32 v) external onlyOwner {
value = v;
}
}use near_sdk::{near, env, require, AccountId};
#[near(contract_state)]
pub struct Config {
owner: AccountId,
value: u32,
}
#[near]
impl Config {
#[init]
pub fn new() -> Self {
Self { owner: env::predecessor_account_id(), value: 0 }
}
pub fn set_value(&mut self, v: u32) {
self.assert_owner();
self.value = v;
}
}
// a plain private helper — not exposed as a contract method
impl Config {
fn assert_owner(&self) {
require!(env::predecessor_account_id() == self.owner, "not owner");
}
}modifier onlyOwner { ...; _; } + onlyOwner ↔ a private assert_owner(&self) called at the top of the method. No macro magic needed — it is just a function call.
Put helpers in a separate `impl` block without `#[near]` (or a non-pub fn) so they stay internal and are never exposed as callable contract methods.
For role-based access across many methods, keep a LookupMap<AccountId, Role> and a guard like assert_role(Role::Admin) — the same pattern, scaled up.