Aptos Global Storage
In Aptos (and Diem/Movement), global storage is a map from (address, resource type) to a value:
26.1 The model
In Aptos (and Diem/Movement), global storage is a map from (address, resource type) to a value:
Each address can hold at most one resource of each type. A resource type must have key. Only the module that defines the type can perform storage operations on it.
GlobalStorage = Map<(address, StructType), value>26.2 Storage operators
Effect / aborts move_to<T>(&signer, T) Publish T under the signer's address Aborts if T already exists there move_from<T>(addr): T Remove and return T Aborts if missing borrow_global<T>(addr): &T borrow_global_mut<T>(addr): &mut T exists<T>(addr): bool
Move 2 index: &T[addr], &mut T[addr], T[addr].field Sugar for borrow_global(_mut)
Note that move_to requires a &signer — you can only publish into an account that authorized the transaction (or for which you hold a signer from an object/resource-account capability). Reads (borrow_global, exists) work on any address.
26.3 A complete example: a simple bank of notes
module my_addr::notes {
use std::signer;
use std::string::String;
use std::vector;
use std::error;
const E_NOT_INITIALIZED: u64 = 1;
const E_ALREADY_INITIALIZED: u64 = 2;
const E_INDEX: u64 = 3;
struct NoteBook has key {
notes: vector<String>,
}
public entry fun init_notebook(account: &signer) {
let addr = signer::address_of(account);
assert!(!exists<NoteBook>(addr), error::already_exists(E_ALREADY_INITIALIZED));
move_to(account, NoteBook { notes: vector::empty() });
}
public entry fun add_note(account: &signer, note: String) acquires NoteBook {
let addr = signer::address_of(account);
assert!(exists<NoteBook>(addr), error::not_found(E_NOT_INITIALIZED));
let book = &mut NoteBook[addr]; // Move 2 resource indexing
book.notes.push_back(note);
}
public entry fun remove_note(account: &signer, index: u64) acquires NoteBook {
let addr = signer::address_of(account);
let book = borrow_global_mut<NoteBook>(addr); // classic form
assert!(index < book.notes.length(), error::out_of_range(E_INDEX));
book.notes.remove(index);
…26.4 Generic resources
struct Vault<phantom CoinType> has key {
coins: aptos_framework::coin::Coin<CoinType>,
}
// An address can hold Vault<USDC> and Vault<AptosCoin> simultaneously:
// they are distinct types.26.5 Resource groups
Aptos stores resource groups together in a single storage slot to reduce IO costs. The Object framework uses ObjectGroup:
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
struct Profile has key { name: String }26.6 Parallel execution note
Aptos executes transactions optimistically in parallel (Block-STM). Transactions touching the same resource conflict and re-execute. Avoid single global "hot" resources (e.g., one counter everyone writes); prefer per-user resources or aggregators (aptos_framework::aggregator_v2) for concurrent counters such as total supply.