Why?
We have a lot of questions floating around various groups and stakeholders about the NFT standard. I would like to align those discussions somewhere official, here on the forum, to establish the following things:
Goal: achieve soft consensus here on the interface and high level architecture. Take it to GH for implementation.
Here’s what we would love to see happen:
- everyone bring their requirements
- lay all ideas out on the table
- look for patterns in the possible solutions
- choose solution(s)
Here’s what we don’t want:
- promoting a particular approach
- not listening to others
- trying to “own” the standard
- starting my own standard
Discussion
1. Standard interface for NFTs
- account ownership of tokens and transfer of ownership
- approval of other accounts to transfer ownership
- markets (stretch goal for this discussion)
2. Suggested architecture and reference implementation that tackles how to:
- split up the interface across contracts
- deal with storage
- deal with UX
- maximize for extensibility future use cases
NFT Basic Requirements
At the core NFT contracts have a unique account owning 1 or many unique token IDs. The ownership can be transferred from account to account. That’s it.
The original creator of the NFT has additional functionality e.g. mint, burn, etc… but that’s outside the scope of this discussion.
Metadata
NFTs may have some associated metadata per token e.g. a URL.
Enumeration (optional)
A user can retrieve an array of all their tokens from the contract.
Markets & Sales
NFTs have a popular function in secondary markets. If you trust a market you give it approval to transfer your token after the sale has been completed.
Market should handle the buying and selling of NFTs. This is also outside the scope of this discussion, but needs to be mentioned within the context of transfer approvals per token.
Note in NEAR the contract pays for how much data is stored, so a dynamically expanding and contracting list of approvals will affect the NEAR tokens locked for the NFT contract owner, which is not always the owner of an individual token ID.
Requirements (incomplete, please discuss)
- a token ID (token) can only be owned by one account at a time
- accounts can own many tokens
- accounts can transfer tokens that they own to other accounts (by passing ownership)
- accounts can approve many other accounts (markets) on a per token basis, to transfer their token
- one or more tokens can be associated with one or more metadata records
???
Interface (INCOMPLETE)
Data Structures
Token {
owner_id: AccountId,
approved_id: AccountId,
metadata: String,
}
???
Fields
owner_id: AccountId,
tokens: UnorderedMap<TokenId, Token>,
???
Methods
nft_transfer(new_owner_id: AccountId, token_id: TokenId),
nft_transfer_call: (new_owner_id: AccountId, token_id: TokenId, memo: Option<String>),
on_nft_transfer: (sender_id: ValidAccountId, token_id: TokenId, memo: String)
???
Implementation Discussion (INCOMPLETE)
As I understand, from discussions with stakeholders, there are a few implementations in the wild and some ideas that need to be reconciled, or we will end up with a fairly fractured ecosystem.
Storage Issues
Storage is dynamic means for the NFT contract, when a user adds an approval for a marketplace, the contract’s NEAR tokens are locked up to reserve that storage. This means users must “pre-pay” storage by “registering”.
Unless the contract pays all storage for users, in A & B a user must “register” with each NFT contract and provide storage deposits for functionality that has “dynamic” storage (e.g. ever expanding list of approved markets). This also means a user must register with a contract when they are receiving NFTs from airdrops or as gifts.
A) Some implementations in the wild have the NFT contract and markets rolled into one monolithic contract
B) Many proposals make NFTs handle the approvals of the markets they are sold on, on a per token basis. Storage is dynamic.
C) A proposal where many common (from the same developer) NFTs share a single “approver” contract that manages the approval of many markets where the NFT can be sold. The user can grant permissions on a per token basis. Storage for NFTs is static. Storage for approver is dynamic.
A pseudo code example of C is here:
Summary
This is by no means incomplete. I am calling on the community for feedback, ideas and a healthy discussion to reach soft consensus. We must band together and quickly around the best (basic) standards so we don’t face composability issues down the road.
Rules
- be kind, open, flexible and fair
- critique ideas not people
- ???