Skip to content
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

CIP-0027 | Standardization of royalties #116

Merged
merged 11 commits into from
Nov 9, 2021
16 changes: 16 additions & 0 deletions CIP-0010/registry.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
[
{
"transaction_metadatum_label": 87,
"description": "milkomeda.com - The protocol magic for the milkomeda protocol"
},
{
"transaction_metadatum_label": 88,
"description": "milkomeda.com - the destination address in the sidechain"
},
{
"transaction_metadatum_label": 674,
"description": "CIP-0020 - Transaction message/comment metadata"
},
{
"transaction_metadatum_label": 721,
"description": "CIP-0025 - NFT Metadata Standard"
},
{
"transaction_metadatum_label": 777,
"description": "CIP-0027 - Royalties Standard"
},
{
"transaction_metadatum_label": 1967,
Expand Down
77 changes: 77 additions & 0 deletions CIP-0027/CIP-0027.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
CIP: 27
Title: CNFT Community Royalties Standard
Authors: Huth S0lo <[email protected]>, TheRealAdamDean <[email protected]>
Comments-URI: https://forum.cardano.org/t/cip-royalties/68599
Status: Draft
Type: Standards
Created: 2021-08-29
Version 1.1 - Changes pct tag to rate. Marketplaces to still honor legacy pct tag.
License: Apache-2.0
---

## Simple Summary

A community standard for royalties&#39; functionality, that does not require smart contracts to implement.

## Abstract

This proposed standard will allow for uniform royalties&#39; distributions across the secondary market space. It is easy to implement using metadata only, and does not require a smart contract. However, it is scalable to allow for the usage of a downstream smart contract, as needed by the asset creator. It has been developed with input from Artano, BuffyBot, CNFT.io, Digital Syndicate, Fencemaker, MADinArt, NFT-Maker.io, Hydrun, Tokhun, and many more.

## Motivation

There is a significant interest within the Cardano Community for an implementation of royalties distribution when a Cardano Asset is resold on the secondary market. It has become a common theme to see and hear statements that the only thing stopping artists from adopting Cardano, is that they are waiting for an implementation of royalties. At the present time, smart contracts do not create a simple mechanism to implement royalties. By developing a community standard, we can resolve the immediate need for royalties, and create a path forward for a potential future iteration of smart contracts.

## Specification

A new tag of 777 is proposed for this implementation. The community guidelines have been agreed as follows:
1) A brand new unused policy for implementation is required.
2) The royalties tags are to be written to an unnamed token, using the policy to be used for the intended Cardano Assets.
3) Only the first minted set of instructions will be honored. Any future updates or rewrites will be ignored. This prevents a Cardano Asset maker from changing the royalties at a future date.
4) Within this created asset will be the metadata for royalties distributions. It will use a tag of 777, and then have two tags to identify the percentage of future sales requested as a royalty, and the payment address to forward those royalties to. Those tags will be "rate" and "addr" respectively.
5) The "rate" key tag can be any floating point value from 0.0 to 1.0, to represent between 0 and 100 percent. For example, a 12.5 percent royalty would be represented with "rate": "0.125". Previous version 1.0 of this proposal used pct instead of rate. Marketplaces to continue to honor legacy pct tag.
6) The "addr" key tag can be a string value, or an array. It is to include a single payment address. By allowing for an array, the payment address can exceed the per line 64 character limitation. This payment address could be part of a smart contract, which should allow for greater flexibility of royalties distributions, controlled by the asset creator.
Copy link
Member

@KtorZ KtorZ Nov 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that in principle, an address is at most 59 bytes. The reason why addresses become a problem here is because of the choice to represent them as bech32-encoded strings. I reckon that JSON has been chosen here as it is quite human-readable but, I would argue that it doesn't have to be since the primary target of the metadata are programs, tools and services.

Hence alternatively, you could either:

  • Encode addresses as bytes. This is supported by various tools by prefixing the string with 0x and encoding the payload in hexadecimal. For instance, here

    {
      "777": {
        "rate": "0.2",
        "addr": "0x616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c"
      }
    }
  • Use the detailed schema for metadata, which can fully capture the on-chain format:

    { 
      "777": {
        "map": [
          { 
            "k": { "string": "rate" },
            "v": { "string": "0.2" } 
          },
          { 
            "k": { "string": "addr" },
            "V": { "bytes": "616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c" }
          }
        ]
      }
    }

Both results in the same binary data.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not enhance it further and implement

0.2: 616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c,
or laternatively 616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c: 0.2

we know that there are only percentages/rates, so no need to also add a string "rate"/"pct" and "addr". Saves us 7/8 bytes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not enhance it further and implement

0.2: 616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c, or laternatively 616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c: 0.2

we know that there are only percentages/rates, so no need to also add a string "rate"/"pct" and "addr". Saves us 7/8 bytes.

Removing the labels makes it less human friendly and makes it more difficult to extend in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that in principle, an address is at most 59 bytes. The reason why addresses become a problem here is because of the choice to represent them as bech32-encoded strings. I reckon that JSON has been chosen here as it is quite human-readable but, I would argue that it doesn't have to be since the primary target of the metadata are programs, tools and services.

Hence alternatively, you could either:

* Encode addresses as _bytes_. This is supported by various tools by prefixing the string with `0x` and encoding the payload in hexadecimal. For instance, here
  ```json
  {
    "777": {
      "rate": "0.2",
      "addr": "0x616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c"
    }
  }
  ```

* Use the detailed schema for metadata, which can fully capture the on-chain format:
  ```json
  { 
    "777": {
      "map": [
        { 
          "k": { "string": "rate" },
          "v": { "string": "0.2" } 
        },
        { 
          "k": { "string": "addr" },
          "V": { "bytes": "616796190577269c59e85fae13708fcfe602211fde63cd7e339d01444c" }
        }
      ]
    }
  }
  ```

Both results in the same binary data.

Where does the 64 character limit come from?
Can it be increased or removed?
If standards are being created with hacks like concatenating array elements, which makes it harder to understand for people and machines, it seems there is a strong case to increase or remove the limit.

7) The royalty token must be minted prior to creating any assets off the policy. All markets will be instructed to look only for the first minted asset on a policy, which would need to be the unnamed 777 token.

## Example JSON with string

{
"777": {
"rate": "0.2",
"addr": "addr1v9nevxg9wunfck0gt7hpxuy0elnqygglme3u6l3nn5q5gnq5dc9un"
}
}

## Example JSON with array

{
"777": {
"rate": "0.2",
"addr": [
"addr1q8g3dv6ptkgsafh7k5muggrvfde2szzmc2mqkcxpxn7c63l9znc9e3xa82h",
"pf39scc37tcu9ggy0l89gy2f9r2lf7husfvu8wh"
]
}
}

## Process Flow
1) Create policy for planned assets.
2) Mint no name token with community standard royalties metadata.
3) Burn no name token to free up UTxO (recommended, but not required).
4) Mint planned assets using this same policy.

## Rationale

By creating a new tag for the distinct purpose of royalties distributions, Cardano Asset makers, and Marketplaces can uniformly apply royalties to assets with predictable results. By creating the instructions on a single, no name token, all marketplaces will know the correct location of the royalties asset, without having to further locate it. By enforcing the requirement of honoring only the first mint, cardano asset buyers and owners can predict the future resale value of the assets in their possession. The solution is scalable to any desired royalty percentage. It is easy to work with this new standard, and does not require an in depth understanding of smart contracts.

## Change Log

## Initial proposal - August 14th, 2021
## Revised proposal - August 28th, 2021
## Minor Revision - August 31st, 2011
## Minor Revision - September 27th, 2021
## Minor Revision - November 8th, 2021
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changelog section seems redundant with git here. If there's really a strong will to keep it, then I would recommend to not use h2 (##) titles which are unnecessarily big, but instead resort to a list of bullet points or use a somewhat standardize format such as keep-a-changelog


Copyright

This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode)