diff --git a/CIP-0060/README.md b/CIP-0060/README.md index 3129db308..f8bb4fdf6 100644 --- a/CIP-0060/README.md +++ b/CIP-0060/README.md @@ -11,7 +11,7 @@ License: CC-BY-4.0 # Abstract -This proposal defines an extension to CIP-25 for token metadata specific to music tokens. +This proposal defines an extension to CIP-25 and CIP-68 for token metadata specific to music tokens. # Motivation @@ -21,13 +21,17 @@ Music tokens on Cardano can be either NFTs or FTs and contain links to audio fil This CIP divides the additional metadata parameters into two categories of `Required` and `Optional`. When minting a music token on Cardano, you are expected to include ALL of the required fields. If you choose to include one or more of the optional fields, they must be named exactly as defined in this CIP. This will properly allow indexing apps and music players to utilize as much of your token metadata as possible without issues. -[CDDL Spec Version 1](cddl/version-1.cddl) +[CDDL Spec Version 2](cddl/version-2.cddl) +[CDDL Spec Version 1 (deprecated)](cddl/version-1.cddl) + +## Summary of v2 Changes ## +In version 2 of the CIP-60 spec, `album_title` has been renamed to `release_title`. `release` is a more generic name that covers all types of releases from Albums, EPs, LPs, Singles, and Compilations. At the top level, we are grouping those metadata items that relate to the release under a new key `release`. At the file for each song, there is a new `song` key that holds the metadata specific to the individual song. These changes separate the music-specific metadata from the general CIP-25/CIP-68 NFT metadata. A music player can look at just the information necessary instead of having to ignore extra NFT-related fields. CIP-68 NFTs are officially supported and an example specific to CIP-68 has been added below. ## Required Fields ### | Field | Type | Example(s) | Notes | | -------- | -------- | -------- | -------- | | artists | Array\ | "artists": [
{ "name": "Stevie Nicks" },
{ "name": "Tom Petty" }
] | | -| album_title| String | "album_title": "Mr. Bad Guy" | | +| release_title| String | "release_title": "Mr. Bad Guy" | | | track_number | Integer | "track_number": 1 | | | song_title | String \| Array\ | "song_title": "Let's Turn it On" | | | song_duration | String | "song_duration": "PT3M21S" | ISO8601 Duration Format | @@ -53,6 +57,7 @@ This CIP divides the additional metadata parameters into two categories of `Requ | publication_date | String | "publication_date": "2022-07-27" | ISO8601 Date Format | | catalog_number | Integer | "catalog_number": 2 | | | bitrate | String | "bitrate": "256 kbit/s" | | +| bpm | String | "bpm": "120 BPM" | | | mix_engineer | String | "mix_engineer": "Robert Smith II" | | | mastering_engineer | String | "mastering_engineer": "Michael Tyson" | | | producer | String | "producer": "Simon Cowell" | | @@ -86,46 +91,50 @@ This CIP divides the additional metadata parameters into two categories of `Requ { "name": "SickCity354-Phil z'viel", "image": "ipfs://QmQ13Cv9Wouf4rcwtNsuFhEeJVK9bEYjCYo6AN986takiu", - "music_metadata_version": 1, - "release_type": "Single", - "album_title": "C.H.I.L.L.", - "song_title": "C.H.I.L.L.", - "song_duration": "PT3M6S", - "track_number": 1, - "mood": "chillout", - "artists": - [ - { "name": "Phil z'viel" } - ], - "collection": "C.H.I.L.L.", - "genres": - [ - "Guitar Live Looping", - "Progressive Ambient" - ], - "copyright": "℗ 2022 Phil z'viel", - "distributor": "https://sickcity.xyz", + "music_metadata_version": 2, + "release": { + "release_type": "Single", + "release_title": "C.H.I.L.L.", + "distributor": "https://sickcity.xyz" + } "files": [ { "name": "C.H.I.L.L.", "mediaType": "audio/mp3", "src": "ipfs://QmfY4ugNdYYJxpbn5BnN8yt5EmiUCznexQoQi6RTEu9SuC" + "song": { + "song_title": "C.H.I.L.L.", + "song_duration": "PT3M6S", + "track_number": 1, + "mood": "chillout", + "artists": + [ + { "name": "Phil z'viel" } + ], + "collection": "C.H.I.L.L.", + "genres": + [ + "Guitar Live Looping", + "Progressive Ambient" + ], + "copyright": "℗ 2022 Phil z'viel", + "links": + { + "discord_user": "Phil z'viel#4711", + "twitter": "@Phil_zviel_CNFT", + "website": "www.philzvielcnft.com" + } + } } ], - "links": - { - "discord_user": "Phil z'viel#4711", - "twitter": "@Phil_zviel_CNFT", - "website": "www.philzvielcnft.com" - } } } } } ``` -### Album ### +### Multiple ### ``` { @@ -137,8 +146,18 @@ This CIP divides the additional metadata parameters into two categories of `Requ "image": "ipfs://QmUBLXPgJM6oSeybv7FB15kQzbZtzPXifk9fJhLVcbCjVh", "mediaType": "image/webp", "version": 1, - "music_metadata_version": 1, - "release_type": "Multiple", + "music_metadata_version": 2, + "release": { + "release_type": "Multiple", + "release_title": "Studio Life", + "producer": "Jamison Daniel", + "distributor": "Jamison Daniel Music", + "visual_artist": "Jamison Daniel", + "links": { + "twitter": "@JamisonDMusic", + "website": "jamisondaniel.com" + } + }, "attributes": { "Collection": "Basic", @@ -155,171 +174,117 @@ This CIP divides the additional metadata parameters into two categories of `Requ "name": "Finally (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://QmduC7pkR14K3mhmvEazoyzGsMWVF4ji45HZ1XfEracKLv", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 1, - "song_title": "Finally (Master 2021)", - "song_duration": "PT6M36S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 1, + "song_title": "Finally (Master 2021)", + "song_duration": "PT6M36S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "Funky Squirrel (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://QmW9sHugSArzf29JPuEC2MqjtbsNkDjd9xNUxZFLDXSDUY", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 2, - "song_title": "Funky Squirrel (Master 2021)", - "song_duration": "PT6M47S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 2, + "song_title": "Funky Squirrel (Master 2021)", + "song_duration": "PT6M47S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "Weekend Ride (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://Qmb8fm7CkzscjjoJGVp3p7qjSVMknsk27d3cwjqM26ELVB", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 3, - "song_title": "Weekend Ride (Master 2021)", - "song_duration": "PT6M39S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 3, + "song_title": "Weekend Ride (Master 2021)", + "song_duration": "PT6M39S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "Rave Culture (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://QmTwvwpgE9Fx6QZsjbXe5STHb3WVmaDuxFzafqCPueCmqc", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 4, - "song_title": "Rave Culture (Master 2021)", - "song_duration": "PT6M39S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 4, + "song_title": "Rave Culture (Master 2021)", + "song_duration": "PT6M39S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "Vibrate (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://QmTETraR8WvExCaanc5aGT8EAUgCojyN8YSZYbGgmzVfja", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 5, - "song_title": "Vibrate (Master 2021)", - "song_duration": "PT6M51S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 5, + "song_title": "Vibrate (Master 2021)", + "song_duration": "PT6M51S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "Top 40's (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://Qmdfr4PvuiZhi3a6EaDupGN6R33PKSy5kntwgFEzLQnPLR", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 6, - "song_title": "Top 40's (Master 2021)", - "song_duration": "PT6M33S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 6, + "song_title": "Top 40's (Master 2021)", + "song_duration": "PT6M33S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "Acid Trip (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://QmSp4Cn7qrhLTovezS1ii7ct1VAPK6Gotd2GnxnBc6ngSv", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 7, - "song_title": "Acid Trip (Master 2021)", - "song_duration": "PT6M7S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 7, + "song_title": "Acid Trip (Master 2021)", + "song_duration": "PT6M7S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "For The Win (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://QmV8ihv8R6cCKsFJyFP8fhnnQjeKjS7HAAjmxMgUPftmw6", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 8, - "song_title": "For The Win (Master 2021)", - "song_duration": "PT6M36S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 8, + "song_title": "For The Win (Master 2021)", + "song_duration": "PT6M36S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } }, { "name": "Sunday Sermon (Master 2021)", "mediaType": "audio/flac", "src": "ipfs://QmWux5UpX6BtYQ7pjugqRh6ySa2vVJN12iSC2AB1cAQynU", - "artists": [{"name": "Jamison Daniel"}], - "album_title": "Studio Life", - "track_number": 9, - "song_title": "Sunday Sermon (Master 2021)", - "song_duration": "PT5M13S", - "genres": ["electronic", "house"], - "copyright": "Jamison Daniel © 2021", - "visual_artist": "Jamison Daniel", - "producer": "Jamison Daniel", - "publisher": "Jamison Daniel Music", - "links": { - "twitter": "@JamisonDMusic", - "website": "jamisondaniel.com" + "song": { + "artists": [{"name": "Jamison Daniel"}], + "track_number": 9, + "song_title": "Sunday Sermon (Master 2021)", + "song_duration": "PT5M13S", + "genres": ["electronic", "house"], + "copyright": "Jamison Daniel © 2021" } } ] @@ -328,6 +293,88 @@ This CIP divides the additional metadata parameters into two categories of `Requ } ``` +### CIP-68 Single ### + +``` +{ + "constructor": 0, + "fields": [ + { + "map": [ + {"k": {"bytes": "6E616D65"}, "v": {"bytes": "5369636B436974793335342D5068696C207A277669656C"}}, + {"k": {"bytes": "696D616765"}, "v": {"bytes": "697066733A2F2F516D513133437639576F756634726377744E7375466845654A564B396245596A43596F36414E39383674616B6975"}}, + {"k": {"bytes": "6D757369635F6D657461646174615F76657273696F6E"}, "v": {"int": 2}}, + {"k": {"bytes": "72656C656173655F74797065"}, "v": {"bytes": "53696E676C65"}}, + {"k": {"bytes": "72656c65617365"}, "v": + { + "map": [ + {"k": {"bytes": "72656c656173655f7469746c65"}, "v": {"bytes": "432e482e492e4c2e4c2e"}}, + {"k": {"bytes": "6469737472696275746f72"}, "v": {"bytes": "68747470733a2f2f7369636b636974792e78797a"}}, + ] + } + }, + {"k": {"bytes": "66696C6573"}, "v": + { + "array": [ + { + "map": [ + {"k": {"bytes": "6e616d65"}, "v": {"bytes": "432e482e492e4c2e4c2e"}}, + {"k": {"bytes": "6d6564696154797065"}, "v": {"bytes": "617564696f2f6d7033"}}, + {"k": {"bytes": "737263"}, "v": {"bytes": "697066733a2f2f516d66593475674e6459594a7870626e35426e4e38797435456d6955437a6e6578516f5169365254457539537543"}}, + {"k": {"bytes": "736f6e67"}, "v": + { + "map": [ + {"k": {"bytes": "736f6e675f7469746c65"}, "v": {"bytes": "432e482e492e4c2e4c2e"}}, + {"k": {"bytes": "736f6e675f6475726174696f6e"}, "v": {"bytes": "5054334d3653"}}, + {"k": {"bytes": "747261636b5f6e756d626572"}, "v": {"int": 1}}, + {"k": {"bytes": "6d6f6f64"}, "v": {"bytes": "6368696c6c6f7574"}}, + {"k": {"bytes": "61727469737473"}, "v": + { + "array": [ + { + "map": [ + {"k": {"bytes": "6e616d65"}, "v": {"bytes": "5068696c207a277669656c"}}, + ] + } + ] + } + }, + {"k": {"bytes": "636f6c6c656374696f6e"}, "v": {"bytes": "432e482e492e4c2e4c2e"}}, + {"k": {"bytes": "67656e726573"}, "v": + { + "array": [ + {"bytes": "477569746172204c697665204c6f6f70696e67"}, + {"bytes": "50726f677265737369766520416d6269656e74"}, + ] + } + }, + {"k": {"bytes": "636f70797269676874"}, "v": {"bytes": "2117 2032303232205068696c207a277669656c"}}, + {"k": {"bytes": "6c696e6b73"}, "v": + { + "map": [ + {"k": {"bytes": "646973636f72645f75736572"}, "v": {"bytes": "5068696c207a277669656c2334373131"}}, + {"k": {"bytes": "74776974746572"}, "v": {"bytes": "405068696c5f7a7669656c5f434e4654"}}, + {"k": {"bytes": "77656273697465"}, "v": {"bytes": "7777772e7068696c7a7669656c636e66742e636f6d"}} + ] + }} + ] + } + } + + ] + } + ] + } + }, + ] + }, + { + "int": 1 + } + ] +} +``` + # Rationale Implementing this simplifies and commonizes the process for creating music tokens on Cardano. It greatly simplifies the work that apps have to make when consuming such tokens. diff --git a/CIP-0060/cddl/version-2.cddl b/CIP-0060/cddl/version-2.cddl new file mode 100644 index 000000000..33a2193b6 --- /dev/null +++ b/CIP-0060/cddl/version-2.cddl @@ -0,0 +1,103 @@ +string = text .size (0..64) + +policy_id = string / bytes ; hex string for CIP-25 version 1, bytes version 2 +asset_name = string / bytes ; utf-8 for CIP-25 version 1, bytes for version 2 + +artist_details = + { + name : string, ; artist or band name + ? image : string / [* string], ; optional image of the artist + } + +release_details = + { + ? release_title : string, + ? copyright: string, + + ? visual_artist: string, + ? distributor: string, + ? release_date: string, + ? publication_date: string, + ? catalog_number: uint, + ? release_version: uint, + ? producer: string, + ? co_producer: string, + ? distributor: string, + ? metadata_language: string, + ? country_of_origin: string, + ? language: string, + ? links: { * string => string / [* string] }, + } + +song_details = + { + ; For Single, some of these values are defined at the top level. For Multiple, define them for each track. + ? artists : [* artist_details], + ? track_number: uint, + ? song_title: string / [* string], + ? song_duration: string .regexp "^P(?!$)(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)$", ; iso8601 duration + ? genres: [1*3 string], + ? copyright: string, + + ; For Single, some of these values are defined at the top level. For Multiple, optionally define them for each track + ? contributing_artists : [* artist_details], + ? series: string, + ? collection: string, + ? set: string, + ? mood: string, + ? lyrics: string, + ? lyricists: [* string], + ? special_thanks: [* string], + ? visual_artist: string, + ? distributor: string, + ? release_date: string, + ? publication_date: string, + ? catalog_number: uint, + ? bitrate: string, + ? bpm: string, + ? mix_engineer: string, + ? mastering_engineer: string, + ? producer: string, + ? co_producer: string, + ? featured_artist: artist_details, + ? recording_engineer: string, + ? release_version: uint, + ? parental_advisory: string, + ? explicit: bool, + ? isrc: string, + ? iswc: string, + ? ipi: [* string], + ? ipn: [* string], + ? isni: [* string], + ? metadata_language: string, + ? country_of_origin: string, + ? language: string, + ? derived_from: string, + ? links: { * string => string / [* string] }, + } + +files_details = + { + name : string, + mediaType : string, + src : string / [* string], + song : song_details, ; song music_metadata that applies to the track. + } + +metadata_details = + { + name : string, + image : string / [* string], + music_metadata_version: 2, ; v2 update moves music metadata under its own music_metadata section. + release_type: "Single" / "Multiple", + release: release_details, ; top-level music metadata that applies to the whole album. + + files : [* files_details], ; was optional in CIP-25, required by CIP-60 + ? version: 1 / 2, ; CIP-25 version + ? mediaType : string, ; mediaType for the image. audio goes under files. + ? description : string / [* string], + } + +label_metadata = { * policy_id => { * asset_name => metadata_details } } + +metadata = { 721 : uint => label_metadata } \ No newline at end of file