Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time

Preamble

SEP: 0039
Title: Interoperability Recommendations for NFTs
Authors: SDF, Frederic Rezeau <@FredericRezeau>
Track: Informational
Status: Draft
Created: 02-22-2022
Updated: 03-21-2022
Version: 1.0.0
Discussion: https://github.com/stellar/stellar-protocol/pull/1140

Simple Summary

This SEP provides informational guidelines on how NFTs can be managed on the Stellar network and within the ecosystem. It outlines some best practices on both minting and representing NFTs to maximize interoperability.

Dependencies

The guidelines around NFT representation are an extension to SEP-1, specifically around the way currencies are represented.

Motivation

With the NFT marketplace exploding in popularity, two needs arise: ecosystem best practices for creating NFTs as well as interoperability guidelines that ensure compatibility throughout the space. While both of these exist throughout the ecosystem, a single informational SEP is a necessary point of reference. Note that while the focus of this document is inspired by NFTs, it applies more broadly to NFTs that don't necessarily have strict adherence to non-fungibility.

Abstract

We address two key concerns of non-fractional tokens: minting (creation) and representation (parsing, rendering, etc.). For the former, we outline a set of community-driven best practices (that are by no means a required minting standard), and for the latter, we extend the SEP-1 currency specification in order to maximize interoperability with how the ecosystem already renders assets.

Specification

As already noted, this informational SEP is split into two parts: NFT minting best practices and NFT representation interoperability.

The minting best practices are merely one way to create NFTs on Stellar and should not be taken as a standard. The interoperability guidelines, however, are important in representing your NFT via SEP-1 and maximizing its compatibility with the greater ecosystem.

Minting NFTs

This section presents a guide on best practices (rather than a standard) for minting some types of NFTs. It's based heavily on this community guide. Your NFT may or may not need certain elements of this guide, or you may need additional components on top of it. These diversions are noted where appropriate.

At a high level, your NFT is represented by an asset on the Stellar network. Owning the asset represents owning the NFT. This makes your NFT a "first-class citizen" on the network: it immediately benefits from all of Stellar's native features for assets like path payments and the decentralized exchange.

Storing your NFT

Regardless of what your NFT represents (artwork, legal contracts, friendship), you need a way to store it. Using decentralized storage such as the InterPlanetary File System (IPFS) is a recommended best-practice for future-proofing your NFTs. IPFS uses content identifiers (CIDs) to address data. These provide data integrity and immutability: if the underlying NFT changes in any way, its content identifier will also change.

Describing your NFT

Since your NFT can be anything, another best practice is storing metadata that describes it. Inspired by Ethereum's EIP-721 standard, many NFTs in the Stellar ecosystem store JSON metadata file like the following:

{
  "name": "A demonstration of NFT metadata",
  "description": "This is a description of the cool NFT used for an informational SEP demo.",
  "url": "ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/I/m/RickAstleyNeverGonnaGiveYouUp7InchSingleCover.jpg",
  "issuer": "GALAXYVOIDAOPZTDLHILAJQKCVVFMD4IKLXLSZV5YHO7VY74IWZILUTO",
  "code": "DEMOASSET"
}

There are a few key elements here: a way to describe the NFT, a reference to what the NFT represents, and a "back-reference" to the Stellar asset that represents NFT ownership. Again, this isn't a standard but rather a set of common best practices: your metadata file (should you decide to use one) may need different fields. You could even publish a JSON schema to help clients validate the NFT's metadata structure.

Referencing your NFT

There is a common naming convention within the Ethereum ecosystem and other APIs to associate NFTs with their content identifiers. You can use the ManageData operation to store a data entry on your issuing account with ipfshash as the key and the IPFS content identifier as the value to benefit from parts of the ecosystem that also follow the convention. For example, NFT marketplaces like Litemint use the naming convention and look up the CID to discover images, video, audio, full descriptions, and other properties about the NFT seamlessly.

Some marketplaces may do additional lookups. For example, if the ipfshash data entry is not found, Litemint also looks up the entry named ipfshash-<ASSET CODE>, allowing issuers to reference multiple assets per issuing account.

You may want to adopt a different model if this one doesn't fit your use case. For example, you could use a url.<asset-code> data entry or just rely on your SEP-1 file's currency description. Fundamentally, though, it's important to create relationships between your issuing accounts and the NFTs they issue.

Issuing your NFT

To implement non-fractional assets it is necessary to use Stellar's indivisible unit: the stroop. This is the smallest quantity in which a Stellar asset can be sent, received, or traded, and it's equal to one ten-millionth or 0.0000001 of a Stellar lumen (XLM). Therefore, to issue one NFT, you would send 0.0000001 of your asset.

Note: Such small amounts may cause issues on the decentralized exchange because of Stellar Core's internal representation of order prices. There are ways to bypass these limitations, such as the one described by Litemint.

Ensuring NFT immutability

If you plan never to increase the supply or modify your NFT, it is best practice to commit to this by locking the issuing account. Freezing the account representing your NFT is key to providing immutability for the above steps:

  1. It prevents the account from issuing additional units of the NFT.
  2. It prevents data entries from being modified.
  3. It prevents the AccountMerge operation so the issuing account persists.
  4. It prevents revocation of ownership (the "Authorization Immutable" flag could also be used, but it would not prevent the other points above on its own).

By default (i.e. without a multisig setup), to freeze an account you would set its masterWeight to zero via the SetOptions operation.

Freezing is an irreversible process once complete (by design), so take extra care when freezing your NFT issuing account. Some use cases may require the option to unfreeze an account at a future date and this is possible if done in advance, prior to the freeze. This can be done on Stellar via a pre-authorized transaction submitted containing a SetOptions operation that sets the masterWeight back to 1.

Representing NFTs

This section provides interoperability guidance around representing NFTs.

Since NFTs are represented by Stellar assets and are thus "first-class citizens" in the ecosystem, they should leverage existing interoperability layers. Setting up a SEP-1 stellar.toml file provides immediate interoperability with all services and wallets on the Stellar ecosystem. It is highly recommended that all assets you issue on Stellar, NFTs or not, follow the SEP-1 standard to provide a valid stellar.toml file. This grants your NFT a degree of legitimacy, because most Stellar ecosystem services and wallets tend to discard TOML-less assets and/or flag them as spam. There is detailed documentation about how to do that on this page.

Using SEP-1

Many of the SEP-1 fields are highly relevant to NFTs. You should include as many of them as is appropriate for your use case:

  • the code and issuer fields are essential to describe the Stellar asset that represents your NFT
  • the name and desc fields provide human-readable information about your NFT
  • the fixed_number, max_number, and is_unlimited fields are mutually exclusive ways to describe the supply of your NFT
  • the image field is how the ecosystem will "draw" your NFT

Note that even if your NFT isn't an image, you may still want to provide a way to represent it as one (like a logo or symbol) to make it stand out. It's good practice to provide an optimized version of the art to allow fast-loading from services and wallets on Stellar.

Here is an example stellar.toml file describing an asset representing a unique digital image, mimicking the JSON metadata file we described earlier:

[DOCUMENTATION]
ORG_URL="<https://ink.litemint.store>"

[[CURRENCIES]]
issuer="GAKZGD5BFXZ7P7P45WHTM6DODMOEWWJUSCAIPGYIVIPYQSVR6MM6YR7M"
code="DEMOASSET"
name="A demonstration of NFT metadata"
desc="This is a description of the cool NFT used in this demo."
image="https://cloudflare-ipfs.com/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/I/m/RickAstleyNeverGonnaGiveYouUp7InchSingleCover.jpg"
fixed_number=1
display_decimals=7

Once you have a stellar.toml file under your domain, you should also configure the issuing account's homedomain to point to it via the SetOptions operation. This unifies the three separate components: the account issuing the NFT, the metadata describing the NFT, and the NFT itself. Note that this value can't be changed if the account gets locked (see Immutability, above).

SEP-1 Extensions

Since NFTs can represent anything, but the SEP-1 currency specification does not have a generic way to refer to an "anything." There is an image key, but it is generally used for something like a currency logo.

Thus, this SEP adds additional supported fields to the SEP-1 currency specification to faciliate this need:

Field Name Description and purpose
url A valid URL pointing to the NFT this asset represents
url_sha256 A SHA-256 hash of the data pointed to by url

The url_sha256 is optional and provided here as a way to verify the integrity of the NFT. It's particularly useful if the NFT lives on a different server relative to the stellar.toml file. Some URLs (like IPFS CIDs) have integrity "batteries included" and won't need this field.

Design Rationale

A key component of a flourishing NFTs marketplace is interoperability: that drives all of the design decisions in this informational SEP. The first section is a set of best practices for a particular set of needs in creating NFTs. There is no "one size fits all" way to do this, so creators should feel free to deviate from the recommendations to fulfill their needs. The second section adds some extremely flexible fields to SEP-1 to accomodate the fact that NFTs can be anything.

It's worth noting that the idea of "ownership" described throughout the SEP—ownership of an asset and its relationship to owning the respective NFT—is a little diluted: neither the network nor a standard can make any claims about legitimacy of the NFT itself. Owning a unit of the Stellar asset representing your NFT is a way to establish a relationship between buyer and seller that is linked to the NFT, nothing more.

Security Concerns

This informational SEP does not introduce security concerns pertaining to the Stellar network itself.

However, it does introduce concerns around data integrity (i.e. changes to data should be detectable) that NFT issuers (and purchasers) should be aware of. NFTs can be changed after purchase of their representative token, since the stellar.toml file can be arbitrarily changed by its owner and is not explicitly tied to the NFT. If this "triangle of integrity" across the issuing account, the NFT metadata, and the corresponding TOML entry is important to you, you should take extra steps to ensure data integrity.

Changelog

  • v1.0.0: Initial release. #1140