Patterns

Ownership

No OpenZeppelin Ownable base to inherit — you keep an owner field and a guard, plus a two-word transfer method.

The Ownable pattern is everywhere in Solidity, usually inherited from OpenZeppelin. On NEAR there is no base contract to inherit; you keep an owner field, guard the privileged methods, and expose a transfer method.

Owned contract
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

abstract contract Ownable {
    address public owner;

    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }

    function transferOwnership(address newOwner) external onlyOwner {
        owner = newOwner;
    }
}
Rust
use near_sdk::{near, env, require, AccountId};

#[near(contract_state)]
pub struct Owned {
    owner: AccountId,
}

#[near]
impl Owned {
    #[init]
    pub fn new(owner: AccountId) -> Self {
        Self { owner }
    }

    pub fn owner(&self) -> AccountId {
        self.owner.clone()
    }

    pub fn transfer_ownership(&mut self, new_owner: AccountId) {
        require!(env::predecessor_account_id() == self.owner, "not owner");
        self.owner = new_owner;
    }
}
Coming from EVM

No inheritable Ownable. You hold the owner AccountId and guard with require!(predecessor == owner) — the access-control pattern from earlier, applied to ownership.

Remember cross-contract semantics: predecessor_account_id() is whoever called *this* method. If a DAO or multisig owns the contract, the owner is *that contract’s* account, and it calls you like any other caller.

For a safer handoff, add a two-step transfer (propose then accept) so a typo in new_owner can’t brick control — the same reason OpenZeppelin ships Ownable2Step.