Near Learn

Ownership

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

Beginner4 min read3-question check

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, PanicOnDefault};

#[near(contract_state)]
#[derive(PanicOnDefault)]
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.

Check yourself

3 questions · progress saved in this browser

  1. 1.How do you get Ownable behavior on NEAR?
  2. 2.A DAO contract, dao.near, owns your contract and calls transfer_ownership. What does env::predecessor_account_id() return inside your method?
  3. 3.Why add a two-step ownership transfer (propose, then accept)?