[SEP-50] Non-Fungible Tokens #1674
Replies: 7 comments 27 replies
-
In terms of metadata, are the Opensea standards considered canonical |
Beta Was this translation helpful? Give feedback.
-
The I had some more general thoughts on the (Completely inconsequential thought: This might wade into "implementation" territory, but would we want to make recommendations for a minting event? Or, is that usually handled like any other transfer event? I'm totally fine either way, just wanted to throw the question out there. |
Beta Was this translation helpful? Give feedback.
-
Had a thought on the use of the I'm not confident about how much of a tangible effect this would have, though. I think @leighmcculloch or @dmkozh might have some knowledge they could share on that (or, they are probably well-situated to tell me I'm completely off-base lol). |
Beta Was this translation helpful? Give feedback.
-
SEP-41 is going to be updated to include the |
Beta Was this translation helpful? Give feedback.
-
The I think we can rename the |
Beta Was this translation helpful? Give feedback.
-
I have a more philosophical question as to how we think standards like this will be implemented by wallets. Right now as I understand it all our ecosystem wallets populate asset data from a A really basic question is should our asset interfaces include a |
Beta Was this translation helpful? Give feedback.
-
I'm doing a final read through the SEP as part of hte merge process, and I noticed an inconsistency and want to check if it's intentional. The The The This lack of symmetry presents some ambiguity:
/// Returns the account approved for `token_id` token.
///
/// # Arguments
///
/// * `e` - Access to the Soroban environment.
/// * `token_id` - Token id as a number.
///
/// # Notes
///
/// If the token does not exist, this function is expected to panic.
fn get_approved(e: &Env, token_id: TokenID) -> Option<Address>;
/// Returns whether the `operator` is allowed to manage all the assets of
/// `owner`.
///
/// # Arguments
///
/// * `e` - Access to the Soroban environment.
/// * `owner` - Account of the token's owner.
/// * `operator` - Account to be checked.
fn is_approved_for_all(e: &Env, owner: Address, operator: Address) -> bool; |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Preamble
Summary
This proposal defines a standard contract interface for non-fungible tokens. The interface is a similar to ERC721, but factors in the differences between Ethereum and Stellar.
Motivation
A non-fungible asset (NFT) is a fundamental concept on blockchains, representing unique and indivisible digital assets. While most blockchain ecosystems have established standards for NFTs, such as ERC-721 and ERC-1155 in Ethereum, the Stellar ecosystem lacks a standardized interface for NFTs. This absence may lead to fragmentation, making it difficult to ensure interoperability between different NFT contracts and applications.
Currently, while it is technically possible to create NFTs on Stellar by issuing non-divisible assets with unique metadata as outlined in SEP-39 -and one can deploy the SAC for it afterwards-, this approach is unintuitive for developers, due to SAC is mainly designed for Fungible tokens, and comes with the following limitations:
By defining NFTs as smart contracts, developers gain more intuitive and straight-forward way to issue NFTs, along with greater flexibility, programmability, and interoperability, enabling use cases beyond simple asset issuance.
This proposal defines a non-fungible token interface that provides core NFT functionality, including ownership management, transfers, and approvals, without enforcing opinionated behaviors beyond the standard expectations for NFTs. By establishing this interface, NFT contracts can interact seamlessly with other contracts and applications that support the standard, ensuring broader usability and compatibility within the Stellar network.
Interface
NFTs can have diverse use cases, and there is no universal
token_id
format that fits all scenarios. Some implementations may use sequential numbers, while others may opt for UUIDs or hashes. To accommodate this variability, this interface remains agnostic to the specifictoken_id
format, defining it as a genericTokenID
type, which should be an unsigned integer.Additionally, since a single account cannot hold more tokens than the total supply of
TokenIDs
, we introduce aBalance
type. In most cases,Balance
should use the same type asTokenID
for consistency.Events
Transfer Event
The transfer event is emitted when an NFT is transferred from one address to another.
Topics:
Symbol
with value"transfer"
Address
: the address holding the token that was transferred.Address
: the address that received the token.Data:
TokenID
: the identifier of the transferred token.Approve Event
The "approve" event is emitted when an owner grants another address permission to manage a specific token.
Topics:
Symbol
with value"approve"
Address
: the owner of the token.TokenID
: the identifier of the token.Data:
Address
: the approved address.u32
: the expiration ledger.Approve for All Event
The "approve for all event" is emitted when an owner grants or revokes permission for an operator to manage all of their NFTs.
Topics:
Symbol
with value"approve_for_all"
Address
: the owner of the tokens.Data:
Address
: the operator receiving or losing permission.u32
: the expiration ledger. If0
, the approval is revoked.Mint Event
The
mint
event is emitted when a token is minted.The event has topics:
Symbol
with value"mint"
Address
: the address to hold the newly minted token.The event has data:
TokenID
the identifier of the minted token.Notes on
mint()
:minting
tokens.Notes on
safeTransferFrom
:safeTransferFrom
andonERC721Received
exist to prevent the loss of NFTs when transferring them to a smart contract that does not support NFT-related operations.onERC721Received
.[permit](https://eips.ethereum.org/EIPS/eip-2612)
mechanism (EIP-2612), which leverages off-chain signatures to authorize the recipient to claim the tokens, reducing on-chain transactions from two to one.Notes on
permit
:safeTransfer
andonReceive
ensure the recipient can handle NFTs, preventing accidental burns. Unlike fungible tokens, NFTs can’t be broken into tiny fractions, and test-transferred in small amounts.Stellar’s trust lines offer similar safety but apply to specific assets, whereas safe transfer secures entire asset classes. Soroban removed trust line requirements for contract transfers.
safeTransferFrom
is relevant for NFT transfers to smart contracts, whilepermit
also works for EOAs, addressing the indivisibility issue. Stellar’s built-in signatures providepermit
-like functionality at the protocol level. For added safety, developers can implement safe variants or leverage existing solutions.Notes on
transfer()
:transfer()
function exists in ERC20 but is absent in ERC721, primarily for historical reasons. In both ERC20 and ERC721,transferFrom()
can be used instead oftransfer()
, with the the only difference being an additional on-chain check. To avoid redundancy,transfer()
was omitted from the ERC721 standard.transfer()
retains a key advantage overtransferFrom()
: when the token owner initiates the transfer,transfer()
is more efficient and cost-effective, as it eliminates the need for an extra on-chain verification.transfer()
remains the same for both fungible and non-fungible tokens, so we decided to include it for NFTs as well in this SEP.Notes on
name()
,symbol()
andtoken_uri()
token_uri()
returns an url that points to a JSON file that conforms to the "Non-Fungible Metadata JSON Schema".Beta Was this translation helpful? Give feedback.
All reactions