The AtomicAssets v2 standard contract. Built from main at fd7d730 with CDT 4.1.1.
v2 is an in-place upgrade of the v1 contract. Every existing table keeps its layout and every existing action keeps its signature, so v1 clients and indexers keep working without changes. New capabilities live in new actions and new tables. Upgrading is a setcode and setabi; on-chain state is preserved and no migration action is required.
What v2 adds
1. Reduce max supply
redtemplmax lowers a template's max_supply. It can never be lowered below the supply already issued.
2. Delete unused templates
deltemplate removes a template that has no issued assets, and cleans up its templates2 row.
3. Mutable templates
createtempl2 creates a template carrying mutable data, and settempldata updates it. Each change emits logsetdatatl. Mutable data lives in the new templates2 table alongside the original immutable templates row, so a v1 reader that knows only templates continues to work.
4. Schema media types
setschematyp records per-field media-type descriptors for a schema in the new schematypes table, so a consumer can tell how to render a field rather than inferring it from the field name.
Note for authors: setschematyp replaces the whole descriptor array. Read the stored descriptors before writing, or a client working from a merged or inferred view will write its guesses back to chain.
5. Collection author succession
A two-step author handover. createauswap proposes a new author, and acceptauswap or rejectauswap completes or cancels it. Pending swaps live in the new authorswaps table, and the collection's author changes only on acceptance, so no single party can move a collection unilaterally.
6. A template must permit transfer or burn
createtempl and createtempl2 reject a template whose assets would be neither transferable nor burnable, with A template cannot be both non-transferable and non-burnable. Such an asset could never move and could never be destroyed, so it would hold its owner's RAM permanently with no way to release it.
Both flags are unchanged from v1 and every other combination stays valid: transferable and burnable, transferable only, burnable only. Only the pair set false is refused. The check runs at creation, so templates already in that state keep working exactly as before.
7. Native backing is disabled
backasset now fails unconditionally with Native backing has been deprecated on the AtomicAssets Contract, and mintasset rejects a non-empty tokens_to_back with the same message. No new asset can be backed with fungible tokens after this upgrade. The action remains in the ABI, so the change is invisible to an ABI diff: any integration that calls backasset will start failing at the point of the upgrade and should be updated first.
Value already backed is not stranded:
- Burning an asset still releases its
backed_tokensto the owner's balance, exactly as in v1. withdrawcontinues to work, so balances can still be withdrawn.announcedepoand the deposit path are unchanged.
8. Contract-wide CPU optimizations
The hot collection-authorization checks (check_has_collection_auth, notify_collection_accounts) read only the bytes they need from the collection row through a low-level partial read, rather than loading a row that can carry several KB of serialized data on every schema, template and asset action.
The transfer and offer paths also stop building their failure message on the success path. check(cond, msg) evaluates its message argument before the call, so every successful transfer was concatenating an asset id into a string it then discarded. The check is now written if (!cond) { check(false, msg) }, and the string is built only when the transfer is actually rejected.
Self-service RAM utilities
setrampayer and setlastpayer reassign an asset's RAM payer, emitting logrampayer.
Interface changes
Additive in full. Nothing is removed and no existing struct changes shape. The behavior changes described above are not expressed in the ABI and an ABI diff will not show them. The final surface is 47 actions and 11 tables.
| Added | |
|---|---|
| Actions (12) | createtempl2, settempldata, logsetdatatl, deltemplate, redtemplmax, setschematyp, createauswap, acceptauswap, rejectauswap, setrampayer, setlastpayer, logrampayer |
| Tables (3) | templates2, schematypes, authorswaps |
Existing tables (assets, templates, schemas, collections, config, offers, balances, tokenconfigs) are unchanged. The ABI version moves from eosio::abi/1.1 to 1.2.
Upgrading
A setcode plus setabi. State is preserved and no migration action runs.
Several calls change from success to failure. Every signature is unchanged, so none of this is visible in an ABI diff. Confirm nothing you operate depends on any of them.
backassetfails unconditionally, andmintassetrejects a non-emptytokens_to_back. See Native backing is disabled.createtemplandcreatetempl2reject a template that is both non-transferable and non-burnable. See A template must permit transfer or burn.addcolauthandaddnotifyaccrefuse to extend a list that already holds 24 accounts, andcreatecolrejects more than 24 in either list. V1 enforced no limit, and these lists are walked on every notifying action. A collection already above the cap keeps every entry it has and can still remove them.
Custodial rentals are not part of v2. That implementation is preserved on the archive/v2-custodial-rentals branch.
Artifacts
| Asset | sha256 |
|---|---|
atomicassets.wasm |
962a93e1adde9779d3afb84983cee076c3d2b50b0473c99fb0fe02573a7b7242 |
atomicassets.abi |
b6389fdde10a16f2d94b12bb10a67b676f6449b1293b57cc0b18256652cfef68 |
Verify against the attached SHA256SUMS. On a deployed account the wasm sha256 equals the on-chain code hash, so get_code_hash is sufficient to confirm which bytes are running.
Build and verification
Built with cdt-cpp 4.1.1 from a clean checkout of main at fd7d730. The published ABI is the legacy-compat build: vector<uint8_t> fields render as uint8[] and pair fields keep their first and second spellings, so integrations reading the ABI are unaffected. The VeRT suite is green at 40 suites and 325 tests, one skipped.
Deploying
Pinned by sha256 in the FACINGS monorepo chain-config and deployed through the contracts-deploy workflow. Where the contract account is governed by a multi-party authority, the upgrade reaches chain as an eosio.msig proposal that the authority's signers verify, approve and execute. Signers should check the proposal's wasm sha256 against the table above and its packed ABI against the published .abi, since the chain does not validate setabi payloads.
Credits
AtomicAssets is an open NFT standard created by Pink Network, with stewardship passing from Pink Network to Spielworks and then to FACINGS. The bulk of the v2 contract was authored by t-break (@on-a-t-break). The interface-header fix is from Aaron Cox (@aaroncox, Greymass). Full attribution is in AUTHORS.md.