Near Learn

Initialization (constructors)

When default state is not enough, mark a method #[init]. It runs once, takes arguments, and returns the starting state — the constructor.

Beginner4 min read3-question check

The contracts so far used #[derive(Default)] and initialized themselves lazily. When the starting state depends on arguments — an owner, a cap, a token address — you need a real constructor. On NEAR that is a method marked #[init] that returns Self.

A vault with an owner and a cap
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Vault {
    address public owner;
    uint256 public cap;

    constructor(address _owner, uint256 _cap) {
        owner = _owner;
        cap = _cap;
    }
}
Rust
use near_sdk::{near, AccountId, PanicOnDefault};
use near_sdk::json_types::U128;

#[near(contract_state)]
#[derive(PanicOnDefault)]
pub struct Vault {
    owner: AccountId,
    cap: u128,
}

#[near]
impl Vault {
    #[init]
    pub fn new(owner: AccountId, cap: U128) -> Self {
        Self { owner, cap: cap.0 }
    }

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

constructor(...) ↔ a method marked #[init] that returns Self. near-sdk 5.x requires the state struct to either implement Default or #[derive(PanicOnDefault)]. A contract *can* have both Default and an #[init] (methods then fall back to the default state until init runs); deriving PanicOnDefault instead is how you say "there is no sensible default — init is mandatory".

With PanicOnDefault, the #[init] method must be called once after deploy, before anything else. Until it runs the contract has no state and every other method panics ("The contract is not initialized") — deploy and init are two separate steps (or one, if you deploy with an init call).

U128 / U64 (near_sdk::json_types) are string-wrapped integers for method arguments and returns. JSON numbers lose precision above 2^53, so money-sized values cross the ABI as U128 and you read the inner value with .0.

Check yourself

3 questions · progress saved in this browser

  1. 1.What is the NEAR equivalent of a Solidity constructor(address _owner, uint256 _cap)?
  2. 2.You deploy the Vault but forget to call new. According to the chapter, what happens when someone calls owner?
  3. 3.Why does new take cap: U128 and then store cap.0?