Collections: mappings & arrays
mapping and dynamic arrays become explicit types from near_sdk::store — LookupMap, Vector — each with its own storage prefix.
Beginner5 min read3-question check
Solidity gives you mapping and T[] as language built-ins. NEAR gives you collection types from near_sdk::store that you pick deliberately: LookupMap, Vector, IterableMap, UnorderedSet. Each is a thin wrapper over on-chain key/value storage.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Points {
mapping(address => uint32) public points;
address[] public members;
function join() external {
if (points[msg.sender] == 0) {
members.push(msg.sender);
}
}
function award(address who, uint32 amount) external {
points[who] += amount;
}
function memberCount() external view returns (uint256) {
return members.length;
}
}use near_sdk::{near, env, AccountId};
use near_sdk::store::{LookupMap, Vector};
#[near(contract_state)]
pub struct Points {
points: LookupMap<AccountId, u32>,
members: Vector<AccountId>,
}
impl Default for Points {
fn default() -> Self {
Self {
// each collection needs its own unique storage prefix
points: LookupMap::new(b"p"),
members: Vector::new(b"m"),
}
}
}
#[near]
impl Points {
pub fn join(&mut self) {
let who = env::predecessor_account_id();
if !self.points.contains_key(&who) {
self.members.push(who.clone());
self.points.insert(who, 0);
}
}
pub fn award(&mut self, who: AccountId, amount: u32) {
let cur = self.points.get(&who).copied().unwrap_or(0);
self.points.insert(who, cur + amount);
}
pub fn points_of(&self, who: AccountId) -> u32 {
self.points.get(&who).copied().unwrap_or(0)
}
pub fn member_count(&self) -> u32 {
self.members.len()
}
}mapping(k => v) ↔ LookupMap<K, V>; a dynamic array ↔ Vector<T>. There is no default value magic — reads return Option, so you unwrap_or(..) the "unset" case yourself.
Each collection takes a unique storage prefix (b"p", b"m") — the byte key its entries are stored under. Two collections sharing a prefix silently corrupt each other, so keep them distinct.
LookupMap is get/set by key but not iterable — the cheapest option. Need to iterate entries or list keys? Use IterableMap (or UnorderedMap). Paying only for what you enumerate is the tradeoff NEAR makes for predictable storage gas.
Check yourself
3 questions · progress saved in this browser