Skip to content

v2.0.0

Latest

Choose a tag to compare

@robrigo robrigo released this 03 Aug 23:10
fd7d730

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_tokens to the owner's balance, exactly as in v1.
  • withdraw continues to work, so balances can still be withdrawn.
  • announcedepo and 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.

  • backasset fails unconditionally, and mintasset rejects a non-empty tokens_to_back. See Native backing is disabled.
  • createtempl and createtempl2 reject a template that is both non-transferable and non-burnable. See A template must permit transfer or burn.
  • addcolauth and addnotifyacc refuse to extend a list that already holds 24 accounts, and createcol rejects 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.