From 1b8654ff0579adb4e94dcc04decbe42f61b46f7c Mon Sep 17 00:00:00 2001 From: SamDelaney Date: Fri, 5 May 2023 18:40:35 -0700 Subject: [PATCH 01/28] First pass: introduce royalty metadata as specified in Nebula --- CIP-0068/README.md | 77 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index e6a059bb5..a42449920 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -95,7 +95,7 @@ datum = #6.121([metadata, version, extra]) #### 222 NFT Standard -Besides the necessary standard for the `reference NFT` we're introducing three specific token standards in this CIP. Note that the possibilities are endless here and more standards can be built on top of this CIP for FTs, other NFTs, rich fungible tokens, etc. The first is the `222` NFT standard with the registered `asset_name_label` prefix value +Besides the necessary standard for the `reference NFT` we're introducing four specific token standards in this CIP. Note that the possibilities are endless here and more standards can be built on top of this CIP for FTs, other NFTs, rich fungible tokens, etc. The first is the `222` NFT standard with the registered `asset_name_label` prefix value | asset_name_label | class | description | | --------------------------- | ------------ | -------------------------------------------------------------------- | @@ -329,6 +329,81 @@ We want to bring the metadata of the RFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8 3. Reference the output in the transaction. (off-chain) 4. Verify validity of datum of the referenced output by checking if policy ID of `reference NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) +#### 500 Royalty Standard + +The third introduced standard is the `500` Royalty NFT standard with the registered `asset_name_label` prefix value + +| asset_name_label | class | description | +| --------------------------- | ------------ | -------------------------------------------------------------------- | +| 500 | NFT | Royalty NFT locked at a script containing a datum making use of CIP-0027 inner structure | + + + +##### Class + +The `royalty token` is an NFT (non-fungible token). + +##### Pattern + +The `royalty token` and `reference NFT` **must** have an identical name, preceded by the `asset_name_label` prefix. + +Example:\ +`royalty token`: `(500)Test123`\ +`reference NFT`: `(100)Test123` + +##### Metadata + +The ideal way to handle the royalty token is to have it under the same `policy id` as the collection. This will make the authentication process smoother and more efficient. However, Nebula allows for specifying a different `policy id` if necessary.\ +The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0067/README.md) label `500`. + +The royalty info datum is specified as follows (CDDL): + +```cddl +big_int = int / big_uint / big_nint +big_uint = #6.2(bounded_bytes) +big_nint = #6.3(bounded_bytes) + +optional_big_int = #6.121([big_int]) / #6.122([]) + +royalty_recipient = #6.121([ + address, ; definition can be derived from: + ; https://github.com/input-output-hk/plutus/blob/master/plutus-ledger-api/src/PlutusLedgerApi/V1/Address.hs#L31 + int, ; variable fee ( calculation: ⌊1 / (fee / 10)⌋ ); integer division with precision 10 + optional_big_int, ; min fee (absolute value in lovelace) + optional_big_int, ; max fee (absolute value in lovelace) + ]) + +royalty_recipients = [ * royalty_recipient ] + +; version is of type int, we start with version 1 +version = 1 + +; Custom user defined plutus data. +; Setting data is optional, but the field is required +; and needs to be at least Unit/Void: #6.121([]) +extra = plutus_data + +royalty_info = #6.121([royalty_recipients, version, extra]) +``` + +##### Retrieve metadata as 3rd party + +A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to lookup the royalties. The steps are + +1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)TestToken` +2. Look up `royalty NFT` and find the output it's locked in. +3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. +4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. + +##### Retrieve metadata from a Plutus validator + +We want to bring the royalty metadata of the NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` in the Plutus validator context. To do this we + +1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)TestToken` (off-chain) +2. Look up `royalty NFT` and find the output it's locked in. (off-chain) +3. Reference the output in the transaction. (off-chain) +4. Verify validity of datum of the referenced output by checking if policy ID of `royalty NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) + ## Rationale Without seperation of `reference NFT` and `user token` you lose all flexibility and moving the `user token` would be quite cumbersome as you would need to add the metadata everytime to the new output where the `user token` is sent to. Hence you separate metadata and `user token` and lock the metadata inside another UTxO, so you can freely move the `user token` around. From 461e20789468f6b5f5784a253c3cd6563c400b31 Mon Sep 17 00:00:00 2001 From: SamDelaney Date: Mon, 15 May 2023 17:47:29 -0700 Subject: [PATCH 02/28] minor fixes --- CIP-0068/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index a42449920..326968f2d 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -331,11 +331,11 @@ We want to bring the metadata of the RFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8 #### 500 Royalty Standard -The third introduced standard is the `500` Royalty NFT standard with the registered `asset_name_label` prefix value +The fourth introduced standard is the `500` Royalty NFT standard with the registered `asset_name_label` prefix value | asset_name_label | class | description | | --------------------------- | ------------ | -------------------------------------------------------------------- | -| 500 | NFT | Royalty NFT locked at a script containing a datum making use of CIP-0027 inner structure | +| 500 | NFT | Royalty NFT locked at a script containing a datum with royalty information | From a05fa4a3557e7b9d1cb1c8ab94fd7271e964369d Mon Sep 17 00:00:00 2001 From: SamDelaney Date: Wed, 17 May 2023 17:03:36 -0700 Subject: [PATCH 03/28] fix token name --- CIP-0068/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 326968f2d..5fe5218c7 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -345,10 +345,10 @@ The `royalty token` is an NFT (non-fungible token). ##### Pattern -The `royalty token` and `reference NFT` **must** have an identical name, preceded by the `asset_name_label` prefix. +The `royalty token` and `reference NFT` **must** have an identical policy ID. The royalty token's name should be `Royalty`, preceded by the `asset_name_label` prefix. Example:\ -`royalty token`: `(500)Test123`\ +`royalty token`: `(500)Royalty`\ `reference NFT`: `(100)Test123` ##### Metadata @@ -390,7 +390,7 @@ royalty_info = #6.121([royalty_recipients, version, extra]) A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to lookup the royalties. The steps are -1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)TestToken` +1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)Royalty` 2. Look up `royalty NFT` and find the output it's locked in. 3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. 4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. @@ -399,7 +399,7 @@ A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5c We want to bring the royalty metadata of the NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` in the Plutus validator context. To do this we -1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)TestToken` (off-chain) +1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)Royalty` (off-chain) 2. Look up `royalty NFT` and find the output it's locked in. (off-chain) 3. Reference the output in the transaction. (off-chain) 4. Verify validity of datum of the referenced output by checking if policy ID of `royalty NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) From 860a77a2b62e664ef53093a776d2d604b075b835 Mon Sep 17 00:00:00 2001 From: SamDelaney Date: Wed, 24 May 2023 18:52:22 -0700 Subject: [PATCH 04/28] consolidate TN spec & rename token -> NFT --- CIP-0068/README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 5fe5218c7..0319da65e 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -337,25 +337,22 @@ The fourth introduced standard is the `500` Royalty NFT standard with the regist | --------------------------- | ------------ | -------------------------------------------------------------------- | | 500 | NFT | Royalty NFT locked at a script containing a datum with royalty information | - - ##### Class -The `royalty token` is an NFT (non-fungible token). +The `royalty NFT` is an NFT (non-fungible token). ##### Pattern -The `royalty token` and `reference NFT` **must** have an identical policy ID. The royalty token's name should be `Royalty`, preceded by the `asset_name_label` prefix. +The ideal way to handle the `royalty NFT` is to have it under the same `policy id` as the collection. This will make the authentication process smoother and more efficient. However, a different `policy id` may be specified if necessary. + +The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0067/README.md) label `500` followed by the word "Royalty". Example:\ -`royalty token`: `(500)Royalty`\ +`royalty NFT`: `(500)Royalty`\ `reference NFT`: `(100)Test123` ##### Metadata -The ideal way to handle the royalty token is to have it under the same `policy id` as the collection. This will make the authentication process smoother and more efficient. However, Nebula allows for specifying a different `policy id` if necessary.\ -The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0067/README.md) label `500`. - The royalty info datum is specified as follows (CDDL): ```cddl From 1fb1f14732acd85e96861db579b5e9718fedd301 Mon Sep 17 00:00:00 2001 From: Sam Delaney Date: Mon, 5 Jun 2023 16:00:42 -0700 Subject: [PATCH 05/28] require royalty NFT policyId to match reference NFT --- CIP-0068/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 0319da65e..0e2f94fbc 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -343,7 +343,7 @@ The `royalty NFT` is an NFT (non-fungible token). ##### Pattern -The ideal way to handle the `royalty NFT` is to have it under the same `policy id` as the collection. This will make the authentication process smoother and more efficient. However, a different `policy id` may be specified if necessary. +The `royalty NFT` **must** have an identical `policy id` as the collection. The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0067/README.md) label `500` followed by the word "Royalty". From f198e2a7b5e17b084c576a2979c260fca8c7316b Mon Sep 17 00:00:00 2001 From: Sam Delaney Date: Wed, 7 Jun 2023 14:30:22 -0700 Subject: [PATCH 06/28] Change royalty location to suggestion --- CIP-0068/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 0e2f94fbc..21a0e771c 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -335,7 +335,7 @@ The fourth introduced standard is the `500` Royalty NFT standard with the regist | asset_name_label | class | description | | --------------------------- | ------------ | -------------------------------------------------------------------- | -| 500 | NFT | Royalty NFT locked at a script containing a datum with royalty information | +| 500 | NFT | Royalty NFT stored in a UTxO containing a datum with royalty information | ##### Class @@ -383,6 +383,8 @@ extra = plutus_data royalty_info = #6.121([royalty_recipients, version, extra]) ``` +To prevent abuse, it is **recommended** that the `royalty NFT` is stored at the script address of a validator that ensures the specified fees are not arbitrarily changed, such as an always-fails validator. + ##### Retrieve metadata as 3rd party A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to lookup the royalties. The steps are From 693adacb42d71931a0be39dcf938c53d06453579 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Wed, 12 Jul 2023 21:47:40 -0700 Subject: [PATCH 07/28] Elaborate on fee calculation --- CIP-0068/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 21a0e771c..632bc00b1 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -383,6 +383,18 @@ extra = plutus_data royalty_info = #6.121([royalty_recipients, version, extra]) ``` +Example of onchain variable fee calculation: +``` +; Given a royalty fee of 1.6% (0.016) + +; To store this in the royalty datum +1 / (0.016 / 10) => 625 + +; To read it back +10 / 625 => 0.016 +``` +Because the computational complexity of Plutus primitives scales with size, this approach significantly minimizes resource consumption. + To prevent abuse, it is **recommended** that the `royalty NFT` is stored at the script address of a validator that ensures the specified fees are not arbitrarily changed, such as an always-fails validator. ##### Retrieve metadata as 3rd party From 1709808cfccf0d5d8f1b7a1c2051cfd7fe6b0e4c Mon Sep 17 00:00:00 2001 From: samdelaney Date: Wed, 12 Jul 2023 22:23:51 -0700 Subject: [PATCH 08/28] Add 500 token to CIP 67 registry --- CIP-0067/registry.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CIP-0067/registry.json b/CIP-0067/registry.json index f7716b1f4..7159abe3d 100644 --- a/CIP-0067/registry.json +++ b/CIP-0067/registry.json @@ -19,4 +19,9 @@ "class": "RFT", "description": "CIP-0068 - Datum Metadata Standard (444 sub standard)" }, + { + "asset_name_label": 500, + "class": "NFT", + "description": "CIP-0068 - Datum Metadata Standard (500 sub standard)" + } ] From 6409e4c9d43a5b7330ad9801821a2436c7d00da6 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Wed, 9 Aug 2023 15:51:19 -0700 Subject: [PATCH 09/28] move to a new CIP Signed-off-by: samdelaney --- CIP-0068/README.md | 87 +------------------------ CIP-XXXX/ref_impl/README.md | 124 ++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 86 deletions(-) create mode 100644 CIP-XXXX/ref_impl/README.md diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 632bc00b1..bafacd6aa 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -95,7 +95,7 @@ datum = #6.121([metadata, version, extra]) #### 222 NFT Standard -Besides the necessary standard for the `reference NFT` we're introducing four specific token standards in this CIP. Note that the possibilities are endless here and more standards can be built on top of this CIP for FTs, other NFTs, rich fungible tokens, etc. The first is the `222` NFT standard with the registered `asset_name_label` prefix value +Besides the necessary standard for the `reference NFT` we're introducing three specific token standards in this CIP. Note that the possibilities are endless here and more standards can be built on top of this CIP for FTs, other NFTs, rich fungible tokens, etc. The first is the `222` NFT standard with the registered `asset_name_label` prefix value | asset_name_label | class | description | | --------------------------- | ------------ | -------------------------------------------------------------------- | @@ -329,91 +329,6 @@ We want to bring the metadata of the RFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8 3. Reference the output in the transaction. (off-chain) 4. Verify validity of datum of the referenced output by checking if policy ID of `reference NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) -#### 500 Royalty Standard - -The fourth introduced standard is the `500` Royalty NFT standard with the registered `asset_name_label` prefix value - -| asset_name_label | class | description | -| --------------------------- | ------------ | -------------------------------------------------------------------- | -| 500 | NFT | Royalty NFT stored in a UTxO containing a datum with royalty information | - -##### Class - -The `royalty NFT` is an NFT (non-fungible token). - -##### Pattern - -The `royalty NFT` **must** have an identical `policy id` as the collection. - -The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0067/README.md) label `500` followed by the word "Royalty". - -Example:\ -`royalty NFT`: `(500)Royalty`\ -`reference NFT`: `(100)Test123` - -##### Metadata - -The royalty info datum is specified as follows (CDDL): - -```cddl -big_int = int / big_uint / big_nint -big_uint = #6.2(bounded_bytes) -big_nint = #6.3(bounded_bytes) - -optional_big_int = #6.121([big_int]) / #6.122([]) - -royalty_recipient = #6.121([ - address, ; definition can be derived from: - ; https://github.com/input-output-hk/plutus/blob/master/plutus-ledger-api/src/PlutusLedgerApi/V1/Address.hs#L31 - int, ; variable fee ( calculation: ⌊1 / (fee / 10)⌋ ); integer division with precision 10 - optional_big_int, ; min fee (absolute value in lovelace) - optional_big_int, ; max fee (absolute value in lovelace) - ]) - -royalty_recipients = [ * royalty_recipient ] - -; version is of type int, we start with version 1 -version = 1 - -; Custom user defined plutus data. -; Setting data is optional, but the field is required -; and needs to be at least Unit/Void: #6.121([]) -extra = plutus_data - -royalty_info = #6.121([royalty_recipients, version, extra]) -``` - -Example of onchain variable fee calculation: -``` -; Given a royalty fee of 1.6% (0.016) - -; To store this in the royalty datum -1 / (0.016 / 10) => 625 - -; To read it back -10 / 625 => 0.016 -``` -Because the computational complexity of Plutus primitives scales with size, this approach significantly minimizes resource consumption. - -To prevent abuse, it is **recommended** that the `royalty NFT` is stored at the script address of a validator that ensures the specified fees are not arbitrarily changed, such as an always-fails validator. - -##### Retrieve metadata as 3rd party - -A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to lookup the royalties. The steps are - -1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)Royalty` -2. Look up `royalty NFT` and find the output it's locked in. -3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. -4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. - -##### Retrieve metadata from a Plutus validator - -We want to bring the royalty metadata of the NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` in the Plutus validator context. To do this we - -1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)Royalty` (off-chain) -2. Look up `royalty NFT` and find the output it's locked in. (off-chain) -3. Reference the output in the transaction. (off-chain) -4. Verify validity of datum of the referenced output by checking if policy ID of `royalty NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) ## Rationale diff --git a/CIP-XXXX/ref_impl/README.md b/CIP-XXXX/ref_impl/README.md new file mode 100644 index 000000000..09bd818d1 --- /dev/null +++ b/CIP-XXXX/ref_impl/README.md @@ -0,0 +1,124 @@ +--- +CIP: ???? +Title: Royalty Datum Metadata Standard +Authors: Sam Delaney +Comments-URI: +Status: Proposed +Type: Informational +Created: 2023-08-08 +Post-History: +License: CC-BY-4.0 +--- + +## Abstract + +This proposal makes use of the onchain metadata pattern established in CIP 68 to provide a way to store royalties with greater assurance and customizability. + +## Motivation + +The inability to create trustless onchain royalty validation with CIP 27 is a major drawback to Cardano NFTs. The pattern defined in CIP 68 represents an opportunity to upgrade the standard to support onchain validation. This CIP aims to eliminate that drawback and demonstrate better support for developers, NFT creators, and NFT collectors, ultimately attracting dapps & NFT projects that would otherwise have taken their talents to another blockchain. + +In addition, this standard allows royalties to be split between multiple addresses, another limitation of the CIP 27 royalty schema. Future versions of this standard could also easily support multiple royalty policies defined for a single collection, applied at the level of individual tokens. + +## Specification + +### Background + +This specification is largely based on [the royalty specification in Nebula](https://github.com/spacebudz/nebula/tree/main#royalty-info-specification), with a couple key departures: + +- The royalty token is recommended to be locked at a script address, rather than stored in the user's wallet. This encourages projects to guarantee royalties won't change by sending their royalties to an always-fails (or similar) script address, but still allows for creative royalty schemes and minimizes disruption to existing projects. + +- The policyId of the royalty NFT must match that of the reference NFT. This enables lookups based on the user token in the same way as is done for the tokens specified in the original CIP 68 standard. + +### 500 Royalty Standard + +The following defines the `500` Royalty NFT standard with the registered `asset_name_label` prefix value + +| asset_name_label | class | description | +| --------------------------- | ------------ | -------------------------------------------------------------------- | +| 500 | NFT | Royalty NFT stored in a UTxO containing a datum with royalty information | + +#### Class + +The `royalty NFT` is an NFT (non-fungible token). + +#### Pattern + +The `royalty NFT` **must** have an identical `policy id` as the collection. + +The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0067/README.md) label `500` followed by the word "Royalty". + +Example:\ +`royalty NFT`: `(500)Royalty`\ +`reference NFT`: `(100)Test123` + +#### Metadata + +The royalty info datum is specified as follows (CDDL): + +```cddl +big_int = int / big_uint / big_nint +big_uint = #6.2(bounded_bytes) +big_nint = #6.3(bounded_bytes) + +optional_big_int = #6.121([big_int]) / #6.122([]) + +royalty_recipient = #6.121([ + address, ; definition can be derived from: + ; https://github.com/input-output-hk/plutus/blob/master/plutus-ledger-api/src/PlutusLedgerApi/V1/Address.hs#L31 + int, ; variable fee ( calculation: ⌊1 / (fee / 10)⌋ ); integer division with precision 10 + optional_big_int, ; min fee (absolute value in lovelace) + optional_big_int, ; max fee (absolute value in lovelace) + ]) + +royalty_recipients = [ * royalty_recipient ] + +; version is of type int, we start with version 1 +version = 1 + +; Custom user defined plutus data. +; Setting data is optional, but the field is required +; and needs to be at least Unit/Void: #6.121([]) +extra = plutus_data + +royalty_info = #6.121([royalty_recipients, version, extra]) +``` + +##### Example of onchain variable fee calculation: +``` +; Given a royalty fee of 1.6% (0.016) + +; To store this in the royalty datum +1 / (0.016 / 10) => 625 + +; To read it back +10 / 625 => 0.016 +``` +Because the computational complexity of Plutus primitives scales with size, this approach significantly minimizes resource consumption. + +To prevent abuse, it is **recommended** that the `royalty NFT` is stored at the script address of a validator that ensures the specified fees are not arbitrarily changed, such as an always-fails validator. + +#### Retrieve metadata as 3rd party + +A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to lookup the royalties. The steps are + +1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)Royalty` +2. Look up `royalty NFT` and find the output it's locked in. +3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. +4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. + +#### Retrieve metadata from a Plutus validator + +We want to bring the royalty metadata of the NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` in the Plutus validator context. To do this we + +1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)Royalty` (off-chain) +2. Look up `royalty NFT` and find the output it's locked in. (off-chain) +3. Reference the output in the transaction. (off-chain) +4. Verify validity of datum of the referenced output by checking if policy ID of `royalty NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) + +### Rationale + +The specification here is made to be as minimal as possible. This is done with expediency in mind and the expectation that additional changes to the specification may be made in the future. The sooner we have a standard established, the sooner we can make use of it. Rather than attempting to anticipate all use cases, we specify with forward-compatibility in mind. + +## Backward Compatibility +To keep metadata compatibility with changes coming in the future, we introduce a `version` field in the datum. \ No newline at end of file From 304dcb099818e71c5f08ee4d83d802753600dee1 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Wed, 9 Aug 2023 17:37:21 -0700 Subject: [PATCH 10/28] reference datum flag spec Signed-off-by: samdelaney --- CIP-XXXX/ref_impl/README.md | 50 +++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/CIP-XXXX/ref_impl/README.md b/CIP-XXXX/ref_impl/README.md index 09bd818d1..ecc58c895 100644 --- a/CIP-XXXX/ref_impl/README.md +++ b/CIP-XXXX/ref_impl/README.md @@ -22,15 +22,7 @@ In addition, this standard allows royalties to be split between multiple address ## Specification -### Background - -This specification is largely based on [the royalty specification in Nebula](https://github.com/spacebudz/nebula/tree/main#royalty-info-specification), with a couple key departures: - -- The royalty token is recommended to be locked at a script address, rather than stored in the user's wallet. This encourages projects to guarantee royalties won't change by sending their royalties to an always-fails (or similar) script address, but still allows for creative royalty schemes and minimizes disruption to existing projects. - -- The policyId of the royalty NFT must match that of the reference NFT. This enables lookups based on the user token in the same way as is done for the tokens specified in the original CIP 68 standard. - -### 500 Royalty Standard +### 500 Royalty Datum Standard The following defines the `500` Royalty NFT standard with the registered `asset_name_label` prefix value @@ -52,7 +44,7 @@ Example:\ `royalty NFT`: `(500)Royalty`\ `reference NFT`: `(100)Test123` -#### Metadata +#### 500 Datum Metadata The royalty info datum is specified as follows (CDDL): @@ -84,7 +76,7 @@ extra = plutus_data royalty_info = #6.121([royalty_recipients, version, extra]) ``` -##### Example of onchain variable fee calculation: +#### Example of onchain variable fee calculation: ``` ; Given a royalty fee of 1.6% (0.016) @@ -98,6 +90,25 @@ Because the computational complexity of Plutus primitives scales with size, this To prevent abuse, it is **recommended** that the `royalty NFT` is stored at the script address of a validator that ensures the specified fees are not arbitrarily changed, such as an always-fails validator. +### Reference Datum Royalty Flag + +If not specified elsewhere in the token's datums, a malicious user could send transactions to a protocol which do not reference the royalty datum. For full assurances, a new optional flag should be added to the reference datum + +``` +extra = + { + ... + + ? royalty_included : big_int + } +``` + +- If the field is present and > 1 the validators must require a royalty input. +- If the field is present and set to 0 the validators don't need to search for a royalty input. +- If the field is not present, validators should accept a royalty input, but not require one. + +### Examples + #### Retrieve metadata as 3rd party A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to lookup the royalties. The steps are @@ -120,5 +131,22 @@ We want to bring the royalty metadata of the NFT `d5e6bf0500378d4f0da4e8dde6bece The specification here is made to be as minimal as possible. This is done with expediency in mind and the expectation that additional changes to the specification may be made in the future. The sooner we have a standard established, the sooner we can make use of it. Rather than attempting to anticipate all use cases, we specify with forward-compatibility in mind. +#### 500 Royalty Token Datum + +This specification is largely based on [the royalty specification in Nebula](https://github.com/spacebudz/nebula/tree/main#royalty-info-specification), with a couple key departures: + +- The royalty token is recommended to be locked at a script address, rather than stored in the user's wallet. This encourages projects to guarantee royalties won't change by sending their royalties to an always-fails (or similar) script address, but still allows for creative royalty schemes and minimizes disruption to existing projects. + +- The policyId of the royalty NFT must match that of the reference NFT. This enables lookups based on the user token in the same way as is done for the tokens specified in the original CIP 68 standard. + +#### Reference Datum Flag + +In addition to providing a way to create guaranteed royalties, this has several advantages: + +- Backwards Compatibility - Existing royalty implementations will still work, just not have the same assurances. +- Minimal Storage Requirement - An optional boolean has about the smallest memory impact possible. This is especially important because it's attached to the - Reference NFT and will be set for each individual NFT. +- Intra-Collection Utility - This already allows for minting a collection with some NFTs with royalties and some without. A future version of this standard will likely make use of this field to allow for multiple versions of royalties for even more granular control. + + ## Backward Compatibility To keep metadata compatibility with changes coming in the future, we introduce a `version` field in the datum. \ No newline at end of file From 689350399d08db658237b83623fe73a50dae4cb2 Mon Sep 17 00:00:00 2001 From: Sam Delaney Date: Wed, 9 Aug 2023 18:57:12 -0700 Subject: [PATCH 11/28] Fix leftover whitespace --- CIP-0068/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index bafacd6aa..e6a059bb5 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -329,7 +329,6 @@ We want to bring the metadata of the RFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8 3. Reference the output in the transaction. (off-chain) 4. Verify validity of datum of the referenced output by checking if policy ID of `reference NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) - ## Rationale Without seperation of `reference NFT` and `user token` you lose all flexibility and moving the `user token` would be quite cumbersome as you would need to add the metadata everytime to the new output where the `user token` is sent to. Hence you separate metadata and `user token` and lock the metadata inside another UTxO, so you can freely move the `user token` around. From fce05fc54da5270f5cd2e9f0ce7a0e4166e65fe9 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Mon, 21 Aug 2023 16:20:39 -0700 Subject: [PATCH 12/28] Path to Active & References --- CIP-XXXX/{ref_impl => }/README.md | 29 ++++++++++++++++++++++++++++- CIP-XXXX/ref_impl/TODO.md | 0 2 files changed, 28 insertions(+), 1 deletion(-) rename CIP-XXXX/{ref_impl => }/README.md (81%) create mode 100644 CIP-XXXX/ref_impl/TODO.md diff --git a/CIP-XXXX/ref_impl/README.md b/CIP-XXXX/README.md similarity index 81% rename from CIP-XXXX/ref_impl/README.md rename to CIP-XXXX/README.md index ecc58c895..ac452a858 100644 --- a/CIP-XXXX/ref_impl/README.md +++ b/CIP-XXXX/README.md @@ -149,4 +149,31 @@ In addition to providing a way to create guaranteed royalties, this has several ## Backward Compatibility -To keep metadata compatibility with changes coming in the future, we introduce a `version` field in the datum. \ No newline at end of file +To keep metadata compatibility with changes coming in the future, we introduce a `version` field in the datum. + + +## Path to Active + +### Acceptance Criteria + +- [ ] This CIP should receive feedback, criticism, and refinement from: CIP Editors and the community of people involved with NFT projects to review any weaknesses or areas of improvement. +- [ ] Guidelines and examples of publication of data as well as discovery and validation should be included as part of of criteria for acceptance. +- [ ] Minimal reference implementation making use of [Lucid](https://github.com/spacebudz/lucid) (off-chain), [PlutusTx](https://github.com/input-output-hk/plutus) (on-chain): [Reference Implementation](./ref_impl/) +- [ ] Implementation and use demonstrated by the community: NFT Projects, Blockchain Explorers, Wallets, Marketplaces. + +### Implementation Plan + +1. Publish open source reference implementation and instructions related to the creation, storage and reading of royalty utxos. +2. Implement in open source libraries and tooling such as [Lucid](https://github.com/spacebudz/lucid), [Blockfrost](https://github.com/blockfrost/blockfrost-backend-ryo), etc. +3. Achieve additional "buy in" from existing community actors and implementors such as: blockchain explorers, token marketplaces, minting platforms, wallets. + +## References + +- CIP-0027: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0027 +- CIP-0031: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0031 +- CIP-0067: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0067 +- CIP-0068: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068 + +## Copyright + +This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). \ No newline at end of file diff --git a/CIP-XXXX/ref_impl/TODO.md b/CIP-XXXX/ref_impl/TODO.md new file mode 100644 index 000000000..e69de29bb From 34089a1ca82aeac680f31be1395ba79e11df8280 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Mon, 21 Aug 2023 16:23:00 -0700 Subject: [PATCH 13/28] update CIP-67 registry entry --- CIP-0067/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0067/registry.json b/CIP-0067/registry.json index 7159abe3d..d93528b4f 100644 --- a/CIP-0067/registry.json +++ b/CIP-0067/registry.json @@ -22,6 +22,6 @@ { "asset_name_label": 500, "class": "NFT", - "description": "CIP-0068 - Datum Metadata Standard (500 sub standard)" + "description": "CIP-XXXX - Datum Metadata Standard (500 sub standard)" } ] From 357202f10f2a33d7dd12eba820cde5c47d057562 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Mon, 28 Aug 2023 17:11:22 -0700 Subject: [PATCH 14/28] changes per review --- CIP-XXXX/README.md | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/CIP-XXXX/README.md b/CIP-XXXX/README.md index ac452a858..72f29d9bb 100644 --- a/CIP-XXXX/README.md +++ b/CIP-XXXX/README.md @@ -1,6 +1,6 @@ --- -CIP: ???? -Title: Royalty Datum Metadata Standard +CIP: ? +Title: Royalty Datum Metadata Authors: Sam Delaney Comments-URI: Status: Proposed @@ -12,13 +12,13 @@ License: CC-BY-4.0 ## Abstract -This proposal makes use of the onchain metadata pattern established in CIP 68 to provide a way to store royalties with greater assurance and customizability. +This proposal makes use of the onchain metadata pattern established in [CIP-0068][] to provide a way to store royalties with greater assurance and customizability. ## Motivation -The inability to create trustless onchain royalty validation with CIP 27 is a major drawback to Cardano NFTs. The pattern defined in CIP 68 represents an opportunity to upgrade the standard to support onchain validation. This CIP aims to eliminate that drawback and demonstrate better support for developers, NFT creators, and NFT collectors, ultimately attracting dapps & NFT projects that would otherwise have taken their talents to another blockchain. +The inability to create trustless onchain royalty validation with [CIP-0027][] is a major drawback to Cardano NFTs. The pattern defined in CIP-68 represents an opportunity to upgrade the standard to support onchain validation. This CIP aims to eliminate that drawback and demonstrate better support for developers, NFT creators, and NFT collectors, ultimately attracting dapps & NFT projects that would otherwise have taken their talents to another blockchain. -In addition, this standard allows royalties to be split between multiple addresses, another limitation of the CIP 27 royalty schema. Future versions of this standard could also easily support multiple royalty policies defined for a single collection, applied at the level of individual tokens. +In addition, this standard allows royalties to be split between multiple addresses, another limitation of the CIP-27 royalty schema. Future versions of this standard could also easily support multiple royalty policies defined for a single collection, applied at the level of individual tokens. ## Specification @@ -38,7 +38,7 @@ The `royalty NFT` is an NFT (non-fungible token). The `royalty NFT` **must** have an identical `policy id` as the collection. -The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0067/README.md) label `500` followed by the word "Royalty". +The `asset name` **must** be `001f4d70526f79616c7479` (hex encoded), it contains the [CIP-0067][] label `500` followed by the word "Royalty". Example:\ `royalty NFT`: `(500)Royalty`\ @@ -111,11 +111,11 @@ extra = #### Retrieve metadata as 3rd party -A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to lookup the royalties. The steps are +A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` and they want to look up the royalties. The steps are 1. Construct `royalty NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(500)Royalty` 2. Look up `royalty NFT` and find the output it's locked in. -3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. +3. Get the datum from the output and look up metadata by going into the first field of constructor 0. 4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. #### Retrieve metadata from a Plutus validator @@ -137,7 +137,7 @@ This specification is largely based on [the royalty specification in Nebula](htt - The royalty token is recommended to be locked at a script address, rather than stored in the user's wallet. This encourages projects to guarantee royalties won't change by sending their royalties to an always-fails (or similar) script address, but still allows for creative royalty schemes and minimizes disruption to existing projects. -- The policyId of the royalty NFT must match that of the reference NFT. This enables lookups based on the user token in the same way as is done for the tokens specified in the original CIP 68 standard. +- The policyId of the royalty NFT must match that of the reference NFT. This enables lookups based on the user token in the same way as is done for the tokens specified in the original CIP-68 standard. #### Reference Datum Flag @@ -167,13 +167,10 @@ To keep metadata compatibility with changes coming in the future, we introduce a 2. Implement in open source libraries and tooling such as [Lucid](https://github.com/spacebudz/lucid), [Blockfrost](https://github.com/blockfrost/blockfrost-backend-ryo), etc. 3. Achieve additional "buy in" from existing community actors and implementors such as: blockchain explorers, token marketplaces, minting platforms, wallets. -## References - -- CIP-0027: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0027 -- CIP-0031: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0031 -- CIP-0067: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0067 -- CIP-0068: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068 - ## Copyright -This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). \ No newline at end of file +This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). + +[CIP-0027]: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0027 +[CIP-0067]: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0067 +[CIP-0068]: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068 \ No newline at end of file From 713aad552645adaf3e401d891e0167b6996c731b Mon Sep 17 00:00:00 2001 From: samdelaney Date: Tue, 29 Aug 2023 21:31:45 -0700 Subject: [PATCH 15/28] Update preamble to match CIP-0001 standard --- CIP-XXXX/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CIP-XXXX/README.md b/CIP-XXXX/README.md index 72f29d9bb..a50956f64 100644 --- a/CIP-XXXX/README.md +++ b/CIP-XXXX/README.md @@ -1,12 +1,13 @@ --- CIP: ? Title: Royalty Datum Metadata -Authors: Sam Delaney -Comments-URI: +Authors: + - Sam Delaney +Discussions: + - https://github.com/ikigai-github/CIPs/pull/1 Status: Proposed -Type: Informational +Category: Tokens Created: 2023-08-08 -Post-History: License: CC-BY-4.0 --- From 0041a7094b1ce9cb706fae7c201919f1d6f2c234 Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 5 Sep 2023 13:59:46 -0400 Subject: [PATCH 16/28] assigned 102 as CIP number --- CIP-XXXX/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CIP-XXXX/README.md b/CIP-XXXX/README.md index a50956f64..a51be9fac 100644 --- a/CIP-XXXX/README.md +++ b/CIP-XXXX/README.md @@ -1,5 +1,5 @@ --- -CIP: ? +CIP: 102 Title: Royalty Datum Metadata Authors: - Sam Delaney @@ -174,4 +174,4 @@ This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4 [CIP-0027]: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0027 [CIP-0067]: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0067 -[CIP-0068]: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068 \ No newline at end of file +[CIP-0068]: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068 From c51bc4a2e6d57775a308088798cd65ba739ca8e8 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Tue, 5 Sep 2023 14:54:13 -0700 Subject: [PATCH 17/28] move docs to new folder --- {CIP-XXXX => CIP-0102}/README.md | 2 +- {CIP-XXXX => CIP-0102}/ref_impl/TODO.md | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {CIP-XXXX => CIP-0102}/README.md (99%) rename {CIP-XXXX => CIP-0102}/ref_impl/TODO.md (100%) diff --git a/CIP-XXXX/README.md b/CIP-0102/README.md similarity index 99% rename from CIP-XXXX/README.md rename to CIP-0102/README.md index a50956f64..e82cab474 100644 --- a/CIP-XXXX/README.md +++ b/CIP-0102/README.md @@ -1,5 +1,5 @@ --- -CIP: ? +CIP: 102 Title: Royalty Datum Metadata Authors: - Sam Delaney diff --git a/CIP-XXXX/ref_impl/TODO.md b/CIP-0102/ref_impl/TODO.md similarity index 100% rename from CIP-XXXX/ref_impl/TODO.md rename to CIP-0102/ref_impl/TODO.md From 7725aafdd25805c0a3d241027877a2afa00feef9 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Tue, 5 Sep 2023 14:55:35 -0700 Subject: [PATCH 18/28] update registry entry --- CIP-0067/registry.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0067/registry.json b/CIP-0067/registry.json index d93528b4f..ea468b668 100644 --- a/CIP-0067/registry.json +++ b/CIP-0067/registry.json @@ -22,6 +22,6 @@ { "asset_name_label": 500, "class": "NFT", - "description": "CIP-XXXX - Datum Metadata Standard (500 sub standard)" + "description": "CIP-0102 - Datum Metadata Standard (500 sub standard)" } ] From 6d897eb60805a58a3e54821fe61284d5c5903764 Mon Sep 17 00:00:00 2001 From: SamDelaney Date: Wed, 6 Sep 2023 12:23:08 -0700 Subject: [PATCH 19/28] add registry documentation link --- CIP-0067/registry.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CIP-0067/registry.json b/CIP-0067/registry.json index ea468b668..f1af122dc 100644 --- a/CIP-0067/registry.json +++ b/CIP-0067/registry.json @@ -22,6 +22,7 @@ { "asset_name_label": 500, "class": "NFT", - "description": "CIP-0102 - Datum Metadata Standard (500 sub standard)" + "description": "CIP-0102 - Datum Metadata Standard (500 sub standard)", + "documentation": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0102" } ] From 4ecab236cc7ae9b6ef721946d82356022f02da0d Mon Sep 17 00:00:00 2001 From: Sam Delaney Date: Tue, 17 Oct 2023 09:51:04 -0700 Subject: [PATCH 20/28] Apply suggestions from code review Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index a51be9fac..28e7103cf 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -5,6 +5,7 @@ Authors: - Sam Delaney Discussions: - https://github.com/ikigai-github/CIPs/pull/1 + - https://github.com/cardano-foundation/CIPs/pull/551 Status: Proposed Category: Tokens Created: 2023-08-08 @@ -15,7 +16,7 @@ License: CC-BY-4.0 This proposal makes use of the onchain metadata pattern established in [CIP-0068][] to provide a way to store royalties with greater assurance and customizability. -## Motivation +## Motivation: why is this CIP necessary? The inability to create trustless onchain royalty validation with [CIP-0027][] is a major drawback to Cardano NFTs. The pattern defined in CIP-68 represents an opportunity to upgrade the standard to support onchain validation. This CIP aims to eliminate that drawback and demonstrate better support for developers, NFT creators, and NFT collectors, ultimately attracting dapps & NFT projects that would otherwise have taken their talents to another blockchain. @@ -128,7 +129,7 @@ We want to bring the royalty metadata of the NFT `d5e6bf0500378d4f0da4e8dde6bece 3. Reference the output in the transaction. (off-chain) 4. Verify validity of datum of the referenced output by checking if policy ID of `royalty NFT` and `user token` and their asset names without the `asset_name_label` prefix match. (on-chain) -### Rationale +## Rationale: how does this CIP achieve its goals? The specification here is made to be as minimal as possible. This is done with expediency in mind and the expectation that additional changes to the specification may be made in the future. The sooner we have a standard established, the sooner we can make use of it. Rather than attempting to anticipate all use cases, we specify with forward-compatibility in mind. @@ -149,7 +150,7 @@ In addition to providing a way to create guaranteed royalties, this has several - Intra-Collection Utility - This already allows for minting a collection with some NFTs with royalties and some without. A future version of this standard will likely make use of this field to allow for multiple versions of royalties for even more granular control. -## Backward Compatibility +### Backward Compatibility To keep metadata compatibility with changes coming in the future, we introduce a `version` field in the datum. @@ -159,7 +160,7 @@ To keep metadata compatibility with changes coming in the future, we introduce a - [ ] This CIP should receive feedback, criticism, and refinement from: CIP Editors and the community of people involved with NFT projects to review any weaknesses or areas of improvement. - [ ] Guidelines and examples of publication of data as well as discovery and validation should be included as part of of criteria for acceptance. -- [ ] Minimal reference implementation making use of [Lucid](https://github.com/spacebudz/lucid) (off-chain), [PlutusTx](https://github.com/input-output-hk/plutus) (on-chain): [Reference Implementation](./ref_impl/) +- [ ] Minimal reference implementation making use of [Lucid](https://github.com/spacebudz/lucid) (off-chain), [PlutusTx](https://github.com/input-output-hk/plutus) (on-chain): [Reference Implementation](./ref_impl/). - [ ] Implementation and use demonstrated by the community: NFT Projects, Blockchain Explorers, Wallets, Marketplaces. ### Implementation Plan From 2e7f21f93b8ecafa5900009527f707dfaa661ad9 Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 13:13:15 -0400 Subject: [PATCH 21/28] all header level fixes agreed at CIP meeting Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index 28e7103cf..6c1c3368f 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -133,7 +133,7 @@ We want to bring the royalty metadata of the NFT `d5e6bf0500378d4f0da4e8dde6bece The specification here is made to be as minimal as possible. This is done with expediency in mind and the expectation that additional changes to the specification may be made in the future. The sooner we have a standard established, the sooner we can make use of it. Rather than attempting to anticipate all use cases, we specify with forward-compatibility in mind. -#### 500 Royalty Token Datum +### 500 Royalty Token Datum This specification is largely based on [the royalty specification in Nebula](https://github.com/spacebudz/nebula/tree/main#royalty-info-specification), with a couple key departures: From d77752caa7dc712ebb680fc2ed5896a083cf9fbf Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 13:14:09 -0400 Subject: [PATCH 22/28] all header level fixes agreed at CIP meeting Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index 6c1c3368f..b62fe1cfc 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -141,7 +141,7 @@ This specification is largely based on [the royalty specification in Nebula](htt - The policyId of the royalty NFT must match that of the reference NFT. This enables lookups based on the user token in the same way as is done for the tokens specified in the original CIP-68 standard. -#### Reference Datum Flag +### Reference Datum Flag In addition to providing a way to create guaranteed royalties, this has several advantages: From ecf6b285367a28d0017ae509d276407926542a9e Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 13:15:33 -0400 Subject: [PATCH 23/28] agreed at meeting null implementors mandatory Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index b62fe1cfc..e9e323fee 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -3,6 +3,7 @@ CIP: 102 Title: Royalty Datum Metadata Authors: - Sam Delaney + Implementors: [] Discussions: - https://github.com/ikigai-github/CIPs/pull/1 - https://github.com/cardano-foundation/CIPs/pull/551 From 1a177b466c557cd71f5a387f49e195e000c5c67d Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 13:16:08 -0400 Subject: [PATCH 24/28] agreed at meeting to use tickboxes Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index e9e323fee..543ec6354 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -166,7 +166,7 @@ To keep metadata compatibility with changes coming in the future, we introduce a ### Implementation Plan -1. Publish open source reference implementation and instructions related to the creation, storage and reading of royalty utxos. +- [ ] Publish open source reference implementation and instructions related to the creation, storage and reading of royalty utxos. 2. Implement in open source libraries and tooling such as [Lucid](https://github.com/spacebudz/lucid), [Blockfrost](https://github.com/blockfrost/blockfrost-backend-ryo), etc. 3. Achieve additional "buy in" from existing community actors and implementors such as: blockchain explorers, token marketplaces, minting platforms, wallets. From f28f8c2082722238519c27561acb1c763d4742ad Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 13:16:45 -0400 Subject: [PATCH 25/28] agreed at meeting to use tickboxes Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index 543ec6354..ba4ef1e26 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -167,7 +167,7 @@ To keep metadata compatibility with changes coming in the future, we introduce a ### Implementation Plan - [ ] Publish open source reference implementation and instructions related to the creation, storage and reading of royalty utxos. -2. Implement in open source libraries and tooling such as [Lucid](https://github.com/spacebudz/lucid), [Blockfrost](https://github.com/blockfrost/blockfrost-backend-ryo), etc. +- [ ] Implement in open source libraries and tooling such as [Lucid](https://github.com/spacebudz/lucid), [Blockfrost](https://github.com/blockfrost/blockfrost-backend-ryo), etc. 3. Achieve additional "buy in" from existing community actors and implementors such as: blockchain explorers, token marketplaces, minting platforms, wallets. ## Copyright From 38a3146880312d9392e00ac3467690d47adff2df Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 13:17:03 -0400 Subject: [PATCH 26/28] agreed at meeting to use tickboxes Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index ba4ef1e26..b6ba8d4ee 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -168,7 +168,7 @@ To keep metadata compatibility with changes coming in the future, we introduce a - [ ] Publish open source reference implementation and instructions related to the creation, storage and reading of royalty utxos. - [ ] Implement in open source libraries and tooling such as [Lucid](https://github.com/spacebudz/lucid), [Blockfrost](https://github.com/blockfrost/blockfrost-backend-ryo), etc. -3. Achieve additional "buy in" from existing community actors and implementors such as: blockchain explorers, token marketplaces, minting platforms, wallets. +- [ ] Achieve additional "buy in" from existing community actors and implementors such as: blockchain explorers, token marketplaces, minting platforms, wallets. ## Copyright From 94805349476c2e7e7821ea95d6a74edcafed88a9 Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 14:44:43 -0400 Subject: [PATCH 27/28] adding `cddl` syntax tag pending eventual GitHub support Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index b6ba8d4ee..93d1908c8 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -80,7 +80,7 @@ royalty_info = #6.121([royalty_recipients, version, extra]) ``` #### Example of onchain variable fee calculation: -``` +```cddl ; Given a royalty fee of 1.6% (0.016) ; To store this in the royalty datum From 75eb324ee70fa4a66a92588dc1218991ded2affa Mon Sep 17 00:00:00 2001 From: Robert Phair Date: Tue, 17 Oct 2023 14:45:16 -0400 Subject: [PATCH 28/28] adding `cddl` syntax tag pending eventual GitHub support Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0102/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0102/README.md b/CIP-0102/README.md index 93d1908c8..37c843503 100644 --- a/CIP-0102/README.md +++ b/CIP-0102/README.md @@ -97,7 +97,7 @@ To prevent abuse, it is **recommended** that the `royalty NFT` is stored at the If not specified elsewhere in the token's datums, a malicious user could send transactions to a protocol which do not reference the royalty datum. For full assurances, a new optional flag should be added to the reference datum -``` +```cddl extra = { ...