Ownership, Moves & Copies
Every value has exactly one owner — a local variable, a struct field, or a storage location.
17.1 Move semantics
Every value has exactly one owner — a local variable, a struct field, or a storage location. Assigning or passing a value moves it unless the type has copy:
public struct Ticket has store { seat: u64 } // no copy, no drop
fun demo(t: Ticket): Ticket {
let a = t; // move
// let b = t; // ERROR: t was moved
a // move out to caller
}17.2 Explicit copy and move
The compiler infers copy or move for local variable uses; explicit annotations are rarely needed.
let x = 5;
let y = copy x; // explicit copy (x still usable)
let z = move x; // explicit move (x no longer usable)
let w = y; // implicit: copied or moved, inferred by the compiler17.3 Consuming resources
A value without drop must be consumed. Ways to consume:
Pass it by value to a function.
Store it in a struct / storage (move_to, transfer::*, dynamic field).
Destructure it inside its module (let Ticket { seat: _ } = t;).
public fun burn(t: Ticket) {
let Ticket { seat: _ } = t; // only possible inside the defining module
}17.4 Ownership vs storage ownership
Language-level ownership: which variable holds the value right now.
On-chain ownership: Sui objects have an owner (address, object, shared, immutable); Aptos resources live under an address. A resource leaving a function must end up in one of these places — Move guarantees no asset is lost or duplicated in between.