A curated collection of Move language examples for the Aptos blockchain. Each snippet demonstrates a specific concept, design pattern, or feature of Move on Aptos, written using Move 2 syntax.
Originally created by @gregnazario as a series of educational tweets on learning Move piece by piece.
Coding agents: start at AGENTS.md (commands, named addresses, non-interactive CLI). Doc index: llms.txt.
This repository contains standalone Move snippets that each focus on a specific topic. The examples progress from basic language features (error codes, structs, objects) through intermediate patterns (NFT minting, storage data structures) to advanced use cases (composable NFTs, liquid tokens, formal verification).
All examples use Move 2 syntax, including:
vector.length() instead of vector::length(&vector))Resource[address] instead of borrow_global<Resource>(address))matchfor loopsRun these from the repository root. Replace <example-dir> with a path from the example index. Most packages use the named address deploy_addr; exceptions are listed under Named Addresses.
aptos move compile --dev --package-dir snippets/<example-dir>
snippets/fractional-token cannot use --dev. Compile it with:
aptos move compile --named-addresses fraction_addr=0x1337,minter=0x2337 --package-dir snippets/fractional-token
aptos move test --dev --package-dir snippets/<example-dir>
Not every package has tests. See the Tests column in the example index or the catalog in AGENTS.md.
Publishing needs a CLI profile and prompts for confirmation unless you pass --assume-yes.
aptos init --network devnet --assume-yes
aptos move publish --assume-yes --named-addresses deploy_addr=default --package-dir snippets/<example-dir>
Using an explicit address instead of a profile name:
MY_ADDR=0x12345
aptos move publish --assume-yes --named-addresses deploy_addr=$MY_ADDR --package-dir snippets/<example-dir>
snippets/snipe-prevention must be deployed as a code object:
aptos move deploy-object --assume-yes --named-addresses antisnipe=default --package-dir snippets/snipe-prevention
After deploying, interact with your contract via the Aptos Explorer.
| Resource | Use it for |
|---|---|
| AGENTS.md | Non-interactive CLI flags, per-package compile/test commands, Move 2 conventions, CI coverage, gotchas |
| llms.txt | Short index of every example README |
snippets/<example>/README.md | Module name, source file, entry/view functions, exact commands |
Practical rules:
aptos init without --network and --assume-yes (it will prompt or hang).deploy_addr. Check Move.toml or the catalog before compiling.--package-dir snippets/... from the repo root so commands match the READMEs.Every example has a README.md in its package directory. Each follows the same structure so you (or an agent) can scan any example quickly:
| Section | Description |
|---|---|
| Overview | What the example demonstrates and when to use it |
| Difficulty | Beginner, Intermediate, or Advanced |
| Concepts Demonstrated | Move language and Aptos framework topics covered |
| Key Structs / Key Functions | Tables summarizing the main types and entry points |
| Deploy & Run | Package path, fully qualified module, source file, named address, then Compile, Deploy, Tests, and Prover when they apply |
| Related Examples | Cross-links to similar or prerequisite examples |
See Named Addresses below for the address placeholder each package expects at compile/deploy time.
For a summary of Move 2 features used across examples, see snippets/move-2/README.md.
| Example | Directory | README | Description |
|---|---|---|---|
| Error Codes | snippets/error-codes/ | README | How to define and use error codes with doc comments for readable error messages |
| Objects (Sticky Notes) | snippets/objects/ | README | Introduction to the Aptos Object model, comparing resources vs objects |
| Private vs Public Functions | snippets/private-vs-public/ | README | Function visibility and why it matters for security (with a cheater example) |
| Example | Directory | README | Description |
|---|---|---|---|
| Controlled Mint | snippets/controlled-mint/ | README | Creator-controlled NFT minting with royalty support |
| Data Structures (Min Heap) | snippets/data-structures/heap/ | README | Min heap implementation with formal verification specs |
| Design Patterns: Autonomous Objects | snippets/design-patterns/autonomous-objects/ | README | Creating objects that can act autonomously via extend refs |
| Modifying NFTs | snippets/modifying-nfts/ | README | How to modify NFT properties, URIs, and extend collections with custom data |
| Parallel NFT Minting | snippets/parallel-nfts/ | README | Parallelized NFT minting using object-owned collections |
| Snipe Prevention | snippets/snipe-prevention/ | README | Anti-snipe protection for token launches using dispatchable fungible assets |
| Storage Patterns | snippets/storage/ | README | Comparison of Vector, SimpleMap, Table, SmartTable, and SmartVector with gas benchmarks |
| Struct Capabilities (Mailbox) | snippets/struct-capabilities/ | README | Using structs for capability-based access control in a mailbox system |
| Example | Directory | README | Description |
|---|---|---|---|
| Composable NFTs | snippets/composable-nfts/ | README | Dynamic composable NFTs where a Face can equip/unequip a Hat, changing the token image |
| FA Lockup / Escrow | snippets/fa-lockup-example/ | README | Time-locked fungible asset escrow with dispatchable transfers |
| Fractional Token | snippets/fractional-token/ | README | Fractionalizing a digital asset into fungible tokens and recombining them |
| Liquid NFTs | snippets/liquid-nfts/ | README | NFT liquidity pools using Coin, Legacy Token, and Fungible Asset standards |
| Lootbox / Mystery Box | snippets/lootbox/ | README | On-chain mystery boxes using Aptos randomness, supporting coins, FAs, and NFTs |
| Prover (Payment Escrow) | snippets/prover/ | README | Formal verification with the Move Prover on a payment escrow contract |
| # | Example | Difficulty | Key Concepts | Move 2 Features Used | Tests |
|---|---|---|---|---|---|
| 1 | error-codes | Beginner | Error codes, doc comments, abort, assert! | Receiver style | Yes |
| 2 | objects | Beginner | Object model, resources vs objects, ExtendRef, DeleteRef, TransferRef | Receiver style, index notation | — |
| 3 | private-vs-public | Beginner | Function visibility (public, public entry, entry, private), security | Receiver style, index notation | — |
| 4 | controlled-mint | Intermediate | Token V2 minting, collections, royalties, named objects | Receiver style, index notation, for loops | Yes |
| 5 | data-structures/heap | Intermediate | Min heap, heap sort, formal verification specs | Receiver style, for loops | Yes + Prover |
| 6 | design-patterns/autonomous-objects | Intermediate | Autonomous object pattern, ownership permission pattern | Receiver style, index notation | — |
| 7 | modifying-nfts | Intermediate | Mutable NFTs, MutatorRef, BurnRef, extending objects | Receiver style, index notation | — |
| 8 | parallel-nfts | Intermediate | Parallelized minting, object-owned collections, numbered tokens | Receiver style, index notation | — |
| 9 | snipe-prevention | Intermediate | Dispatchable FA hooks, anti-snipe, allowlists, enum types | Receiver style, index notation, enums, match | Yes |
| 10 | storage | Intermediate | Vector, SimpleMap, Table, SmartTable, SmartVector, gas comparison | Receiver style, index notation, for loops | — |
| 11 | struct-capabilities | Intermediate | Capability pattern, SmartTable, SmartVector, envelopes | Receiver style, index notation | — |
| 12 | composable-nfts | Advanced | Composable tokens, dynamic URIs, transfer locking | Receiver style, index notation | Yes |
| 13 | fa-lockup-example | Advanced | Fungible asset escrow, time locks, enum types, match | Receiver style, index notation, enums, match, for loops | Yes |
| 14 | fractional-token | Advanced | Fractionalization, fungible assets, primary stores | Receiver style, index notation | Yes |
| 15 | liquid-nfts | Advanced | Liquidity pools, Coin vs FA, legacy tokens, pseudorandom | Receiver style, index notation, for loops | Yes |
| 16 | lootbox | Advanced | Randomness API, multi-asset boxes, soulbound tickets | Receiver style, index notation, for loops | — |
| 17 | prover | Advanced | Move Prover, formal specs, invariants, schemas | Receiver style, index notation | Prover |
public, public entry, entry, private, public(friend), inlinehas key, has store, has copy, has drop abilitiesphantom type parameters for type-safe wrappersmatch expressions for enums and destructuringConstructorRef, ExtendRef, DeleteRef, TransferRef, object creation, named/sticky objectsMutatorRef, BurnRef, numbered tokensMetadata, FungibleStore, primary stores, mint/burn/transfercoin::initialize, mint/burn capabilities, CoinStorerandomness::u64_range for on-chain random number generationtimestamp::now_seconds(), timestamp::now_microseconds()ExtendRef for programmatic actionsobject::is_owner or object::owns before granting accessobject::create_named_objectspec blocks, ensures, requires, aborts_if, aborts_withsnippets/
├── composable-nfts/ # Dynamic composable Face + Hat NFTs
│ ├── Move.toml
│ └── sources/
│ └── composable_nfts.move
├── controlled-mint/ # Creator-controlled batch NFT minting
│ ├── Move.toml
│ └── sources/
│ └── controlled_mint.move
├── data-structures/
│ └── heap/ # Min heap with formal verification
│ ├── Move.toml
│ ├── sources/
│ │ └── min_heap_u64.move
│ └── tests/
│ └── min_heap_u64_tests.move
├── design-patterns/
│ └── autonomous-objects/ # Autonomous object design pattern
│ ├── Move.toml
│ └── sources/
│ └── base.move
├── error-codes/ # Error code best practices
│ ├── Move.toml
│ └── sources/
│ └── error_codes.move
├── fa-lockup-example/ # Fungible asset time-locked escrow
│ ├── Move.toml
│ └── sources/
│ └── lockup.move
├── fractional-token/ # NFT fractionalization into fungible tokens
│ ├── Move.toml
│ ├── sources/
│ │ └── fractional_token.move
│ └── tests/
│ ├── common_tests.move
│ └── fractional_token_tests.move
├── liquid-nfts/ # NFT liquidity pools (3 implementations)
│ ├── Move.toml
│ └── sources/
│ ├── common.move
│ ├── liquid_coin.move
│ ├── liquid_coin_legacy.move
│ └── liquid_fungible_asset.move
├── lootbox/ # On-chain mystery boxes with randomness
│ ├── Move.toml
│ └── sources/
│ └── mystery_box.move
├── modifying-nfts/ # Mutable NFT properties and extension
│ ├── Move.toml
│ └── sources/
│ └── modify_nfts.move
├── move-2/ # Move 2 feature reference (redirects to examples)
│ └── README.md
├── parallel-nfts/ # Parallelized public NFT minting
│ ├── Move.toml
│ └── sources/
│ └── parallel_mint.move
├── private-vs-public/ # Function visibility & security
│ ├── cheater/
│ │ ├── Move.toml
│ │ └── sources/
│ │ └── cheater.move
│ └── dice_roll/
│ ├── Move.toml
│ └── sources/
│ └── dice_roll.move
├── prover/ # Formal verification with Move Prover
│ ├── Move.toml
│ └── sources/
│ └── payment_escrow.move
├── snipe-prevention/ # Anti-snipe protection for token launches
│ ├── Move.toml
│ └── sources/
│ └── antisnipe_token.move
├── storage/ # Data structure comparison with gas benchmarks
│ ├── Move.toml
│ └── sources/
│ ├── allowlist_simple_map.move
│ ├── allowlist_smart_table.move
│ ├── allowlist_smart_vector.move
│ ├── allowlist_table.move
│ ├── allowlist_vector.move
│ └── object_management.move
└── struct-capabilities/ # Capability-based mailbox system
├── Move.toml
└── sources/
└── mailbox.move
Different examples use different named addresses in their Move.toml. When compiling without --dev, or when deploying, substitute the appropriate address. Agents: copy the compile line from the package README or from AGENTS.md rather than assuming deploy_addr.
| Named Address | Used By |
|---|---|
deploy_addr | Most examples (error-codes, composable-nfts, controlled-mint, modifying-nfts, parallel-nfts, storage, struct-capabilities, private-vs-public, data-structures/heap) |
deploy_address | design-patterns/autonomous-objects |
fraction_addr | fractional-token, liquid-nfts |
minter | fractional-token (required together with fraction_addr; do not compile this package with --dev) |
mystery_addr | lootbox |
lockup_deployer | fa-lockup-example |
deployer | prover |
antisnipe | snipe-prevention |
| (none) | objects — the module is 0x42::sticky_note (numeric address, not a named address) |
See LICENSE for details.
Move
100.0%
A curated collection of Move language examples for the Aptos blockchain. Each snippet demonstrates a specific concept, design pattern, or feature of Move on Aptos, written using Move 2 syntax.
Originally created by @gregnazario as a series of educational tweets on learning Move piece by piece.
Coding agents: start at AGENTS.md (commands, named addresses, non-interactive CLI). Doc index: llms.txt.
This repository contains standalone Move snippets that each focus on a specific topic. The examples progress from basic language features (error codes, structs, objects) through intermediate patterns (NFT minting, storage data structures) to advanced use cases (composable NFTs, liquid tokens, formal verification).
All examples use Move 2 syntax, including:
vector.length() instead of vector::length(&vector))Resource[address] instead of borrow_global<Resource>(address))matchfor loopsRun these from the repository root. Replace <example-dir> with a path from the example index. Most packages use the named address deploy_addr; exceptions are listed under Named Addresses.
aptos move compile --dev --package-dir snippets/<example-dir>
snippets/fractional-token cannot use --dev. Compile it with:
aptos move compile --named-addresses fraction_addr=0x1337,minter=0x2337 --package-dir snippets/fractional-token
aptos move test --dev --package-dir snippets/<example-dir>
Not every package has tests. See the Tests column in the example index or the catalog in AGENTS.md.
Publishing needs a CLI profile and prompts for confirmation unless you pass --assume-yes.
aptos init --network devnet --assume-yes
aptos move publish --assume-yes --named-addresses deploy_addr=default --package-dir snippets/<example-dir>
Using an explicit address instead of a profile name:
MY_ADDR=0x12345
aptos move publish --assume-yes --named-addresses deploy_addr=$MY_ADDR --package-dir snippets/<example-dir>
snippets/snipe-prevention must be deployed as a code object:
aptos move deploy-object --assume-yes --named-addresses antisnipe=default --package-dir snippets/snipe-prevention
After deploying, interact with your contract via the Aptos Explorer.
| Resource | Use it for |
|---|---|
| AGENTS.md | Non-interactive CLI flags, per-package compile/test commands, Move 2 conventions, CI coverage, gotchas |
| llms.txt | Short index of every example README |
snippets/<example>/README.md | Module name, source file, entry/view functions, exact commands |
Practical rules:
aptos init without --network and --assume-yes (it will prompt or hang).deploy_addr. Check Move.toml or the catalog before compiling.--package-dir snippets/... from the repo root so commands match the READMEs.Every example has a README.md in its package directory. Each follows the same structure so you (or an agent) can scan any example quickly:
| Section | Description |
|---|---|
| Overview | What the example demonstrates and when to use it |
| Difficulty | Beginner, Intermediate, or Advanced |
| Concepts Demonstrated | Move language and Aptos framework topics covered |
| Key Structs / Key Functions | Tables summarizing the main types and entry points |
| Deploy & Run | Package path, fully qualified module, source file, named address, then Compile, Deploy, Tests, and Prover when they apply |
| Related Examples | Cross-links to similar or prerequisite examples |
See Named Addresses below for the address placeholder each package expects at compile/deploy time.
For a summary of Move 2 features used across examples, see snippets/move-2/README.md.
| Example | Directory | README | Description |
|---|---|---|---|
| Error Codes | snippets/error-codes/ | README | How to define and use error codes with doc comments for readable error messages |
| Objects (Sticky Notes) | snippets/objects/ | README | Introduction to the Aptos Object model, comparing resources vs objects |
| Private vs Public Functions | snippets/private-vs-public/ | README | Function visibility and why it matters for security (with a cheater example) |
| Example | Directory | README | Description |
|---|---|---|---|
| Controlled Mint | snippets/controlled-mint/ | README | Creator-controlled NFT minting with royalty support |
| Data Structures (Min Heap) | snippets/data-structures/heap/ | README | Min heap implementation with formal verification specs |
| Design Patterns: Autonomous Objects | snippets/design-patterns/autonomous-objects/ | README | Creating objects that can act autonomously via extend refs |
| Modifying NFTs | snippets/modifying-nfts/ | README | How to modify NFT properties, URIs, and extend collections with custom data |
| Parallel NFT Minting | snippets/parallel-nfts/ | README | Parallelized NFT minting using object-owned collections |
| Snipe Prevention | snippets/snipe-prevention/ | README | Anti-snipe protection for token launches using dispatchable fungible assets |
| Storage Patterns | snippets/storage/ | README | Comparison of Vector, SimpleMap, Table, SmartTable, and SmartVector with gas benchmarks |
| Struct Capabilities (Mailbox) | snippets/struct-capabilities/ | README | Using structs for capability-based access control in a mailbox system |
| Example | Directory | README | Description |
|---|---|---|---|
| Composable NFTs | snippets/composable-nfts/ | README | Dynamic composable NFTs where a Face can equip/unequip a Hat, changing the token image |
| FA Lockup / Escrow | snippets/fa-lockup-example/ | README | Time-locked fungible asset escrow with dispatchable transfers |
| Fractional Token | snippets/fractional-token/ | README | Fractionalizing a digital asset into fungible tokens and recombining them |
| Liquid NFTs | snippets/liquid-nfts/ | README | NFT liquidity pools using Coin, Legacy Token, and Fungible Asset standards |
| Lootbox / Mystery Box | snippets/lootbox/ | README | On-chain mystery boxes using Aptos randomness, supporting coins, FAs, and NFTs |
| Prover (Payment Escrow) | snippets/prover/ | README | Formal verification with the Move Prover on a payment escrow contract |
| # | Example | Difficulty | Key Concepts | Move 2 Features Used | Tests |
|---|---|---|---|---|---|
| 1 | error-codes | Beginner | Error codes, doc comments, abort, assert! | Receiver style | Yes |
| 2 | objects | Beginner | Object model, resources vs objects, ExtendRef, DeleteRef, TransferRef | Receiver style, index notation | — |
| 3 | private-vs-public | Beginner | Function visibility (public, public entry, entry, private), security | Receiver style, index notation | — |
| 4 | controlled-mint | Intermediate | Token V2 minting, collections, royalties, named objects | Receiver style, index notation, for loops | Yes |
| 5 | data-structures/heap | Intermediate | Min heap, heap sort, formal verification specs | Receiver style, for loops | Yes + Prover |
| 6 | design-patterns/autonomous-objects | Intermediate | Autonomous object pattern, ownership permission pattern | Receiver style, index notation | — |
| 7 | modifying-nfts | Intermediate | Mutable NFTs, MutatorRef, BurnRef, extending objects | Receiver style, index notation | — |
| 8 | parallel-nfts | Intermediate | Parallelized minting, object-owned collections, numbered tokens | Receiver style, index notation | — |
| 9 | snipe-prevention | Intermediate | Dispatchable FA hooks, anti-snipe, allowlists, enum types | Receiver style, index notation, enums, match | Yes |
| 10 | storage | Intermediate | Vector, SimpleMap, Table, SmartTable, SmartVector, gas comparison | Receiver style, index notation, for loops | — |
| 11 | struct-capabilities | Intermediate | Capability pattern, SmartTable, SmartVector, envelopes | Receiver style, index notation | — |
| 12 | composable-nfts | Advanced | Composable tokens, dynamic URIs, transfer locking | Receiver style, index notation | Yes |
| 13 | fa-lockup-example | Advanced | Fungible asset escrow, time locks, enum types, match | Receiver style, index notation, enums, match, for loops | Yes |
| 14 | fractional-token | Advanced | Fractionalization, fungible assets, primary stores | Receiver style, index notation | Yes |
| 15 | liquid-nfts | Advanced | Liquidity pools, Coin vs FA, legacy tokens, pseudorandom | Receiver style, index notation, for loops | Yes |
| 16 | lootbox | Advanced | Randomness API, multi-asset boxes, soulbound tickets | Receiver style, index notation, for loops | — |
| 17 | prover | Advanced | Move Prover, formal specs, invariants, schemas | Receiver style, index notation | Prover |
public, public entry, entry, private, public(friend), inlinehas key, has store, has copy, has drop abilitiesphantom type parameters for type-safe wrappersmatch expressions for enums and destructuringConstructorRef, ExtendRef, DeleteRef, TransferRef, object creation, named/sticky objectsMutatorRef, BurnRef, numbered tokensMetadata, FungibleStore, primary stores, mint/burn/transfercoin::initialize, mint/burn capabilities, CoinStorerandomness::u64_range for on-chain random number generationtimestamp::now_seconds(), timestamp::now_microseconds()ExtendRef for programmatic actionsobject::is_owner or object::owns before granting accessobject::create_named_objectspec blocks, ensures, requires, aborts_if, aborts_withsnippets/
├── composable-nfts/ # Dynamic composable Face + Hat NFTs
│ ├── Move.toml
│ └── sources/
│ └── composable_nfts.move
├── controlled-mint/ # Creator-controlled batch NFT minting
│ ├── Move.toml
│ └── sources/
│ └── controlled_mint.move
├── data-structures/
│ └── heap/ # Min heap with formal verification
│ ├── Move.toml
│ ├── sources/
│ │ └── min_heap_u64.move
│ └── tests/
│ └── min_heap_u64_tests.move
├── design-patterns/
│ └── autonomous-objects/ # Autonomous object design pattern
│ ├── Move.toml
│ └── sources/
│ └── base.move
├── error-codes/ # Error code best practices
│ ├── Move.toml
│ └── sources/
│ └── error_codes.move
├── fa-lockup-example/ # Fungible asset time-locked escrow
│ ├── Move.toml
│ └── sources/
│ └── lockup.move
├── fractional-token/ # NFT fractionalization into fungible tokens
│ ├── Move.toml
│ ├── sources/
│ │ └── fractional_token.move
│ └── tests/
│ ├── common_tests.move
│ └── fractional_token_tests.move
├── liquid-nfts/ # NFT liquidity pools (3 implementations)
│ ├── Move.toml
│ └── sources/
│ ├── common.move
│ ├── liquid_coin.move
│ ├── liquid_coin_legacy.move
│ └── liquid_fungible_asset.move
├── lootbox/ # On-chain mystery boxes with randomness
│ ├── Move.toml
│ └── sources/
│ └── mystery_box.move
├── modifying-nfts/ # Mutable NFT properties and extension
│ ├── Move.toml
│ └── sources/
│ └── modify_nfts.move
├── move-2/ # Move 2 feature reference (redirects to examples)
│ └── README.md
├── parallel-nfts/ # Parallelized public NFT minting
│ ├── Move.toml
│ └── sources/
│ └── parallel_mint.move
├── private-vs-public/ # Function visibility & security
│ ├── cheater/
│ │ ├── Move.toml
│ │ └── sources/
│ │ └── cheater.move
│ └── dice_roll/
│ ├── Move.toml
│ └── sources/
│ └── dice_roll.move
├── prover/ # Formal verification with Move Prover
│ ├── Move.toml
│ └── sources/
│ └── payment_escrow.move
├── snipe-prevention/ # Anti-snipe protection for token launches
│ ├── Move.toml
│ └── sources/
│ └── antisnipe_token.move
├── storage/ # Data structure comparison with gas benchmarks
│ ├── Move.toml
│ └── sources/
│ ├── allowlist_simple_map.move
│ ├── allowlist_smart_table.move
│ ├── allowlist_smart_vector.move
│ ├── allowlist_table.move
│ ├── allowlist_vector.move
│ └── object_management.move
└── struct-capabilities/ # Capability-based mailbox system
├── Move.toml
└── sources/
└── mailbox.move
Different examples use different named addresses in their Move.toml. When compiling without --dev, or when deploying, substitute the appropriate address. Agents: copy the compile line from the package README or from AGENTS.md rather than assuming deploy_addr.
| Named Address | Used By |
|---|---|
deploy_addr | Most examples (error-codes, composable-nfts, controlled-mint, modifying-nfts, parallel-nfts, storage, struct-capabilities, private-vs-public, data-structures/heap) |
deploy_address | design-patterns/autonomous-objects |
fraction_addr | fractional-token, liquid-nfts |
minter | fractional-token (required together with fraction_addr; do not compile this package with --dev) |
mystery_addr | lootbox |
lockup_deployer | fa-lockup-example |
deployer | prover |
antisnipe | snipe-prevention |
| (none) | objects — the module is 0x42::sticky_note (numeric address, not a named address) |
See LICENSE for details.
Move
100.0%