Functions & calls
Initialization (constructors)
When default state is not enough, mark a method #[init]. It runs once, takes arguments, and returns the starting state — the constructor.
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.
// 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;
}
}use near_sdk::{near, AccountId};
use near_sdk::json_types::U128;
#[near(contract_state)]
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()
}
}constructor(...) ↔ a method marked #[init] that returns Self. Note there is no #[derive(Default)] here — a contract has exactly one of the two.
An #[init] method must be called once after deploy, before anything else. Until it runs the contract has no state and every other method panics with "not initialized" — deploy and init are two separate steps.
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.