-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add NFT standard #3
Merged
Merged
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
ef4e785
Create nft-standard.md
friedger c978f09
Update nft-standard.md
friedger 96a87f8
Update nft-standard.md
friedger ca68556
move sip
friedger 98b2f03
fix order in transfer
friedger 7b6a919
add implementation rules
friedger 5f6cbd0
fix response type, add error rules, add impl
friedger 660ba1b
Add reference implementation, more details for functions
friedger 629a976
Remove ? from function names
friedger 76778ea
Update sip-009-nft-standard.md
friedger 6ea5810
Minor changes from by @pxydn
friedger 92d64c7
add get-token-uri
friedger b7be83d
explain differences to EIP 721
friedger e2fe2df
fix typos
friedger aca6516
restructure as suggested by @muneebm
friedger a2cf277
add Muneeb as author
friedger b16b169
add trait deployment addresses, improve wording, replace id with ID
friedger bd97e51
fix typo
friedger 9183bdc
fix mainnet address
friedger f50ad4a
fix mainnet address
friedger 1455469
update response error type of transfer to uint
friedger 0fc6b6d
Merge branch 'main' of github.com:stacksgov/sips into main
friedger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# Preamble | ||
|
||
SIP Number: 009 | ||
|
||
Title: Standard Trait Definition for Non-Fungible Tokens | ||
|
||
Author: Friedger Müffke ([email protected]) | ||
|
||
Consideration: Technical | ||
|
||
Type: Standard | ||
|
||
Status: Draft | ||
|
||
Created: 10 December 2020 | ||
|
||
License: CC0-1.0 | ||
|
||
Sign-off: | ||
|
||
# Abstract | ||
|
||
Non-fungible token are unique digital assets that are registered on the Stacks blockchain through a smart contract with certain properties. | ||
Users should be able to identify a single non-fungible token. Users should be able to own it and transfer it. Non-fungible tokens can have additional properties not specified in this standard. | ||
|
||
# License and Copyright | ||
|
||
This SIP is made available under the terms of the Creative Commons CC0 1.0 Universal license, available at https://creativecommons.org/publicdomain/zero/1.0/ | ||
This SIP’s copyright is held by the Stacks Open Internet Foundation. | ||
|
||
# Introduction | ||
|
||
Tokens are digital assets that are registered on the Stacks blockchain through a smart contract. A non-fungible token (NFT) is a token that is globally unique and that users can identify through its identifier. The smart contract that registers the NFTs defines a name for the group of NFTs. | ||
|
||
NFTs are enumerated, the id starts at 1 and the current last id is provided by the smart contract. | ||
|
||
# Specification | ||
|
||
NFT smart contract shall implement the trait defined at `ST314JC8J24YWNVAEJJHQXS5Q4S9DX1FW5Z9DK9NT.nft-trait` as well as satisfy the additional conditions. | ||
The trait has three functions: | ||
* `get-last-token-id` does not take any arguments and returns the highest number that is used as an identifier for any NFT. This is the upper limit when iterating through all NFTs. | ||
* `get-token-uri` takes an NFT identifier and returns a response containing a URI pointing to metadata of the given identifier. The URI is wrapped as an optional, which means if the corresponding NFT exists or the contract does not maintain metadata, the response is `(ok none)` - otherwise, e.g. `(ok (some "https://example.com"))`. The length of the returned URI is limited to 256. The specification of the metadata should be covered in a separate SIP. | ||
* `get-owner` takes an NFT identifier and returns a response containing the principal owning the NFT for the given identifier. The principal is wrapped as an optional, which means if the corresponding NFT does not exists the response is `(ok none)`, otherwise, e.g. `(ok (some 'ST12...))`. The owner can be a contract principal. | ||
* `transfer` takes an NFT identifier, a sender principal and a receiver principal. The function changes the ownership of the NFT for the given identifier. The change has to be reflected in the `get-owner` function, for details see implementation rules. | ||
|
||
## Trait | ||
|
||
``` | ||
(define-trait stacks-token-nft-standard-v1 | ||
( | ||
;; Token ID, limited to uint range | ||
(get-last-token-id () (response uint uint)) | ||
|
||
;; URI for metadata about the token | ||
(get-token-uri (uint) (response (optional (string-ascii 256)) uint)) | ||
|
||
;; Owner of given token identifier | ||
(get-owner (uint) (response (optional principal) uint)) | ||
friedger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
;; Transfer from to | ||
(transfer (uint principal principal) (response bool (tuple (kind (string-ascii 32)) (code uint)))) | ||
friedger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
) | ||
``` | ||
|
||
## Implementation rules | ||
|
||
1. Contracts must use a least one NFT asset. A post-condition with deny mode and without any NFT condition about a changed owner must fail for `transfer` function calls. | ||
1. After a successful call to function `transfer`, the function `get-owner` must return the recipient of the `transfer` call as the new owner. | ||
1. If a call to function `get-owner` returns some principal `A` value then it must return the same value until `transfer` is called with principal `A` as a sender | ||
1. For any call to `get-owner`, resp. `transfer` with an id greater than `last-token-id`, the call should return a response `none`, resp. failed transfer. | ||
1. The following error codes are defined | ||
|
||
| function | error | description | | ||
|----------|-------|-------------| | ||
|`transfer`|`{kind: "nft-transfer-failed", code: from-nft-transfer}`| Error if the call failed due to the underlying asset transfer. The code `from-nft-transfer` is the error code from the native asset transfer function| | ||
|
||
1. The methods `get-last-token-id`, `get-token-uri` and `get-owner` can be implemented as read-only functions. | ||
|
||
# Related Work | ||
|
||
NFTs are an established asset class on blockchains. Read for example [here](https://www.ledger.com/academy/what-are-nft). | ||
|
||
## EIP 721 | ||
Ethereum has [ERP 721](https://eips.ethereum.org/EIPS/eip-721) that defined non-fungible tokens on the Ethereum blockchain. Notable differences are that the transfer function in EIP 721 uses a different ordering of the arguments ending with the token id. This SIP uses the token id as the first argument which is in line with all transfer functions in Clarity. Furthermore, this SIP only defines a URI pointing to metadata. There are no specifications about schema or other properties of token metadata. These should be specified in a separate SIP. | ||
|
||
|
||
# Backwards Compatibility | ||
|
||
Not applicable | ||
|
||
# Activation | ||
|
||
This SIP is activated if 5 contracts are deployed that use the same trait that follows this specification. This must happen before Bitcoin tip #700,000. | ||
|
||
# Reference Implementations | ||
|
||
## Source code | ||
### Friedger's clarity-smart-contracts | ||
https://github.com/friedger/clarity-smart-contracts/blob/master/contracts/sips/nft-trait.clar | ||
|
||
Deployment on testnet: TODO |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.