From 7a8cc21228547661784c4d2e623caca4b65b1439 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Tue, 18 Oct 2022 15:36:15 +0100 Subject: [PATCH 01/63] Initial draft for dapp registration certificate spec --- CIP-0072/README.md | 107 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 CIP-0072/README.md diff --git a/CIP-0072/README.md b/CIP-0072/README.md new file mode 100644 index 0000000000..8b53350e5b --- /dev/null +++ b/CIP-0072/README.md @@ -0,0 +1,107 @@ +--- +CIP: 72 +Title: Cardano DApp Registration +Authors: Bruno Martins +Status: Draft +Type: Standards +Created: 2022-10-18 +License: CC-BY-4.0 +--- + +## **Abstract** +DApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developers needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by the dApp developer. + +This proposal aims to standardise the process of dApp registration and verification, and to provide a set of claims that dApp developers can use to register their dApp(s). + +## **Motivation** +DApps can express a plethora of information. Some of this information could be claims about who the developer is, what is the dApp's associated metadata are, and more. This data lacks standarisation, persistence, and immutabulity. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. + +Also having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. + +## **Specification** + +### **On-chain dApp Registration certificate** + +```json +{ + "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", + "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", + "cip26": ["http://somelocation.io/", "http://somelocation2.io/"], + "did": "did:prism:f2019bd31a8530fb67c6d81da758dfa9a65be09d835cf2cd361d595a8858301d", + "signature": { + "r": "5114674f1ce8a2615f2b15138944e5c58511804d72a96260ce8c587e7220daa90b9e65b450ff49563744d7633b43a78b8dc6ec3e3397b50080", + "s": "a15f06ce8005ad817a1681a4e96ee6b4831679ef448d7c283b188ed64d399d6bac420fadf33964b2f2e0f2d1abd401e8eb09ab29e3ff280600", + "algo": "Ed25519−EdDSA", + "pub": "b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde" + } +} +``` + +### Properties +*`subject`*: Identifier of the claim subject (i.e dapp). A UTF-8 encoded string. This uniquess of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. This can be done by knowning verifying the signature against a trusted / known public key or by using Decentralized Identifiers (DIDs) as described in the [DID Specification](https://www.w3.org/TR/did-core/). + +*`rootHash`*: The hash of the metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. + +*`cip26`*: An array of URLs that point to the location of the dApp's metadata. The client should try to fetch the metadata from the first URL in the array. If the client fails to fetch the metadata from the first URL, it should try the second URL, and so on. If the client fails to fetch the metadata from all URLs, it should consider the metadata to be invalid. + +The format of the metadata tree object is described in the [CIP-26](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026) specification. + +*`did`*(optional): The DID of the dApp's developer. The DID is used to verify the authenticity of the certificate. The client should use the DID to fetch the developer's public key from the Cardano blockchain. The client should then use the public key to verify the signature of the certificate. This field is *optional* and can be used by identity centric dApps to verify the authenticity of the developer. + +*`signature`*: The signature of the certificate. The signature is done over the blake2b hash of the certificate. The client should use the public key to verify the signature of the certificate. If a DID is provided, the client should use the DID to fetch the developer's public from the DID Document. If a DID is not provided, the client should use the public key provided in the signature object or from a already known public key. + +## Certificate JSON Schema +```json +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "rootHash": { + "type": "string" + }, + "cip26": { + "type": "array", + "items": [ + { + "type": "string" + } + ] + }, + "did": { + "type": "string" + }, + "signature": { + "type": "object", + "properties": { + "r": { + "type": "string" + }, + "s": { + "type": "string" + }, + "algo": { + "type": "string" + }, + "pub": { + "type": "string" + } + }, + "required": [ + "r", + "s", + "algo", + "pub" + ] + } + }, + "required": [ + "subject", + "rootHash", + "cip26", + "signature" + ] +} +``` \ No newline at end of file From c8939a1c7d7c7542bb14ca8e75f80208451b65fb Mon Sep 17 00:00:00 2001 From: ehanoc Date: Wed, 19 Oct 2022 15:38:11 +0100 Subject: [PATCH 02/63] Init Draft CPS-0001 --- CPS-0001/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 CPS-0001/README.md diff --git a/CPS-0001/README.md b/CPS-0001/README.md new file mode 100644 index 0000000000..0889fe9bef --- /dev/null +++ b/CPS-0001/README.md @@ -0,0 +1,39 @@ +--- +CPS: 1 +Title: DApps Metadata Registration, Discovery and Trust +Authors: Bruno Martins +Status: Proposed +Type: Standards +Category: Wallets | Metadata | Plutus +Proposed Solutions: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026, +https://github.com/cardano-foundation/CIPs/pull/355 +Created: 2022-19-10 +--- + +## **Abstract** +This document attempts to describe the problem in the cardano ecocystem where there are many different types of applications being developed and there's a need to associate metadata with them. This metadata can be used to describe the application, its purpose, its version, its author, which scripts it uses, certifications and information about it's developer or publisher. This metadata can be used to provide information to the user about the application and its trustworthiness. This metadata can also be used to provide information to the wallet about the application and how to interact with it. + +## **Goals** +- Uncensorable and decentralized metadata registration +- Define how metadata can be associated with the a subject (i.e dapp) +- Define how a DApp metadata can be registered in the ecosystem for the purpose of discovery (i.e dapp stores) +- Associate some form of identity to the metadata claim +- Provide standard for certification of the dapp metadata claim, scripts and code +- Offer a trust model for the wallets to make an informed decision wheter to trust a dapp or not +- Standard to find metadata for a given subject (dapp, script, etc) + +## **Problem** +**`Dapp Discovery`**: There's no standard way to discover dapps in the ecosystem. A Dapp being a collection of scripts and metadata, a dapp store for instance has no defined mechanism to index a "dapp publication" claim. This claim can be made by the dapp developer or by a third party. The dapp store can then use this claim to index the dapp and make it available for the user to browse. + +**`Certification`**: Any actor of the ecosystem may see other actors as more trustworthy than others. Metadata certification can be used to provide a way for the user to make an informed decision about the trustworthiness of the dapp and it's provided information. This claim can be made by a third party, such as a dapp store, a auditor, a known developer, a community member, etc. The certification claim can be used to provide a trust model for the wallet to make an informed decision about the trustworthiness of the dapp. + +**`Identity`**: In order to anchor some form of trust to the dapp metadata claim, there's a need to associate some form of identity to it's publisher. This should be cryptographically verifiable. + +**`Verify correctness of metadata`**: For a given metadata structure we need to be able to verify that the metadata is correct in it's structure and that the data is correct. Given the uncensorable nature and goal for a healthy ecosystem, there can be multiple claims against the same subject and the concept of "correct" is therefore subjective and should be attached in some way to the *identity* of the publisher. + +**`Metadata discovery`**: When provided with specific pieces of information such as script addresses, we need to be able to find the metadata associated with it. This is useful for the wallet to be able to provide the user with information about the dapp, other related scripts and potential certifications or identity information about parties that made claims about that subject. + +## **Open Questions** +- Is this a combination of problems and should be split into multiple CPS? +- Does this englobes all the problems related to dapp metadata? +- Is this just a problem for dapps or should this be more generic? \ No newline at end of file From 9a5e5c13520a1a5922b391a90498d4012185b64f Mon Sep 17 00:00:00 2001 From: ehanoc Date: Mon, 24 Oct 2022 13:54:22 +0100 Subject: [PATCH 03/63] Add Use Cases, improve descriptions --- CPS-0001/README.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/CPS-0001/README.md b/CPS-0001/README.md index 0889fe9bef..c851f1a762 100644 --- a/CPS-0001/README.md +++ b/CPS-0001/README.md @@ -1,26 +1,34 @@ --- CPS: 1 -Title: DApps Metadata Registration, Discovery and Trust +Title: Metadata Discoverability and Trust Authors: Bruno Martins Status: Proposed Type: Standards Category: Wallets | Metadata | Plutus Proposed Solutions: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026, -https://github.com/cardano-foundation/CIPs/pull/355 +https://github.com/cardano-foundation/CIPs/pull/355, +https://github.com/cardano-foundation/CIPs/pull/85, +https://github.com/cardano-foundation/CIPs/pull/112, +https://github.com/cardano-foundation/CIPs/pull/137, +https://github.com/cardano-foundation/CIPs/pull/299 Created: 2022-19-10 --- ## **Abstract** -This document attempts to describe the problem in the cardano ecocystem where there are many different types of applications being developed and there's a need to associate metadata with them. This metadata can be used to describe the application, its purpose, its version, its author, which scripts it uses, certifications and information about it's developer or publisher. This metadata can be used to provide information to the user about the application and its trustworthiness. This metadata can also be used to provide information to the wallet about the application and how to interact with it. +This document attempts to describe the problem in the Cardano ecocystem where there are many different types **subjects** or *chain entities* and there's a need to associate metadata with them. This metadata can be used to describe an script, stake pools, script hashes, token policies and applications. This metadata can be used to provide information to the user on it's applications, it's trustworthiness and how to interact with it. ## **Goals** -- Uncensorable and decentralized metadata registration -- Define how metadata can be associated with the a subject (i.e dapp) -- Define how a DApp metadata can be registered in the ecosystem for the purpose of discovery (i.e dapp stores) -- Associate some form of identity to the metadata claim -- Provide standard for certification of the dapp metadata claim, scripts and code -- Offer a trust model for the wallets to make an informed decision wheter to trust a dapp or not -- Standard to find metadata for a given subject (dapp, script, etc) +- Define how metadata can be associated with the a subject (i.e dapp, stake pool, token policy, etc) +- Metadata should be discoverable by wallets and applications +- Associate some form of identity to a metadata claim + +## **Use Cases** +- Find scripts used by a dApp +- Discover general information of a dApp (i.e name, description, icons, etc) +- Find the different metadata claims associated with a subject +- Associate some form of identity to a metadata claim owner that can be verified cryptographically +- Offer mechanism to attest for the correctness of a given metadata object that can be fetched by wallets and applications from off-chain sources (i.e CIP-26 complaint servers) +- Discover datum schemas used by a script in a specific context or dApp use cases ## **Problem** **`Dapp Discovery`**: There's no standard way to discover dapps in the ecosystem. A Dapp being a collection of scripts and metadata, a dapp store for instance has no defined mechanism to index a "dapp publication" claim. This claim can be made by the dapp developer or by a third party. The dapp store can then use this claim to index the dapp and make it available for the user to browse. From d5b5dee7f5472fc5f85c7faae8a451a086a35229 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Mon, 24 Oct 2022 14:38:45 +0100 Subject: [PATCH 04/63] Typo --- CPS-0001/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPS-0001/README.md b/CPS-0001/README.md index c851f1a762..7dae756e5b 100644 --- a/CPS-0001/README.md +++ b/CPS-0001/README.md @@ -26,7 +26,7 @@ This document attempts to describe the problem in the Cardano ecocystem where th - Find scripts used by a dApp - Discover general information of a dApp (i.e name, description, icons, etc) - Find the different metadata claims associated with a subject -- Associate some form of identity to a metadata claim owner that can be verified cryptographically +- Associate some form of identity to a claim's owner so that it can be verified cryptographically - Offer mechanism to attest for the correctness of a given metadata object that can be fetched by wallets and applications from off-chain sources (i.e CIP-26 complaint servers) - Discover datum schemas used by a script in a specific context or dApp use cases From d014e59186aa4d1ab5b4cee5a4b31ba5842cb59c Mon Sep 17 00:00:00 2001 From: ehanoc Date: Mon, 24 Oct 2022 15:28:40 +0100 Subject: [PATCH 05/63] Generalizing CPS, simplifying problems and use cases. Add open questions --- CPS-0001/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CPS-0001/README.md b/CPS-0001/README.md index 7dae756e5b..532a895ced 100644 --- a/CPS-0001/README.md +++ b/CPS-0001/README.md @@ -29,19 +29,19 @@ This document attempts to describe the problem in the Cardano ecocystem where th - Associate some form of identity to a claim's owner so that it can be verified cryptographically - Offer mechanism to attest for the correctness of a given metadata object that can be fetched by wallets and applications from off-chain sources (i.e CIP-26 complaint servers) - Discover datum schemas used by a script in a specific context or dApp use cases +- An wallet receiving a request to connect to a dApp, it can verify the authenticity of the dApp and the metadata associated with it. ## **Problem** -**`Dapp Discovery`**: There's no standard way to discover dapps in the ecosystem. A Dapp being a collection of scripts and metadata, a dapp store for instance has no defined mechanism to index a "dapp publication" claim. This claim can be made by the dapp developer or by a third party. The dapp store can then use this claim to index the dapp and make it available for the user to browse. +**`Discoverability`**: Means to discover the different metadata claims associated with a subject. Discoverability is important for wallets, applications (i.e dapps, stores, etc) and users to be able to find the different metadata claims associated with a subject. This is important for the user to be able to make an informed decision on how to interact with a subject. -**`Certification`**: Any actor of the ecosystem may see other actors as more trustworthy than others. Metadata certification can be used to provide a way for the user to make an informed decision about the trustworthiness of the dapp and it's provided information. This claim can be made by a third party, such as a dapp store, a auditor, a known developer, a community member, etc. The certification claim can be used to provide a trust model for the wallet to make an informed decision about the trustworthiness of the dapp. +**`Correctness`**: Lack of mechanism to assert that a given metadata claim is correct. Anybody and any service can provide metadata structures, but it's necessary to attest for the correctness of this metadata so that the user (or applications) are be able to make an informed decision in accepting, rejecting or how to interact with a subject. -**`Identity`**: In order to anchor some form of trust to the dapp metadata claim, there's a need to associate some form of identity to it's publisher. This should be cryptographically verifiable. - -**`Verify correctness of metadata`**: For a given metadata structure we need to be able to verify that the metadata is correct in it's structure and that the data is correct. Given the uncensorable nature and goal for a healthy ecosystem, there can be multiple claims against the same subject and the concept of "correct" is therefore subjective and should be attached in some way to the *identity* of the publisher. - -**`Metadata discovery`**: When provided with specific pieces of information such as script addresses, we need to be able to find the metadata associated with it. This is useful for the wallet to be able to provide the user with information about the dapp, other related scripts and potential certifications or identity information about parties that made claims about that subject. +**`Trust`**: There's no standard mechanism to assert that the metadata is coming from a legitimate source. This is important for the user to be able to make an informed decision on how to interact with a subject. This is also important for applications to be able to provide a better user experience. ## **Open Questions** - Is this a combination of problems and should be split into multiple CPS? -- Does this englobes all the problems related to dapp metadata? -- Is this just a problem for dapps or should this be more generic? \ No newline at end of file +- Does this englobes all the problems related to metadata? +- Trust can be anchored to the owner's metadata or also third-parties that attest for the correctness of the metadata. How to handle this? +- How to associate identity to a metadata claim? +- How to handle the case where a subject has multiple metadata claims associated with it? +- How to handle the case where a subject has multiple metadata claims associated with it and the user wants to select a specific one? \ No newline at end of file From bc239e9734ca5d93f245eaea7f11711eea12ba59 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Tue, 13 Dec 2022 13:02:44 +0000 Subject: [PATCH 06/63] Add type key for REGISTER & UPDATE. Define rules for calculting hash of the metadata object tree --- CIP-0072/README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 8b53350e5b..218b7f9835 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -26,8 +26,9 @@ Also having this formalisation facilitates any actor in the ecosystem to index a { "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", - "cip26": ["http://somelocation.io/", "http://somelocation2.io/"], - "did": "did:prism:f2019bd31a8530fb67c6d81da758dfa9a65be09d835cf2cd361d595a8858301d", + "type": "REGISTER", + "cip26": ["http://somelocation.io/", "http://somelocation2.io/"], + "did": "did:ada:f2019bd31a8530fb67c6d81da758dfa9a65be09d835cf2cd361d595a8858301d", "signature": { "r": "5114674f1ce8a2615f2b15138944e5c58511804d72a96260ce8c587e7220daa90b9e65b450ff49563744d7633b43a78b8dc6ec3e3397b50080", "s": "a15f06ce8005ad817a1681a4e96ee6b4831679ef448d7c283b188ed64d399d6bac420fadf33964b2f2e0f2d1abd401e8eb09ab29e3ff280600", @@ -40,7 +41,11 @@ Also having this formalisation facilitates any actor in the ecosystem to index a ### Properties *`subject`*: Identifier of the claim subject (i.e dapp). A UTF-8 encoded string. This uniquess of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. This can be done by knowning verifying the signature against a trusted / known public key or by using Decentralized Identifiers (DIDs) as described in the [DID Specification](https://www.w3.org/TR/did-core/). -*`rootHash`*: The hash of the metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. +*`type`*: The type of the claim. A UTF-8 encoded string. The value of this property can have the value `REGISTER` or `UPDATE`. The `REGISTER` type is used to register a new dApp. The `UPDATE` type is used to update the metadata of an existing dApp. + +*`rootHash`*: The hash of the metadata entire tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. + +This hash is calculated by taking the entire metadata tree object, ordering the keys in the object alphanumerically, and then hashing the resulting JSON string using the blake2b hashing algorithm. The hash is encoded as a hex string. *`cip26`*: An array of URLs that point to the location of the dApp's metadata. The client should try to fetch the metadata from the first URL in the array. If the client fails to fetch the metadata from the first URL, it should try the second URL, and so on. If the client fails to fetch the metadata from all URLs, it should consider the metadata to be invalid. @@ -59,6 +64,13 @@ The format of the metadata tree object is described in the [CIP-26](https://gith "subject": { "type": "string" }, + "type": { + "type": "string", + "enum": [ + "REGISTER", + "UPDATE" + ] + }, "rootHash": { "type": "string" }, From e15d119dc9d0186dd78b39da061d1af36306d665 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Tue, 13 Dec 2022 13:08:40 +0000 Subject: [PATCH 07/63] typoe fix --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 218b7f9835..c196af77a4 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -14,7 +14,7 @@ DApp developers do not have a standardised method to record immutable, persisten This proposal aims to standardise the process of dApp registration and verification, and to provide a set of claims that dApp developers can use to register their dApp(s). ## **Motivation** -DApps can express a plethora of information. Some of this information could be claims about who the developer is, what is the dApp's associated metadata are, and more. This data lacks standarisation, persistence, and immutabulity. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. +DApps can express a plethora of information. Some of this information could be claims about who the developer is, what is the dApp's associated metadata are, and more. This data lacks standarisation, persistence, and immutability. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. Also having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. From 145f35082a7383c751329dc3fe4ef08c1ac895ca Mon Sep 17 00:00:00 2001 From: ehanoc Date: Thu, 15 Dec 2022 12:02:07 +0000 Subject: [PATCH 08/63] mistake folder added in last commit --- CPS-0001/README.md | 47 ---------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 CPS-0001/README.md diff --git a/CPS-0001/README.md b/CPS-0001/README.md deleted file mode 100644 index 532a895ced..0000000000 --- a/CPS-0001/README.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -CPS: 1 -Title: Metadata Discoverability and Trust -Authors: Bruno Martins -Status: Proposed -Type: Standards -Category: Wallets | Metadata | Plutus -Proposed Solutions: https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026, -https://github.com/cardano-foundation/CIPs/pull/355, -https://github.com/cardano-foundation/CIPs/pull/85, -https://github.com/cardano-foundation/CIPs/pull/112, -https://github.com/cardano-foundation/CIPs/pull/137, -https://github.com/cardano-foundation/CIPs/pull/299 -Created: 2022-19-10 ---- - -## **Abstract** -This document attempts to describe the problem in the Cardano ecocystem where there are many different types **subjects** or *chain entities* and there's a need to associate metadata with them. This metadata can be used to describe an script, stake pools, script hashes, token policies and applications. This metadata can be used to provide information to the user on it's applications, it's trustworthiness and how to interact with it. - -## **Goals** -- Define how metadata can be associated with the a subject (i.e dapp, stake pool, token policy, etc) -- Metadata should be discoverable by wallets and applications -- Associate some form of identity to a metadata claim - -## **Use Cases** -- Find scripts used by a dApp -- Discover general information of a dApp (i.e name, description, icons, etc) -- Find the different metadata claims associated with a subject -- Associate some form of identity to a claim's owner so that it can be verified cryptographically -- Offer mechanism to attest for the correctness of a given metadata object that can be fetched by wallets and applications from off-chain sources (i.e CIP-26 complaint servers) -- Discover datum schemas used by a script in a specific context or dApp use cases -- An wallet receiving a request to connect to a dApp, it can verify the authenticity of the dApp and the metadata associated with it. - -## **Problem** -**`Discoverability`**: Means to discover the different metadata claims associated with a subject. Discoverability is important for wallets, applications (i.e dapps, stores, etc) and users to be able to find the different metadata claims associated with a subject. This is important for the user to be able to make an informed decision on how to interact with a subject. - -**`Correctness`**: Lack of mechanism to assert that a given metadata claim is correct. Anybody and any service can provide metadata structures, but it's necessary to attest for the correctness of this metadata so that the user (or applications) are be able to make an informed decision in accepting, rejecting or how to interact with a subject. - -**`Trust`**: There's no standard mechanism to assert that the metadata is coming from a legitimate source. This is important for the user to be able to make an informed decision on how to interact with a subject. This is also important for applications to be able to provide a better user experience. - -## **Open Questions** -- Is this a combination of problems and should be split into multiple CPS? -- Does this englobes all the problems related to metadata? -- Trust can be anchored to the owner's metadata or also third-parties that attest for the correctness of the metadata. How to handle this? -- How to associate identity to a metadata claim? -- How to handle the case where a subject has multiple metadata claims associated with it? -- How to handle the case where a subject has multiple metadata claims associated with it and the user wants to select a specific one? \ No newline at end of file From 6c9b76ecd9bd62c0ccce057b95aee6f6b3c4fa47 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Mon, 19 Dec 2022 08:41:22 +0000 Subject: [PATCH 09/63] Suggest metadata transaction labels for dapp registration and certification --- CIP-0072/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index c196af77a4..3b2bd2a22a 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -1,6 +1,6 @@ --- CIP: 72 -Title: Cardano DApp Registration +Title: Cardano DApp Registration & Certification Authors: Bruno Martins Status: Draft Type: Standards @@ -116,4 +116,11 @@ The format of the metadata tree object is described in the [CIP-26](https://gith "signature" ] } -``` \ No newline at end of file +``` + +## Metadata Label + +When submitting the transaction metadata picks one of the following values for `transaction_metadatum_label`: + +- `666`: DApp Registration +- `667`: DApp Certification From 7b8127610cfa581aec31e4fbcc3c456ffaca788e Mon Sep 17 00:00:00 2001 From: ehanoc Date: Mon, 23 Jan 2023 14:40:15 +0000 Subject: [PATCH 10/63] Suggest metadata structure, off chain storages up to the operators. Improvements in schema and release properties --- CIP-0072/README.md | 379 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 330 insertions(+), 49 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 3b2bd2a22a..5a21e94e59 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -18,44 +18,133 @@ DApps can express a plethora of information. Some of this information could be c Also having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. +## **Definitions** +- **anchor** - A hash written on-chain that can be used to verify the integrity (by way of a cryptographic hash) of the data that is found off-chain. +- **dApp** - A decentralised application that is described by the combination of metadata, certificate and a set of used scripts. + ## **Specification** +### **Developers / Publishers** +Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verifier by stores, auditors and other actors. + +### **Stores / Auditors** +Store and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. + +#### **Off-chain Location Adversitment** +Each store and auditor should make public the location of their off-chain sources where they will look for the dApp's metadata based on certificates found on-chain. These can be advertised through their own API or publically available on a website. + +Sample off-chain sources could be for example : +- [CIP-26](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026) compliant servers +- IPFS + +##### **Targetted Releases** +Each developer and publisher can choose to where to write metadata based on the information available from known stores & auditors. This gives **developers** and **publishers** the ability to perform targeted releases. (i.e to which stores and auditors) + +#### **Suggested Validations** + +- **`integrity`**: The dapp's metadata off-chain should match the metadata anchored on-chain. +- **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. + ### **On-chain dApp Registration certificate** ```json { "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", - "type": "REGISTER", - "cip26": ["http://somelocation.io/", "http://somelocation2.io/"], - "did": "did:ada:f2019bd31a8530fb67c6d81da758dfa9a65be09d835cf2cd361d595a8858301d", + "schema_version": "0.0.1", + "type": { + "action": "REGISTER", + "releaseNumber": "1.0.0", + "releaseName": "My First Release", + }, "signature": { "r": "5114674f1ce8a2615f2b15138944e5c58511804d72a96260ce8c587e7220daa90b9e65b450ff49563744d7633b43a78b8dc6ec3e3397b50080", "s": "a15f06ce8005ad817a1681a4e96ee6b4831679ef448d7c283b188ed64d399d6bac420fadf33964b2f2e0f2d1abd401e8eb09ab29e3ff280600", "algo": "Ed25519−EdDSA", "pub": "b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde" - } + }, + "permissionToAggregate": true } ``` ### Properties -*`subject`*: Identifier of the claim subject (i.e dapp). A UTF-8 encoded string. This uniquess of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. This can be done by knowning verifying the signature against a trusted / known public key or by using Decentralized Identifiers (DIDs) as described in the [DID Specification](https://www.w3.org/TR/did-core/). +*`subject`*: Identifier of the claim subject (i.e dapp). A UTF-8 encoded string. This uniquess of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. -*`type`*: The type of the claim. A UTF-8 encoded string. The value of this property can have the value `REGISTER` or `UPDATE`. The `REGISTER` type is used to register a new dApp. The `UPDATE` type is used to update the metadata of an existing dApp. +*`type`*: The type of the claim. This is a JSON object that contains the following properties: +- *`action`*: The action that the certificate is asserting. It can take the following values: + - *`REGISTER`*: The certificate is asserting that the dApp is being registered for the first time. + - *`UPDATE`*: The certificate is asserting that the dApp is being updated. *`rootHash`*: The hash of the metadata entire tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. -This hash is calculated by taking the entire metadata tree object, ordering the keys in the object alphanumerically, and then hashing the resulting JSON string using the blake2b hashing algorithm. The hash is encoded as a hex string. +This hash is calculated by taking the entire metadata tree object, ordering the keys in the object alphanumerically, and then hashing the resulting JSON string using the blake2b-256 hashing algorithm. The hash is encoded as a hex string. + +*`signature`*: The signature of the certificate. The signature is done over the blake2b hash of the certificate. The client should use the public key to verify the signature of the certificate. + +## Certificate JSON Schema +```json +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://example.com/person.schema.json", + "title": "Person", + "type": "object", + "properties": { + "subject": { + "type": "string", + "description": "Can be anything. Description of the registration", + }, + "type": { + "type": "object", + "description": "Describes the releases, if they are new or an updates. Also states the versioning of such releases", + "properties": { + "action": { + "type": "string", + "description": "Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; or 'UPDATE' for a new release" + }, + "releaseNumber": { + "type": "string", + "description": "offical version of the release" + }, + "releaseName": { + "type": "string", + "description": "Dapp release name" + } + } + }, + "rootHash": { + "type": "string", + "description": "blake2b hash of the metadata describing the dApp" + }, + "signature": { + "description": "Age in years which must be equal to or greater than zero.", + "type": "object", + "properties": { + "r": { + "type": "string", + "description": "hex representation of the R component of the signature" + }, + "s": { + "type": "string", + "description": "hex representation of the S component of the signature" + }, + + }, + "required": ["r", "s", "algo", "pub"] + } + }, + "required": ["subject", "rootHash","type", "signature"] +} +``` -*`cip26`*: An array of URLs that point to the location of the dApp's metadata. The client should try to fetch the metadata from the first URL in the array. If the client fails to fetch the metadata from the first URL, it should try the second URL, and so on. If the client fails to fetch the metadata from all URLs, it should consider the metadata to be invalid. +## Metadata Label -The format of the metadata tree object is described in the [CIP-26](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026) specification. +When submitting the transaction metadata pick the following value for `transaction_metadatum_label`: -*`did`*(optional): The DID of the dApp's developer. The DID is used to verify the authenticity of the certificate. The client should use the DID to fetch the developer's public key from the Cardano blockchain. The client should then use the public key to verify the signature of the certificate. This field is *optional* and can be used by identity centric dApps to verify the authenticity of the developer. +- `1667`: DApp Registration -*`signature`*: The signature of the certificate. The signature is done over the blake2b hash of the certificate. The client should use the public key to verify the signature of the certificate. If a DID is provided, the client should use the DID to fetch the developer's public from the DID Document. If a DID is not provided, the client should use the public key provided in the signature object or from a already known public key. +## Offchain Metadata Format +The Dapp Registration certificate itself doesn't enforce a particular structure to the metadata you might fetch off-chain. However, we recommend that you use the following structure: -## Certificate JSON Schema ```json { "$schema": "http://json-schema.org/draft-04/schema#", @@ -64,63 +153,255 @@ The format of the metadata tree object is described in the [CIP-26](https://gith "subject": { "type": "string" }, - "type": { - "type": "string", - "enum": [ - "REGISTER", - "UPDATE" - ] + "projectName": { + "type": "string" }, - "rootHash": { + "link": { "type": "string" }, - "cip26": { - "type": "array", - "items": [ - { - "type": "string" - } - ] + "twitter": { + "type": "string" }, - "did": { + "category": { "type": "string" }, - "signature": { + "subCategory": { + "type": "string" + }, + "description": { "type": "object", "properties": { - "r": { - "type": "string" - }, - "s": { - "type": "string" - }, - "algo": { - "type": "string" - }, - "pub": { + "short": { "type": "string" } }, "required": [ - "r", - "s", - "algo", - "pub" + "short" + ] + }, + "releases": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "releaseNumber": { + "type": "integer" + }, + "releaseName": { + "type": "string" + }, + "auditId": { + "type": "string" + }, + "scripts": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "version" + ] + } + ] + } + }, + "required": [ + "releaseNumber", + "releaseName", + "auditId", + "scripts" + ] + } + ] + }, + "scripts": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "purpose": { + "type": "string" + }, + "type": { + "type": "string" + }, + "versions": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "version": { + "type": "integer" + }, + "plutusVersion": { + "type": "integer" + }, + "fullScriptHash": { + "type": "string" + }, + "scriptHash": { + "type": "string" + }, + "contractAddress": { + "type": "string" + } + }, + "required": [ + "version", + "plutusVersion", + "fullScriptHash", + "scriptHash", + "contractAddress" + ] + } + ] + }, + "audits": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "auditId": { + "type": "string" + }, + "auditor": { + "type": "string" + }, + "auditLink": { + "type": "string" + }, + "auditType": { + "type": "string" + }, + "signature": { + "type": "string" + }, + "publicKey": { + "type": "string" + } + }, + "required": [ + "auditId", + "auditor", + "auditLink", + "auditType", + "signature", + "publicKey" + ] + } + ] + } + }, + "required": [ + "id", + "name", + "purpose", + "type", + "versions", + "audits" + ] + } ] } }, "required": [ "subject", - "rootHash", - "cip26", - "signature" + "projectName", + "link", + "twitter", + "category", + "subCategory", + "description", + "releases", + "scripts" ] } ``` -## Metadata Label +## Example + +```json +{ + "subject": "9SYAJPNN", + "projectName": "My Project", + "link": "https://myProject.app", + "twitter": "https://twitter.com/MyProject", + "category": "GAMING", + "subCategory": "RPG", + "description": { + "short": "A story rich game where choices matter" + }, + + "releases": [ + { + "releaseNumber": 1, + "releaseName": "V1", + "auditId": "z5L90f", + "scripts": [ + { + "id": "PmNd6w", + "version": 1 + } + ] + } + ], + "scripts": [ + { + "id": "PmNd6w", + "name": "Marketplace", + "purpose": "SPEND", + "type": "PLUTUS", + "versions": [ + { + "version": 1, + "plutusVersion": 1, + "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" + } + ], + "audits": [ + { + "auditId": "z5L90f", + "auditor": "Canonical LLC.", + "auditLink": "https://github.com/somlinkToAessment", + "auditType": "MANUAL", + "signature": "0x1234567890abcdef", + "publicKey": "0x1234567890abcdef" + } + ] + } + ] +} +``` + +### **Scripts Audits** +As part of the metadata we will be including a list of audits for each script. This will be a list of audits that have been performed on the script. The audits will be performed by a third party auditor and will be signed by the auditor. + +Some of the properties included in the audit are: -When submitting the transaction metadata picks one of the following values for `transaction_metadatum_label`: +- **auditType** property will be included that can take one of the following values: MANUAL, AUTOMATED, or MIXED. +- **auditId** property will be included that will be a unique identifier for the audit. +- **auditLink** property will be included that will be a link to the audit report. +- **signature** property will be included that will be a signature of the audit report. +- **publicKey** property will be included that will be the public key of the auditor. -- `666`: DApp Registration -- `667`: DApp Certification From eb6f68ec79e28f1e3b8d0cf06a775753565a3e56 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Tue, 24 Jan 2023 10:20:32 +0000 Subject: [PATCH 11/63] Refactor for more compliant header --- CIP-0072/README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 5a21e94e59..1142153ebb 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -1,13 +1,18 @@ --- CIP: 72 Title: Cardano DApp Registration & Certification -Authors: Bruno Martins Status: Draft -Type: Standards +Category: Metadata +Authors: + - Bruno Martins +Discussions: + - https://github.com/cardano-foundation/CIPs/pull/355 Created: 2022-10-18 License: CC-BY-4.0 --- +# CIP-0072: Cardano DApp Registration & Certification + ## **Abstract** DApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developers needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by the dApp developer. From 420c292a819499bb8af6602e153477d7a0b74c15 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Tue, 24 Jan 2023 11:25:50 +0000 Subject: [PATCH 12/63] Removing permissionToAggregate --- CIP-0072/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 1142153ebb..a89051d2d6 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -67,8 +67,7 @@ Each developer and publisher can choose to where to write metadata based on the "s": "a15f06ce8005ad817a1681a4e96ee6b4831679ef448d7c283b188ed64d399d6bac420fadf33964b2f2e0f2d1abd401e8eb09ab29e3ff280600", "algo": "Ed25519−EdDSA", "pub": "b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde" - }, - "permissionToAggregate": true + } } ``` From c55b5b531ca0ab8f4092234992f1e77fe5b85939 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Tue, 24 Jan 2023 14:33:05 +0000 Subject: [PATCH 13/63] Section for stores custom required metadata fields --- CIP-0072/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index a89051d2d6..627c18aae8 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -409,3 +409,5 @@ Some of the properties included in the audit are: - **signature** property will be included that will be a signature of the audit report. - **publicKey** property will be included that will be the public key of the auditor. +### **Stores Custom fields** +Each store might have their own requirements for the metadata. For example, some stores might require a field for logo, or screenshots links. The store's should adviertise what fields they require in their documentation so that developers are aware and they can include them in the metadata. \ No newline at end of file From b2b5fc08b67599ab5333041104ebcb4172b89cf9 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Tue, 24 Jan 2023 16:16:56 +0000 Subject: [PATCH 14/63] Better descriptive title --- CIP-0072/README.md | 90 ++++++++++++++++++++++++++++++++++++++-- CIP-0072/sample-cip26.md | 60 +++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 CIP-0072/sample-cip26.md diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 627c18aae8..18e175ac91 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -1,6 +1,6 @@ --- CIP: 72 -Title: Cardano DApp Registration & Certification +Title: Cardano DApp Registration & Discovery Status: Draft Category: Metadata Authors: @@ -11,7 +11,7 @@ Created: 2022-10-18 License: CC-BY-4.0 --- -# CIP-0072: Cardano DApp Registration & Certification +# CIP-0072: Cardano DApp Registration & Discovery ## **Abstract** DApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developers needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by the dApp developer. @@ -410,4 +410,88 @@ Some of the properties included in the audit are: - **publicKey** property will be included that will be the public key of the auditor. ### **Stores Custom fields** -Each store might have their own requirements for the metadata. For example, some stores might require a field for logo, or screenshots links. The store's should adviertise what fields they require in their documentation so that developers are aware and they can include them in the metadata. \ No newline at end of file +Each store might have their own requirements for the metadata. For example, some stores might require a field for logo, or screenshots links. The store's should adviertise what fields they require in their documentation so that developers are aware and they can include them in the metadata. + +### **Offchain Metadata Storage** + +There are multiple options to store metadata offchain. The most common options are: +- IPFS +- CIP-26 + +#### `CIP-26 Example` + +CIP-26 offers a API that stores properties regarding a particular subject. This isn't directly JSON compliant as it would only support writing flat JSON objects into a CIP-26 server. Although we can make use of encoding mechanisms to store nested JSON properties in a CIP-26 server. + +Sample JSON +```json + { + "subject": "9SYAJPNN", + "projectName": "My Project", + "link": "https://myProject.app", + "twitter": "https://twitter.com/MyProject", + "category": "GAMING", + "subCategory": "RPG", + "description": { + "short": "A story rich game where choices matter" + }, + + "releases": [{ + "releaseNumber": 1, + "releaseName": "V1", + "auditId": "z5L90f", + "scripts": [{ + "id": "PmNd6w", + "version": 1 + }] + }], + "scripts": [{ + "id": "PmNd6w", + "name": "Marketplace", + "purpose": "SPEND", + "type": "PLUTUS", + "versions": [{ + "version": 1, + "plutusVersion": 1, + "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" + }], + "audits": [{ + "auditId": "z5L90f", + "auditor": "Canonical LLC.", + "auditLink": "https://github.com/somlinkToAessment", + "auditType": "MANUAL", + "signature": "0x1234567890abcdef", + "publicKey": "0x1234567890abcdef" + }] + }] + } +``` + +Could be stored into CIP-26 by encoding the nested hierarchical objects. So the previous metadata object would look something like the following: + +```json +{ + "subject": "9SYAJPNN", + "projectName": "My Project", + "link": "https://myProject.app", + "twitter": "https://twitter.com/MyProject", + "category": "GAMING", + "subCategory": "RPG", + "description": { + "short": "A story rich game where choices matter" + }, + "releases": "AAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAABQAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAEAAAAA", + "scripts": "AAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABwEBAAAABAAIAAAHAAAAAAADCAQAAAUDBwUGBgEAAAEAAAcEAAcAAAAAAAcDAAAAAgMGAAAGCAEJAgAAAAAAAAAAAAAAAAAAAAABAAAABAAIAAAHAAAAAAADCAQAAAUDBwUGBgEAAAEAAAcEAAcAAAAAAAcDAAAAAgMGAAAGCAEJAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAABQAGAAAAAAUAAAAAAAACAAAAAAgACAAAAAcAAAAAAAYDAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAUGBwgJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAUGBwgJAAAAAAAAAAAAAAAA" +} +``` + +##### `CIP-26 submission` + +```bash +curl -X 'POST' \ + 'https://somecip26server/metadata' \ + -H 'accept: */*' \ + -H 'Content-Type: application/json' \ + -d `[ENCODED_JSON_GOES_HERE` +``` \ No newline at end of file diff --git a/CIP-0072/sample-cip26.md b/CIP-0072/sample-cip26.md new file mode 100644 index 0000000000..c24879ac87 --- /dev/null +++ b/CIP-0072/sample-cip26.md @@ -0,0 +1,60 @@ +### **Offchain Metadata Storage** + +There are multiple options to store metadata offchain. The most common options are: +- IPFS +- CIP-26 + +#### `CIP-26 Example` + +CIP-26 offers a API that stores properties regarding a particular subject. This isn't directly JSON compliant as it would only support writing flat JSON objects into a CIP-26 server. Although we can make use of encoding mechanisms to store nested JSON properties in a CIP-26 server. + +The following example shows how we can store a JSON object into CIP-26. The nested JSON object is encoded into a string and stored into CIP-26 in a single property. + +Even though CIP-26 does not support nested JSON objects and hierarchies, we can still store them by encoding them into a string. Giving us the ability to take advantage of it's versioning, historical data, auditability and signature attestations at the property level. + +Sample JSON +```json + { + "subject": "9SYAJPNN", + "projectName": "My Project", + "link": "https://myProject.app", + "twitter": "https://twitter.com/MyProject", + "category": "GAMING", + "subCategory": "RPG", + "description": { + "short": "A story rich game where choices matter" + }, + + "releases": [{ + "releaseNumber": 1, + "releaseName": "V1", + "auditId": "z5L90f", + "scripts": [{ + "id": "PmNd6w", + "version": 1 + }] + }], + "scripts": [{ + "id": "PmNd6w", + "name": "Marketplace", + "purpose": "SPEND", + "type": "PLUTUS", + "versions": [{ + "version": 1, + "plutusVersion": 1, + "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" + }], + "audits": [{ + "auditId": "z5L90f", + "auditor": "Canonical LLC.", + "auditLink": "https://github.com/somlinkToAessment", + "auditType": "MANUAL", + "signature": "0x1234567890abcdef", + "publicKey": "0x1234567890abcdef" + }] + }] + } +``` + From 65b06aec168b405899f89e700ea29524469651c9 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Thu, 2 Mar 2023 08:41:38 +0000 Subject: [PATCH 15/63] Metadata links included in cert. Removing audits and simplify explanation --- CIP-0072/README.md | 328 ++++++++++++++++++++++----------------------- 1 file changed, 160 insertions(+), 168 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 18e175ac91..2f991233b6 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -56,6 +56,11 @@ Each developer and publisher can choose to where to write metadata based on the { "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", + "metadata": [ + "https://cip26.foundation.app/properties/d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", + "https://example.com/metadata.json", + "ipfs://QmWmXcRqPzJn5yDh8cXqL1oYjHr4kZx1aYQ1w1yTfTJqNn", + ], "schema_version": "0.0.1", "type": { "action": "REGISTER", @@ -83,6 +88,8 @@ Each developer and publisher can choose to where to write metadata based on the This hash is calculated by taking the entire metadata tree object, ordering the keys in the object alphanumerically, and then hashing the resulting JSON string using the blake2b-256 hashing algorithm. The hash is encoded as a hex string. +*`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON object that contains the dApp's metadata. + *`signature`*: The signature of the certificate. The signature is done over the blake2b hash of the certificate. The client should use the public key to verify the signature of the certificate. ## Certificate JSON Schema @@ -163,9 +170,6 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "link": { "type": "string" }, - "twitter": { - "type": "string" - }, "category": { "type": "string" }, @@ -278,38 +282,171 @@ The Dapp Registration certificate itself doesn't enforce a particular structure } ] }, - "audits": { + }, + "required": [ + "id", + "name", + "purpose", + "type", + "versions", + "audits" + ] + } + ] + } + }, + "required": [ + "subject", + "projectName", + "link", + "twitter", + "category", + "subCategory", + "description", + "releases", + "scripts" + ] +} +``` + +## Example + +```json +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "projectName": { + "type": "string" + }, + "link": { + "type": "string" + }, + "category": { + "type": "string" + }, + "subCategory": { + "type": "string" + }, + "social": { + "type": "object", + "properties": { + "twitter": { + "type": "string" + }, + "github": { + "type": "string" + }, + "website": { + "type": "string" + } + } + }, + "description": { + "type": "object", + "properties": { + "short": { + "type": "string" + } + }, + "required": [ + "short" + ] + }, + "releases": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "releaseNumber": { + "type": "integer" + }, + "releaseName": { + "type": "string" + }, + "auditId": { + "type": "string" + }, + "scripts": { "type": "array", "items": [ { "type": "object", "properties": { - "auditId": { + "id": { "type": "string" }, - "auditor": { - "type": "string" + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "version" + ] + } + ] + } + }, + "required": [ + "releaseNumber", + "releaseName", + "auditId", + "scripts" + ] + } + ] + }, + "scripts": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "purpose": { + "type": "string" + }, + "type": { + "type": "string" + }, + "versions": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "version": { + "type": "integer" }, - "auditLink": { - "type": "string" + "plutusVersion": { + "type": "integer" }, - "auditType": { + "fullScriptHash": { "type": "string" }, - "signature": { + "scriptHash": { "type": "string" }, - "publicKey": { + "contractAddress": { "type": "string" } }, "required": [ - "auditId", - "auditor", - "auditLink", - "auditType", - "signature", - "publicKey" + "version", + "plutusVersion", + "fullScriptHash", + "scriptHash", + "contractAddress" ] } ] @@ -320,8 +457,7 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "name", "purpose", "type", - "versions", - "audits" + "versions" ] } ] @@ -331,7 +467,7 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "subject", "projectName", "link", - "twitter", + "social", "category", "subCategory", "description", @@ -341,74 +477,6 @@ The Dapp Registration certificate itself doesn't enforce a particular structure } ``` -## Example - -```json -{ - "subject": "9SYAJPNN", - "projectName": "My Project", - "link": "https://myProject.app", - "twitter": "https://twitter.com/MyProject", - "category": "GAMING", - "subCategory": "RPG", - "description": { - "short": "A story rich game where choices matter" - }, - - "releases": [ - { - "releaseNumber": 1, - "releaseName": "V1", - "auditId": "z5L90f", - "scripts": [ - { - "id": "PmNd6w", - "version": 1 - } - ] - } - ], - "scripts": [ - { - "id": "PmNd6w", - "name": "Marketplace", - "purpose": "SPEND", - "type": "PLUTUS", - "versions": [ - { - "version": 1, - "plutusVersion": 1, - "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" - } - ], - "audits": [ - { - "auditId": "z5L90f", - "auditor": "Canonical LLC.", - "auditLink": "https://github.com/somlinkToAessment", - "auditType": "MANUAL", - "signature": "0x1234567890abcdef", - "publicKey": "0x1234567890abcdef" - } - ] - } - ] -} -``` - -### **Scripts Audits** -As part of the metadata we will be including a list of audits for each script. This will be a list of audits that have been performed on the script. The audits will be performed by a third party auditor and will be signed by the auditor. - -Some of the properties included in the audit are: - -- **auditType** property will be included that can take one of the following values: MANUAL, AUTOMATED, or MIXED. -- **auditId** property will be included that will be a unique identifier for the audit. -- **auditLink** property will be included that will be a link to the audit report. -- **signature** property will be included that will be a signature of the audit report. -- **publicKey** property will be included that will be the public key of the auditor. - ### **Stores Custom fields** Each store might have their own requirements for the metadata. For example, some stores might require a field for logo, or screenshots links. The store's should adviertise what fields they require in their documentation so that developers are aware and they can include them in the metadata. @@ -416,82 +484,6 @@ Each store might have their own requirements for the metadata. For example, some There are multiple options to store metadata offchain. The most common options are: - IPFS -- CIP-26 - -#### `CIP-26 Example` - -CIP-26 offers a API that stores properties regarding a particular subject. This isn't directly JSON compliant as it would only support writing flat JSON objects into a CIP-26 server. Although we can make use of encoding mechanisms to store nested JSON properties in a CIP-26 server. - -Sample JSON -```json - { - "subject": "9SYAJPNN", - "projectName": "My Project", - "link": "https://myProject.app", - "twitter": "https://twitter.com/MyProject", - "category": "GAMING", - "subCategory": "RPG", - "description": { - "short": "A story rich game where choices matter" - }, - - "releases": [{ - "releaseNumber": 1, - "releaseName": "V1", - "auditId": "z5L90f", - "scripts": [{ - "id": "PmNd6w", - "version": 1 - }] - }], - "scripts": [{ - "id": "PmNd6w", - "name": "Marketplace", - "purpose": "SPEND", - "type": "PLUTUS", - "versions": [{ - "version": 1, - "plutusVersion": 1, - "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" - }], - "audits": [{ - "auditId": "z5L90f", - "auditor": "Canonical LLC.", - "auditLink": "https://github.com/somlinkToAessment", - "auditType": "MANUAL", - "signature": "0x1234567890abcdef", - "publicKey": "0x1234567890abcdef" - }] - }] - } -``` - -Could be stored into CIP-26 by encoding the nested hierarchical objects. So the previous metadata object would look something like the following: - -```json -{ - "subject": "9SYAJPNN", - "projectName": "My Project", - "link": "https://myProject.app", - "twitter": "https://twitter.com/MyProject", - "category": "GAMING", - "subCategory": "RPG", - "description": { - "short": "A story rich game where choices matter" - }, - "releases": "AAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAABQAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAEAAAAA", - "scripts": "AAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABwEBAAAABAAIAAAHAAAAAAADCAQAAAUDBwUGBgEAAAEAAAcEAAcAAAAAAAcDAAAAAgMGAAAGCAEJAgAAAAAAAAAAAAAAAAAAAAABAAAABAAIAAAHAAAAAAADCAQAAAUDBwUGBgEAAAEAAAcEAAcAAAAAAAcDAAAAAgMGAAAGCAEJAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAABQAGAAAAAAUAAAAAAAACAAAAAAgACAAAAAcAAAAAAAYDAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAUGBwgJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIDBAUGBwgJAAAAAAAAAAAAAAAA" -} -``` - -##### `CIP-26 submission` - -```bash -curl -X 'POST' \ - 'https://somecip26server/metadata' \ - -H 'accept: */*' \ - -H 'Content-Type: application/json' \ - -d `[ENCODED_JSON_GOES_HERE` -``` \ No newline at end of file +- CIP-26 +- Bitbucket +- Regular HTTP server From 35221dcd1e9970b7bfb9890ca9ad58e4c74e23b9 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Wed, 25 Jan 2023 06:53:08 -0500 Subject: [PATCH 16/63] Update CIP-0072/README.md Co-authored-by: simonjohnthompson --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 2f991233b6..8b64e164d0 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -30,7 +30,7 @@ Also having this formalisation facilitates any actor in the ecosystem to index a ## **Specification** ### **Developers / Publishers** -Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verifier by stores, auditors and other actors. +Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verified by stores, auditors and other actors. ### **Stores / Auditors** Store and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. From bb51de17e2007f2450c2e3490ce2fc89c15804c8 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Wed, 25 Jan 2023 06:53:33 -0500 Subject: [PATCH 17/63] Update CIP-0072/README.md Co-authored-by: simonjohnthompson --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 8b64e164d0..16d309861a 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -35,7 +35,7 @@ Developers and publishers of dApps can register their dApps by submitting a tran ### **Stores / Auditors** Store and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. -#### **Off-chain Location Adversitment** +#### **Off-chain Location Advertisement** Each store and auditor should make public the location of their off-chain sources where they will look for the dApp's metadata based on certificates found on-chain. These can be advertised through their own API or publically available on a website. Sample off-chain sources could be for example : From db90256fcb6bb9d84254a5d97da001745a449893 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Wed, 25 Jan 2023 06:53:54 -0500 Subject: [PATCH 18/63] Update CIP-0072/README.md Co-authored-by: simonjohnthompson --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 16d309861a..fbe2708189 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -48,7 +48,7 @@ Each developer and publisher can choose to where to write metadata based on the #### **Suggested Validations** - **`integrity`**: The dapp's metadata off-chain should match the metadata anchored on-chain. -- **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. +- **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain and publish their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. ### **On-chain dApp Registration certificate** From 1a7bdce80fcec6c6db7ae3ddf266b0ae29fe56e9 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 2 Feb 2023 11:20:42 +0000 Subject: [PATCH 19/63] typos, structure adjustments and small prose adds --- CIP-0072/README.md | 57 ++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index fbe2708189..594720eac6 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -1,10 +1,11 @@ --- CIP: 72 Title: Cardano DApp Registration & Discovery -Status: Draft +Status: Proposed Category: Metadata Authors: - Bruno Martins +Implementors: [] Discussions: - https://github.com/cardano-foundation/CIPs/pull/355 Created: 2022-10-18 @@ -13,45 +14,48 @@ License: CC-BY-4.0 # CIP-0072: Cardano DApp Registration & Discovery -## **Abstract** -DApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developers needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by the dApp developer. +## Abstract +DApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developer needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by dApp developers. This proposal aims to standardise the process of dApp registration and verification, and to provide a set of claims that dApp developers can use to register their dApp(s). -## **Motivation** -DApps can express a plethora of information. Some of this information could be claims about who the developer is, what is the dApp's associated metadata are, and more. This data lacks standarisation, persistence, and immutability. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. +## Motivation +DApps can express a plethora of information. Some of this information could be claims about who the developer is, what the dApp's associated metadata is, and more. This data lacks standardisation, persistence, and immutability. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. -Also having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. +Also, having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. -## **Definitions** +## Specification + +### **Definitions** - **anchor** - A hash written on-chain that can be used to verify the integrity (by way of a cryptographic hash) of the data that is found off-chain. - **dApp** - A decentralised application that is described by the combination of metadata, certificate and a set of used scripts. - -## **Specification** +- **metadata claim** - Generically any attempt to map off-chain metadata to an on-chain subject. This specification looks at dApp specific metadata claims. +- **client** - Any ecosystem participant which follows on-chain data to consume metadata claims (i.e. dApp stores, wallets, auditors, block explorers, etc.). +- **dApp Store** - A dApp aggregator application which follows on-chain data looking for and verifying dApp metadata claims, serving their users linked dApp metadata. +- **publishers** - Entities which publish metadata claims on-chain, in the case of dApps the publishers are likely the dApp developer(s). +- **auditors** - These are clients which maintain lists of trusted entities and metadata servers, checking metadata claims against these. ### **Developers / Publishers** -Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verified by stores, auditors and other actors. +Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verified by stores, auditors and other ecosystem actors. ### **Stores / Auditors** -Store and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. +Stores and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. #### **Off-chain Location Advertisement** -Each store and auditor should make public the location of their off-chain sources where they will look for the dApp's metadata based on certificates found on-chain. These can be advertised through their own API or publically available on a website. +Each store and auditor should make public the location of their off-chain sources where they will look for the dApp's metadata based on certificates found on-chain. These can be advertised through their own API or publicly available on a website. -Sample off-chain sources could be for example : +Sample off-chain sources could be for example: - [CIP-26](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026) compliant servers -- IPFS +- [IPFS](https://ipfs.tech/) ##### **Targetted Releases** -Each developer and publisher can choose to where to write metadata based on the information available from known stores & auditors. This gives **developers** and **publishers** the ability to perform targeted releases. (i.e to which stores and auditors) +Each developer and publisher can choose where to write metadata based on the information available from known stores & auditors. This gives **developers** and **publishers** the ability to perform targeted releases. (i.e to which stores and auditors). #### **Suggested Validations** +- **`integrity`**: The dApp's metadata off-chain should match the metadata **anchored** on-chain. +- **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain and publish their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. These entities could be directly associated with developer/publisher or not. -- **`integrity`**: The dapp's metadata off-chain should match the metadata anchored on-chain. -- **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain and publish their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. - -### **On-chain dApp Registration certificate** - +### **On-chain dApp Registration Certificate** ```json { "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", @@ -77,7 +81,7 @@ Each developer and publisher can choose to where to write metadata based on the ``` ### Properties -*`subject`*: Identifier of the claim subject (i.e dapp). A UTF-8 encoded string. This uniquess of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. +*`subject`*: Identifier of the claim subject (i.e dApp). A UTF-8 encoded string. This uniqueness of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. *`type`*: The type of the claim. This is a JSON object that contains the following properties: - *`action`*: The action that the certificate is asserting. It can take the following values: @@ -92,7 +96,7 @@ This hash is calculated by taking the entire metadata tree object, ordering the *`signature`*: The signature of the certificate. The signature is done over the blake2b hash of the certificate. The client should use the public key to verify the signature of the certificate. -## Certificate JSON Schema +### Certificate JSON Schema ```json { "$schema": "https://json-schema.org/draft/2019-09/schema", @@ -114,7 +118,7 @@ This hash is calculated by taking the entire metadata tree object, ordering the }, "releaseNumber": { "type": "string", - "description": "offical version of the release" + "description": "official version of the release" }, "releaseName": { "type": "string", @@ -147,13 +151,12 @@ This hash is calculated by taking the entire metadata tree object, ordering the } ``` -## Metadata Label - +### Metadata Label When submitting the transaction metadata pick the following value for `transaction_metadatum_label`: - `1667`: DApp Registration -## Offchain Metadata Format +### Off-chain Metadata Format The Dapp Registration certificate itself doesn't enforce a particular structure to the metadata you might fetch off-chain. However, we recommend that you use the following structure: ```json @@ -309,7 +312,7 @@ The Dapp Registration certificate itself doesn't enforce a particular structure } ``` -## Example +### Example ```json { From da01282c76481e802060bdbe4a81f067b667dc4a Mon Sep 17 00:00:00 2001 From: ehanoc Date: Thu, 2 Mar 2023 08:54:25 +0000 Subject: [PATCH 20/63] Metadata links included in cert. Removing audits. Small refactoring --- CIP-0072/README.md | 221 +++++++++++---------------------------------- 1 file changed, 55 insertions(+), 166 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 594720eac6..1d9707db61 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -41,13 +41,6 @@ Developers and publishers of dApps can register their dApps by submitting a tran ### **Stores / Auditors** Stores and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. -#### **Off-chain Location Advertisement** -Each store and auditor should make public the location of their off-chain sources where they will look for the dApp's metadata based on certificates found on-chain. These can be advertised through their own API or publicly available on a website. - -Sample off-chain sources could be for example: -- [CIP-26](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026) compliant servers -- [IPFS](https://ipfs.tech/) - ##### **Targetted Releases** Each developer and publisher can choose where to write metadata based on the information available from known stores & auditors. This gives **developers** and **publishers** the ability to perform targeted releases. (i.e to which stores and auditors). @@ -159,161 +152,6 @@ When submitting the transaction metadata pick the following value for `transacti ### Off-chain Metadata Format The Dapp Registration certificate itself doesn't enforce a particular structure to the metadata you might fetch off-chain. However, we recommend that you use the following structure: -```json -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "subject": { - "type": "string" - }, - "projectName": { - "type": "string" - }, - "link": { - "type": "string" - }, - "category": { - "type": "string" - }, - "subCategory": { - "type": "string" - }, - "description": { - "type": "object", - "properties": { - "short": { - "type": "string" - } - }, - "required": [ - "short" - ] - }, - "releases": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "releaseNumber": { - "type": "integer" - }, - "releaseName": { - "type": "string" - }, - "auditId": { - "type": "string" - }, - "scripts": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "version": { - "type": "integer" - } - }, - "required": [ - "id", - "version" - ] - } - ] - } - }, - "required": [ - "releaseNumber", - "releaseName", - "auditId", - "scripts" - ] - } - ] - }, - "scripts": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "purpose": { - "type": "string" - }, - "type": { - "type": "string" - }, - "versions": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "version": { - "type": "integer" - }, - "plutusVersion": { - "type": "integer" - }, - "fullScriptHash": { - "type": "string" - }, - "scriptHash": { - "type": "string" - }, - "contractAddress": { - "type": "string" - } - }, - "required": [ - "version", - "plutusVersion", - "fullScriptHash", - "scriptHash", - "contractAddress" - ] - } - ] - }, - }, - "required": [ - "id", - "name", - "purpose", - "type", - "versions", - "audits" - ] - } - ] - } - }, - "required": [ - "subject", - "projectName", - "link", - "twitter", - "category", - "subCategory", - "description", - "releases", - "scripts" - ] -} -``` - -### Example - ```json { "$schema": "http://json-schema.org/draft-04/schema#", @@ -480,13 +318,64 @@ The Dapp Registration certificate itself doesn't enforce a particular structure } ``` +### Example + +```json +{ + "subject": "9SYAJPNN", + "projectName": "My Project", + "link": "https://myProject.app", + "social": { + "twitter": "twiterHandle", + "github": "githubHandle", + "website": "https://website" + }, + "category": "GAMING", + "subCategory": "RPG", + "description": { + "short": "A story rich game where choices matter" + }, + "releases": [ + { + "releaseNumber": 1, + "releaseName": "V1", + "auditId": "z5L90f", + "scripts": [ + { + "id": "PmNd6w", + "version": 1 + } + ] + } + ], + "scripts": [ + { + "id": "PmNd6w", + "name": "Marketplace", + "purpose": "SPEND", + "type": "PLUTUS", + "versions": [ + { + "version": 1, + "plutusVersion": 1, + "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" + } + ] + } + ] +} +``` + ### **Stores Custom fields** Each store might have their own requirements for the metadata. For example, some stores might require a field for logo, or screenshots links. The store's should adviertise what fields they require in their documentation so that developers are aware and they can include them in the metadata. ### **Offchain Metadata Storage** There are multiple options to store metadata offchain. The most common options are: -- IPFS -- CIP-26 -- Bitbucket -- Regular HTTP server +- [CIP-26](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026) compliant servers +- [IPFS](https://ipfs.tech/) +- [Bitbucket](https://bitbucket.org/) +- Any REST JSON API + From ef5d718935baaa1510a29678a4b06aa2b8054044 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Thu, 2 Mar 2023 08:55:51 +0000 Subject: [PATCH 21/63] specify size of hash --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 1d9707db61..5c194acee3 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -87,7 +87,7 @@ This hash is calculated by taking the entire metadata tree object, ordering the *`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON object that contains the dApp's metadata. -*`signature`*: The signature of the certificate. The signature is done over the blake2b hash of the certificate. The client should use the public key to verify the signature of the certificate. +*`signature`*: The signature of the certificate. The signature is done over the blake2b-256 hash of the certificate. The client should use the public key to verify the signature of the certificate. ### Certificate JSON Schema ```json From 9d8d87e23f4c5066c83600874eb187f41ec6014d Mon Sep 17 00:00:00 2001 From: ehanoc Date: Thu, 2 Mar 2023 09:02:08 +0000 Subject: [PATCH 22/63] Authors update --- CIP-0072/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 5c194acee3..86310e61ed 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -5,6 +5,7 @@ Status: Proposed Category: Metadata Authors: - Bruno Martins + - Mateusz Czeladka Implementors: [] Discussions: - https://github.com/cardano-foundation/CIPs/pull/355 From 150910309f61cb635b0446ac79fb7709eefdd728 Mon Sep 17 00:00:00 2001 From: ehanoc Date: Fri, 3 Mar 2023 16:09:45 +0000 Subject: [PATCH 23/63] Delete sample-cip26.md --- CIP-0072/sample-cip26.md | 60 ---------------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 CIP-0072/sample-cip26.md diff --git a/CIP-0072/sample-cip26.md b/CIP-0072/sample-cip26.md deleted file mode 100644 index c24879ac87..0000000000 --- a/CIP-0072/sample-cip26.md +++ /dev/null @@ -1,60 +0,0 @@ -### **Offchain Metadata Storage** - -There are multiple options to store metadata offchain. The most common options are: -- IPFS -- CIP-26 - -#### `CIP-26 Example` - -CIP-26 offers a API that stores properties regarding a particular subject. This isn't directly JSON compliant as it would only support writing flat JSON objects into a CIP-26 server. Although we can make use of encoding mechanisms to store nested JSON properties in a CIP-26 server. - -The following example shows how we can store a JSON object into CIP-26. The nested JSON object is encoded into a string and stored into CIP-26 in a single property. - -Even though CIP-26 does not support nested JSON objects and hierarchies, we can still store them by encoding them into a string. Giving us the ability to take advantage of it's versioning, historical data, auditability and signature attestations at the property level. - -Sample JSON -```json - { - "subject": "9SYAJPNN", - "projectName": "My Project", - "link": "https://myProject.app", - "twitter": "https://twitter.com/MyProject", - "category": "GAMING", - "subCategory": "RPG", - "description": { - "short": "A story rich game where choices matter" - }, - - "releases": [{ - "releaseNumber": 1, - "releaseName": "V1", - "auditId": "z5L90f", - "scripts": [{ - "id": "PmNd6w", - "version": 1 - }] - }], - "scripts": [{ - "id": "PmNd6w", - "name": "Marketplace", - "purpose": "SPEND", - "type": "PLUTUS", - "versions": [{ - "version": 1, - "plutusVersion": 1, - "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" - }], - "audits": [{ - "auditId": "z5L90f", - "auditor": "Canonical LLC.", - "auditLink": "https://github.com/somlinkToAessment", - "auditType": "MANUAL", - "signature": "0x1234567890abcdef", - "publicKey": "0x1234567890abcdef" - }] - }] - } -``` - From 18ad978cb3ddecb9ac330102f2929045b6eff78a Mon Sep 17 00:00:00 2001 From: ehanoc Date: Sat, 4 Mar 2023 17:29:10 +0000 Subject: [PATCH 24/63] removing auditId --- CIP-0072/README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 86310e61ed..577df9ac17 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -210,9 +210,6 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "releaseName": { "type": "string" }, - "auditId": { - "type": "string" - }, "scripts": { "type": "array", "items": [ @@ -237,7 +234,6 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "required": [ "releaseNumber", "releaseName", - "auditId", "scripts" ] } @@ -340,7 +336,6 @@ The Dapp Registration certificate itself doesn't enforce a particular structure { "releaseNumber": 1, "releaseName": "V1", - "auditId": "z5L90f", "scripts": [ { "id": "PmNd6w", From 69e3e0cb73751b228fe2aa83a9b3714ccb9809ac Mon Sep 17 00:00:00 2001 From: ehanoc Date: Thu, 23 Mar 2023 16:38:21 +0000 Subject: [PATCH 25/63] Add logo to suggested metadata properties --- CIP-0072/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 577df9ac17..92b68552e7 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -167,6 +167,10 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "link": { "type": "string" }, + "logo": { + "type": "string", + "description": "URL to the logo or the base64 encoded image" + }, "category": { "type": "string" }, @@ -315,6 +319,8 @@ The Dapp Registration certificate itself doesn't enforce a particular structure } ``` +This schema describes the minimum required fields for a store to be able to display and validate your dApp. You can add any other fields you want to the metadata, but we recommend that you use at least the ones described above. + ### Example ```json @@ -322,6 +328,7 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "subject": "9SYAJPNN", "projectName": "My Project", "link": "https://myProject.app", + "logo": "https://myProject.app/logo.png", "social": { "twitter": "twiterHandle", "github": "githubHandle", From 3e1e3e97c76bc7e1ab4d5b976ae12081d659d9ec Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Tue, 11 Apr 2023 16:30:01 +0200 Subject: [PATCH 26/63] amendments based on comments / experience / feedback. --- CIP-0072/README.md | 295 ++++++++++++++++++++++++++------------------- 1 file changed, 173 insertions(+), 122 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 92b68552e7..574af88ec1 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -1,6 +1,6 @@ --- CIP: 72 -Title: Cardano DApp Registration & Discovery +Title: Cardano dApp Registration & Discovery Status: Proposed Category: Metadata Authors: @@ -13,22 +13,22 @@ Created: 2022-10-18 License: CC-BY-4.0 --- -# CIP-0072: Cardano DApp Registration & Discovery +# CIP-0072: Cardano dApp Registration & Discovery ## Abstract -DApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developer needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by dApp developers. +dApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developer needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by dApp developers. This proposal aims to standardise the process of dApp registration and verification, and to provide a set of claims that dApp developers can use to register their dApp(s). ## Motivation -DApps can express a plethora of information. Some of this information could be claims about who the developer is, what the dApp's associated metadata is, and more. This data lacks standardisation, persistence, and immutability. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. +dApps can express a plethora of information. Some of this information could be claims about who the developer is, what the dApp's associated metadata is, and more. This data lacks standardisation, persistence, and immutability. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. Also, having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. -## Specification +## Glossary ### **Definitions** -- **anchor** - A hash written on-chain that can be used to verify the integrity (by way of a cryptographic hash) of the data that is found off-chain. +- **anchor** - A hash written on-chain (rootHash) that can be used to verify the integrity (by way of a cryptographic hash) of the data that is found off-chain. - **dApp** - A decentralised application that is described by the combination of metadata, certificate and a set of used scripts. - **metadata claim** - Generically any attempt to map off-chain metadata to an on-chain subject. This specification looks at dApp specific metadata claims. - **client** - Any ecosystem participant which follows on-chain data to consume metadata claims (i.e. dApp stores, wallets, auditors, block explorers, etc.). @@ -37,10 +37,10 @@ Also, having this formalisation facilitates any actor in the ecosystem to index - **auditors** - These are clients which maintain lists of trusted entities and metadata servers, checking metadata claims against these. ### **Developers / Publishers** -Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verified by stores, auditors and other ecosystem actors. +Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verified by stores, auditors and other ecosystem actors. ### **Stores / Auditors** -Stores and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. +Stores and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. ##### **Targetted Releases** Each developer and publisher can choose where to write metadata based on the information available from known stores & auditors. This gives **developers** and **publishers** the ability to perform targeted releases. (i.e to which stores and auditors). @@ -50,6 +50,9 @@ Each developer and publisher can choose where to write metadata based on the inf - **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain and publish their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. These entities could be directly associated with developer/publisher or not. ### **On-chain dApp Registration Certificate** + +The on chain dApp registration certificate MUST follow canonical JSON and be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785). This stipulation is to avoid any ambigiutines in the signature calculation. + ```json { "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", @@ -59,11 +62,9 @@ Each developer and publisher can choose where to write metadata based on the inf "https://example.com/metadata.json", "ipfs://QmWmXcRqPzJn5yDh8cXqL1oYjHr4kZx1aYQ1w1yTfTJqNn", ], - "schema_version": "0.0.1", "type": { "action": "REGISTER", - "releaseNumber": "1.0.0", - "releaseName": "My First Release", + "releaseNumber": "1.0.0" }, "signature": { "r": "5114674f1ce8a2615f2b15138944e5c58511804d72a96260ce8c587e7220daa90b9e65b450ff49563744d7633b43a78b8dc6ec3e3397b50080", @@ -75,119 +76,159 @@ Each developer and publisher can choose where to write metadata based on the inf ``` ### Properties -*`subject`*: Identifier of the claim subject (i.e dApp). A UTF-8 encoded string. This uniqueness of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. +*`subject`*: Identifier of the claim subject (dApp). A UTF-8 encoded string. This uniqueness of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist, therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. *`type`*: The type of the claim. This is a JSON object that contains the following properties: - *`action`*: The action that the certificate is asserting. It can take the following values: - *`REGISTER`*: The certificate is asserting that the dApp is being registered for the first time. - *`UPDATE`*: The certificate is asserting that the dApp is being updated. -*`rootHash`*: The hash of the metadata entire tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. +*`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. -This hash is calculated by taking the entire metadata tree object, ordering the keys in the object alphanumerically, and then hashing the resulting JSON string using the blake2b-256 hashing algorithm. The hash is encoded as a hex string. +To avoid ambiguities, the hash is calculated by taking the entire metadata tree object and it MUST be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785) compatible json format. Once serialised resulting JSON MUST be hashed using blake2b-256 hashing algorithm. The result, a hash is then encoded as a hex string. -*`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON object that contains the dApp's metadata. +*`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. *`signature`*: The signature of the certificate. The signature is done over the blake2b-256 hash of the certificate. The client should use the public key to verify the signature of the certificate. -### Certificate JSON Schema +### dApp on-chain certificate JSON Schema ```json { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://example.com/person.schema.json", - "title": "Person", - "type": "object", - "properties": { - "subject": { - "type": "string", - "description": "Can be anything. Description of the registration", + "$schema":"https://json-schema.org/draft/2019-09/schema", + "$id":"https://example.com/dApp.schema.json", + "title": "Cardano dApp Claim", + "description": "Registration of update of Cardano dApp claim.", + "type":"object", + "properties":{ + "subject":{ + "type":"string", + "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string. Typically it is randomly generated hash by the dApp developer." }, - "type": { - "type": "object", - "description": "Describes the releases, if they are new or an updates. Also states the versioning of such releases", - "properties": { - "action": { - "type": "string", - "description": "Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; or 'UPDATE' for a new release" - }, - "releaseNumber": { - "type": "string", - "description": "official version of the release" - }, - "releaseName": { - "type": "string", - "description": "Dapp release name" - } - } - }, - "rootHash": { - "type": "string", - "description": "blake2b hash of the metadata describing the dApp" + "rootHash":{ + "type":"string", + "description":"blake2b hash of the metadata describing the dApp." + }, + "metadata": { + "type": "array", + "items": { + "type": "string", + "description": "A valid url pointing to off-chain CIP-72 compatible metadata document.", + "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + } + }, + "type":{ + "type":"object", + "description":"Describes the releases, if they are new or an updates. Also states the versioning of such releases.", + "properties":{ + "action":{ + "type":"string", + "enum":["REGISTER", "UPDATE"], + "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; or 'UPDATE' for a new release" + }, + "releaseNumber":{ + "type":"string", + "description":"An official version of the release following semver format (major.minor.patch)." + }, + "releaseName":{ + "type":"string", + "description":"An optional dApp release name." + } + }, + "required":[ + "action", + "releaseNumber" + ] }, - "signature": { - "description": "Age in years which must be equal to or greater than zero.", - "type": "object", - "properties": { - "r": { - "type": "string", - "description": "hex representation of the R component of the signature" - }, - "s": { - "type": "string", - "description": "hex representation of the S component of the signature" - }, - - }, - "required": ["r", "s", "algo", "pub"] + "signature":{ + "description":"Signature of the whole canonical (RFC 8785) JSON document (except signature property).", + "type":"object", + "properties":{ + "r":{ + "type":"string", + "description":"A hex representation of the R component of the signature." + }, + "s":{ + "type":"string", + "description":"A hex representation of the S component of the signature." + }, + "algo":{ + "const":"Ed25519−EdDSA" + }, + "pub":{ + "type":"string", + "description":"A hex representation of the public key." + } + }, + "required":[ + "r", + "s", + "algo", + "pub" + ] } - }, - "required": ["subject", "rootHash","type", "signature"] + }, + "required":[ + "subject", + "rootHash", + "type", + "signature" + ] } ``` ### Metadata Label When submitting the transaction metadata pick the following value for `transaction_metadatum_label`: -- `1667`: DApp Registration +- `1667`: dApp Registration ### Off-chain Metadata Format -The Dapp Registration certificate itself doesn't enforce a particular structure to the metadata you might fetch off-chain. However, we recommend that you use the following structure: +The dApp Registration certificate itself doesn't enforce a particular structure to the metadata you might fetch off-chain. However, we recommend that you use the following structure: ```json { "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", + "type":"object", "properties": { "subject": { - "type": "string" + "type":"string", + "description": "A subject, it must match with subject stored on chain data." }, "projectName": { - "type": "string" + "type":"string", + "description": "A project name, e.g. My dApp." }, "link": { - "type": "string" + "type":"string", + "description": "Website presenting a dApp.", + "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + }, + "projectName": { + "type":"string", + "description": "A project name, e.g. My dApp." }, "logo": { - "type": "string", - "description": "URL to the logo or the base64 encoded image" + "type":"string", + "description": "URL to the logo or the base64 encoded image." }, - "category": { - "type": "string" - }, - "subCategory": { - "type": "string" + "categories": { + "type":"array", + "enum":["MARKETPLACE", "DEFI", "COLLECTION", "BRIDGE", "STABLECOIN", "NFT_MINTING_PLATFORM", "GAMING", "TOKEN_DISTRIBUTION", "COMMUNITY", "MOBILE_NETWORK", "SIDECHAIN", "LAYER_2"], + "description": "One or more categories. Category MUST be one of the following schema definition." }, "social": { - "type": "object", + "type":"object", "properties": { "twitter": { - "type": "string" + "type":"string", + "description": "An optional Twitter link." }, "github": { - "type": "string" + "type":"string", + "description": "An optional Github link." }, - "website": { - "type": "string" + "discord": { + "type":"string", + "description": "An optional Discord link." } } }, @@ -195,7 +236,16 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "type": "object", "properties": { "short": { - "type": "string" + "type": "string", + "description": "Short dApp description (No less than 40 and no longer than 168 characters).", + "minLength": 40, + "maxLength": 168 + }, + "long": { + "type": "string", + "description": "An optional long dApp description (no less than 40 and no longer than 1008 characters).", + "minLength": 40, + "maxLength": 1008 } }, "required": [ @@ -209,10 +259,12 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "type": "object", "properties": { "releaseNumber": { - "type": "integer" + "type": "string", + "description": "Semver compatible release number (major.minor.patch), e.g. 1.2.3, where 1 is major, 2 is a minor and 3 is a patch.", }, "releaseName": { - "type": "string" + "type": "string", + "description": "An optional human readable release name, e.g. V1", }, "scripts": { "type": "array", @@ -237,7 +289,6 @@ The Dapp Registration certificate itself doesn't enforce a particular structure }, "required": [ "releaseNumber", - "releaseName", "scripts" ] } @@ -248,47 +299,52 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "items": [ { "type": "object", - "properties": { + "properties":{ "id": { - "type": "string" + "type":"string", + "description": "Unique Script ID (across all scripts from this dApp).", }, - "name": { - "type": "string" + "name":{ + "type":"string", + "description": "An optional script name usually related to it's function.", }, - "purpose": { - "type": "string" + "purposes":{ + "type":"array", + "enum":["SPEND", "MINT"], + "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages).", }, - "type": { - "type": "string" + "type":{ + "enum":["PLUTUS", "NATIVE"], + "description": "Script Type. PLUTUS refers to the typical PlutusV1 or PlutusV2 scripts, where as NATIVE means there has been no Plutus directly used by this is a native script.", }, - "versions": { - "type": "array", - "items": [ + "versions":{ + "type":"array", + "items":[ { - "type": "object", - "properties": { - "version": { - "type": "integer" + "type":"object", + "properties":{ + "version":{ + "type":"integer", + "description":"Script version, monotically increasing.", }, - "plutusVersion": { - "type": "integer" + "plutusVersion":{ + "type":"integer", + "enum":[1, 2], }, - "fullScriptHash": { - "type": "string" - }, - "scriptHash": { - "type": "string" + "scriptHash":{ + "type":"string", + "description":"Full on-chain script hash (hex).", + "pattern":"[0-9a-fA-F]+" }, "contractAddress": { - "type": "string" + "type":"string", + "description":"An optional Bech32 contract address matching script's hash.", } }, "required": [ "version", "plutusVersion", - "fullScriptHash", - "scriptHash", - "contractAddress" + "scriptHash" ] } ] @@ -296,7 +352,6 @@ The Dapp Registration certificate itself doesn't enforce a particular structure }, "required": [ "id", - "name", "purpose", "type", "versions" @@ -310,8 +365,7 @@ The Dapp Registration certificate itself doesn't enforce a particular structure "projectName", "link", "social", - "category", - "subCategory", + "categories", "description", "releases", "scripts" @@ -331,17 +385,15 @@ This schema describes the minimum required fields for a store to be able to disp "logo": "https://myProject.app/logo.png", "social": { "twitter": "twiterHandle", - "github": "githubHandle", - "website": "https://website" + "github": "githubHandle" }, - "category": "GAMING", - "subCategory": "RPG", + "categories": ["GAMING"], "description": { - "short": "A story rich game where choices matter" + "short": "A story rich game where choices matter." }, "releases": [ { - "releaseNumber": 1, + "releaseNumber": "1.0.0", "releaseName": "V1", "scripts": [ { @@ -354,15 +406,14 @@ This schema describes the minimum required fields for a store to be able to disp "scripts": [ { "id": "PmNd6w", - "name": "Marketplace", + "name": "marketplace", "purpose": "SPEND", "type": "PLUTUS", "versions": [ { "version": 1, "plutusVersion": 1, - "fullScriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", - "scriptHash": "1dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", + "scriptHash": "711dcb4e80d7cd0ed384da5375661cb1e074e7feebd73eea236cd68192", "contractAddress": "addr1wywukn5q6lxsa5uymffh2esuk8s8fel7a0tna63rdntgrysv0f3ms" } ] From 0fe81290cd8d59c48988b7110b79272c19a9fa5d Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Tue, 11 Apr 2023 18:05:46 +0200 Subject: [PATCH 27/63] re-intro website + added regex patterns. --- CIP-0072/README.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 574af88ec1..fc8d319eab 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -218,19 +218,29 @@ The dApp Registration certificate itself doesn't enforce a particular structure "social": { "type":"object", "properties": { + "website": { + "type":"string", + "description": "dApps website link.", + "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + }, "twitter": { "type":"string", - "description": "An optional Twitter link." + "description": "An optional Twitter link.", + "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + }, "github": { "type":"string", - "description": "An optional Github link." + "description": "An optional Github link.", + "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" }, "discord": { "type":"string", - "description": "An optional Discord link." - } - } + "description": "An optional Discord link.", + "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + }, + }, + "required": ["website"] }, "description": { "type": "object", From 9915366c9238a07939ab5c706e09db787d36ff1a Mon Sep 17 00:00:00 2001 From: matiwinnetou Date: Wed, 12 Apr 2023 09:14:46 +0200 Subject: [PATCH 28/63] Update CIP-0072/README.md Co-authored-by: Robert Phair --- CIP-0072/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index fc8d319eab..471fa81090 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -13,8 +13,6 @@ Created: 2022-10-18 License: CC-BY-4.0 --- -# CIP-0072: Cardano dApp Registration & Discovery - ## Abstract dApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developer needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by dApp developers. From ccef79c5b503d3b3852de0fea16c2630015051d6 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 09:22:50 +0200 Subject: [PATCH 29/63] example fixes and adjusting to CIP template --- CIP-0072/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 471fa81090..df3e0014ff 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -18,12 +18,12 @@ dApp developers do not have a standardised method to record immutable, persisten This proposal aims to standardise the process of dApp registration and verification, and to provide a set of claims that dApp developers can use to register their dApp(s). -## Motivation +## Motivation: why is this CIP necessary? dApps can express a plethora of information. Some of this information could be claims about who the developer is, what the dApp's associated metadata is, and more. This data lacks standardisation, persistence, and immutability. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. Also, having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. -## Glossary +## Specification ### **Definitions** - **anchor** - A hash written on-chain (rootHash) that can be used to verify the integrity (by way of a cryptographic hash) of the data that is found off-chain. @@ -225,7 +225,6 @@ The dApp Registration certificate itself doesn't enforce a particular structure "type":"string", "description": "An optional Twitter link.", "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" - }, "github": { "type":"string", @@ -392,8 +391,9 @@ This schema describes the minimum required fields for a store to be able to disp "link": "https://myProject.app", "logo": "https://myProject.app/logo.png", "social": { - "twitter": "twiterHandle", - "github": "githubHandle" + "github": "https://mywebsite.com", + "twitter": "https://twitter.com/my_dapp", + "github": "https://github.com/my_dapp" }, "categories": ["GAMING"], "description": { @@ -415,7 +415,7 @@ This schema describes the minimum required fields for a store to be able to disp { "id": "PmNd6w", "name": "marketplace", - "purpose": "SPEND", + "purposes": ["SPEND"], "type": "PLUTUS", "versions": [ { @@ -441,3 +441,4 @@ There are multiple options to store metadata offchain. The most common options a - [Bitbucket](https://bitbucket.org/) - Any REST JSON API + From d6be21eb5590f6a61777c2f305110cf059cd986a Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 09:27:20 +0200 Subject: [PATCH 30/63] added placeholders --- CIP-0072/README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index df3e0014ff..1098efd9c2 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -244,7 +244,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "properties": { "short": { "type": "string", - "description": "Short dApp description (No less than 40 and no longer than 168 characters).", + "description": "Short dApp description (no less than 40 and no longer than 168 characters).", "minLength": 40, "maxLength": 168 }, @@ -441,4 +441,15 @@ There are multiple options to store metadata offchain. The most common options a - [Bitbucket](https://bitbucket.org/) - Any REST JSON API - +## Rationale: how does this CIP achieve its goals? +TODO +## Path to Active +TODO +### Acceptance Criteria +TODO +### Implementation Plan +N/A + +## Copyright +[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode +[Apache-2.0]: http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file From 3db07933c58b04e5496b9c22e8623cffb4432179 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 09:58:54 +0200 Subject: [PATCH 31/63] added rationale section --- CIP-0072/README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 1098efd9c2..bab4ffac89 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -442,7 +442,35 @@ There are multiple options to store metadata offchain. The most common options a - Any REST JSON API ## Rationale: how does this CIP achieve its goals? -TODO + +### Decoupling of dApp registration from certifications / audits +We quickly reached a conclusion that it is better to separate them and keep scope of CIP smaller. During discussions it became clear that while there is +some overlap of certifications / audits with dApp registration, this overlap is small and can be even removed. At one point we wanted to couple +certifications CIP to this CIP (e.g. via some link or dApp version) but we analyzed how dApp developers are currently following the process and we noticed +that in many cases certification / audit comes before an official dApp release on main-net. Having established it, we removed this link and not only +that dApp registration and certifications are different CIPs but they are very loosely coupled. Loose coupling has also disadvantages as it leads to a situation that in order to attest that a dApp is certified / audited, implementators will have to scan for all script hashes belonging to a dApp and check +whether those have been certified / explicitly mentioned in the audit. + +### Small metadata anchor on chain +We analyzed how much we should put on-chain vs off-chain and we quickly reached the conclusion that it is better to keep small amount of data on-chain and larger chunk off-chain for which e.g. CIP-26 is meant for. + +### CIP-26 as NOT the only storage layer +We believe that CIP-26 is geared towards storing this type of off-chain metadata format but we don't want by any means to stipulate / police this form of storage. In fact it is possible to use alternatives such as direct http hosting / REST API/ IPFS / git, etc. + +### How to find off-chain data? +We went back and forth whether we should actually store link (links) to off-chain metadata, eventually we settled on a solution that this is required +because there could be a situation that a dApp registration may not have even one offchain metadata, situation far from ideal for anybody willing to reason about this data. + +### Simple dApp registration +It has been debated whether scripts / versions should be mandatory. There are use cases which require only basic dApp information, such as dApp developer, website, twitter link, etc, there are, however, also use cases that require analysing of this dApp performance data and basic information won't suffice. To encourage dApps to share scripts (which are hard to reverse engineer and analyse) for the moment this CIP enforces and makes it a requirement to list +all scripts including all script hashes belonging to a dApp. + +### Optional release name? +Release Name is a field, which dApp developers can use on top of release version, it has been debated whether field should be mandatory or optional but eventually it has been agreed that we do not want to enforce this field, dapp release is an optional field, dApp version, however, needs to follow semver and is a mandatory field. + + + ## Path to Active TODO ### Acceptance Criteria From ffc245ca62eb2d36dae54969f809796c837410b1 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 10:03:28 +0200 Subject: [PATCH 32/63] fixes in rationale section --- CIP-0072/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index bab4ffac89..647afb6387 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -452,14 +452,14 @@ that dApp registration and certifications are different CIPs but they are very l whether those have been certified / explicitly mentioned in the audit. ### Small metadata anchor on chain -We analyzed how much we should put on-chain vs off-chain and we quickly reached the conclusion that it is better to keep small amount of data on-chain and larger chunk off-chain for which e.g. CIP-26 is meant for. +We analyzed how much we should put on-chain vs off-chain and we quickly reached the conclusion that it is better to keep small amount of data on-chain and larger chunk off-chain for which is what exactly CIP-26 is meant for. ### CIP-26 as NOT the only storage layer -We believe that CIP-26 is geared towards storing this type of off-chain metadata format but we don't want by any means to stipulate / police this form of storage. In fact it is possible to use alternatives such as direct http hosting / REST API/ IPFS / git, etc. +We believe that CIP-26 is geared towards storing this type of off-chain metadata format but we don't want by any means to stipulate / police this form of storage. In fact it is possible to use offchain metadata storage alternatives such as direct http hosting / REST API/ IPFS / git, etc. ### How to find off-chain data? We went back and forth whether we should actually store link (links) to off-chain metadata, eventually we settled on a solution that this is required -because there could be a situation that a dApp registration may not have even one offchain metadata, situation far from ideal for anybody willing to reason about this data. +because there could be a situation that a dApp registration may have off-chain metadata stored somewhere but some stores have it, others don't have it. Now it is required that a dApp developer points to at least one store that has off-chain metadata (as a reference). ### Simple dApp registration It has been debated whether scripts / versions should be mandatory. There are use cases which require only basic dApp information, such as dApp developer, website, twitter link, etc, there are, however, also use cases that require analysing of this dApp performance data and basic information won't suffice. To encourage dApps to share scripts (which are hard to reverse engineer and analyse) for the moment this CIP enforces and makes it a requirement to list From 8f976edf6843169c83cdd830c41f39cfbce9d7c6 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 10:30:41 +0200 Subject: [PATCH 33/63] more rationale --- CIP-0072/README.md | 49 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 647afb6387..bf2201319b 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -443,7 +443,7 @@ There are multiple options to store metadata offchain. The most common options a ## Rationale: how does this CIP achieve its goals? -### Decoupling of dApp registration from certifications / audits +### Decoupling of dApp Registration From Certifications / Audits We quickly reached a conclusion that it is better to separate them and keep scope of CIP smaller. During discussions it became clear that while there is some overlap of certifications / audits with dApp registration, this overlap is small and can be even removed. At one point we wanted to couple certifications CIP to this CIP (e.g. via some link or dApp version) but we analyzed how dApp developers are currently following the process and we noticed @@ -451,23 +451,54 @@ that in many cases certification / audit comes before an official dApp release o that dApp registration and certifications are different CIPs but they are very loosely coupled. Loose coupling has also disadvantages as it leads to a situation that in order to attest that a dApp is certified / audited, implementators will have to scan for all script hashes belonging to a dApp and check whether those have been certified / explicitly mentioned in the audit. -### Small metadata anchor on chain -We analyzed how much we should put on-chain vs off-chain and we quickly reached the conclusion that it is better to keep small amount of data on-chain and larger chunk off-chain for which is what exactly CIP-26 is meant for. +### Small Metadata Anchor On Chain +This one is rather obvious but for the sake of completeness worth documenting. We analyzed how much we should put on-chain vs off-chain and we quickly reached the conclusion that it is better to keep small amount of data on-chain and larger chunk off-chain for which is what exactly CIP-26 is meant for. -### CIP-26 as NOT the only storage layer +### CIP-26 as *ONE* of Storage Layers We believe that CIP-26 is geared towards storing this type of off-chain metadata format but we don't want by any means to stipulate / police this form of storage. In fact it is possible to use offchain metadata storage alternatives such as direct http hosting / REST API/ IPFS / git, etc. -### How to find off-chain data? +### How to Find Off-Chain Data? We went back and forth whether we should actually store link (links) to off-chain metadata, eventually we settled on a solution that this is required -because there could be a situation that a dApp registration may have off-chain metadata stored somewhere but some stores have it, others don't have it. Now it is required that a dApp developer points to at least one store that has off-chain metadata (as a reference). +because there could be a situation that a dApp registration may have off-chain metadata stored somewhere but some stores have it, others don't have it. Now it is required that a dApp developer points to at least one store that has off-chain metadata (as a reference metadata). -### Simple dApp registration -It has been debated whether scripts / versions should be mandatory. There are use cases which require only basic dApp information, such as dApp developer, website, twitter link, etc, there are, however, also use cases that require analysing of this dApp performance data and basic information won't suffice. To encourage dApps to share scripts (which are hard to reverse engineer and analyse) for the moment this CIP enforces and makes it a requirement to list +### Limited fields dApp Registration (what is mandatory / what is not) +It has been debated whether scripts / versions should NOT be mandatory. There are use cases which require only basic dApp information, such as dApp developer, website, twitter link, etc, there are, however, also use cases that require analysing of this dApp performance data and basic information won't suffice. To encourage dApps to share scripts (which are hard to reverse engineer and analyse) for the moment this CIP enforces and makes it a requirement to list all scripts including all script hashes belonging to a dApp. -### Optional release name? +### Optional Release Name? Release Name is a field, which dApp developers can use on top of release version, it has been debated whether field should be mandatory or optional but eventually it has been agreed that we do not want to enforce this field, dapp release is an optional field, dApp version, however, needs to follow semver and is a mandatory field. +### Canonical JSON +At the begining neither on-chain, nor off-chain storage has been following RFC 8785 (canonical json) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted +according to RFC 8785 before taking a blake2b-256 hash of it. + +### On-Chain Signature Controversy +On-chain part has a signature, which has a role to assign owner +It has been debated whether it is enough to just + +### Who Is The Owner? +Smart contracts are ownerless, it has been debated that there could be multiple claims to the same dApps from different parties. + +She standard doesn't prevent anyone from making a claim, so it's up to the different operator to their diligence work and make their own choices of whom they trust. The signature should give the most confidence as anyone can collect known public keys from known devs (i.e sundaeswap, minswap, wingriders, etc ). Future CIP revisions can include DID's and Verifiable Credentials. + +### DIDs +Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, usage of them in this initial CIP version has been descoped. + +### Category +Category is a predefined enum with values defined in the CIP / schema, it is *NOT* a free text field, rationale for this is that dApp developers will have no idea what ontology / classification to use, which will likely result in many duplicates of the same thing. + +### Purpouse Field As an Array or as a Single Item? +It may have been visible that we have a `purpose` field, which can be: "SPEND" or "MINT", those fields directly map to what is allowed by a Cardano Smart Contract. As of the time of writing CIP - PlutusTx does not allow a script to be both of type: "SPEND" and "MINT", however, there are new +languages on Cardano being worked on where they already allow one validator to be both spending UTxOs and minting tokens - all with the same script hash. To be open for the future it has been agreed to turn `purpouse` field into `purpouses` and make it a json array. + +### Parametrised Scripts +On Cardano, there are parametrised scripts, meaning that before compilation takes place, it is possible to pass certain parameters instead of using `Datum`. +The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't see that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION or an UPDATE to the existing dApp. + +### Often Changing Scripts +There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide off-chain metadata following the change, for scripts that are changing daily / hourly it is +envisaged that this process be automated by a dApp developer. + From 1ac12627c45aac1828b06621b35b71ae2deca9ee Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 10:42:43 +0200 Subject: [PATCH 34/63] fixed on-chain signature scope --- CIP-0072/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index bf2201319b..fece60254d 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -472,9 +472,8 @@ Release Name is a field, which dApp developers can use on top of release version At the begining neither on-chain, nor off-chain storage has been following RFC 8785 (canonical json) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted according to RFC 8785 before taking a blake2b-256 hash of it. -### On-Chain Signature Controversy -On-chain part has a signature, which has a role to assign owner -It has been debated whether it is enough to just +### On-Chain Signature Scope +On-chain part has a signature, which has a role to verify that a certain dApp owner made changes. In the initial version, a blake2b-256 signature was needed only for `rootHash` but following discussion, due to security concerns, decision has been made that the signature should attest the whole on-chain canonical json except signature field itself (because it would end up in an infinite recursion). ### Who Is The Owner? Smart contracts are ownerless, it has been debated that there could be multiple claims to the same dApps from different parties. From 8ef196ac1fde35f72e7c1ac3488b069659ef277e Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 11:12:50 +0200 Subject: [PATCH 35/63] categories --- CIP-0072/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index fece60254d..c7414daf29 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -483,8 +483,8 @@ She standard doesn't prevent anyone from making a claim, so it's up to the diffe ### DIDs Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, usage of them in this initial CIP version has been descoped. -### Category -Category is a predefined enum with values defined in the CIP / schema, it is *NOT* a free text field, rationale for this is that dApp developers will have no idea what ontology / classification to use, which will likely result in many duplicates of the same thing. +### Categories +`Categories` is a predefined enum with values defined in the CIP / schema, it is *NOT* a free text field, rationale for this is that dApp developers will have no idea what ontology / classification to use, which will likely result in many duplicates of the same thing. ### Purpouse Field As an Array or as a Single Item? It may have been visible that we have a `purpose` field, which can be: "SPEND" or "MINT", those fields directly map to what is allowed by a Cardano Smart Contract. As of the time of writing CIP - PlutusTx does not allow a script to be both of type: "SPEND" and "MINT", however, there are new From abd0f4f3ac713803236c6c3ec0421ade6ff6220d Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 11:14:17 +0200 Subject: [PATCH 36/63] typo fixes --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index c7414daf29..473eb85d55 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -478,7 +478,7 @@ On-chain part has a signature, which has a role to verify that a certain dApp ow ### Who Is The Owner? Smart contracts are ownerless, it has been debated that there could be multiple claims to the same dApps from different parties. -She standard doesn't prevent anyone from making a claim, so it's up to the different operator to their diligence work and make their own choices of whom they trust. The signature should give the most confidence as anyone can collect known public keys from known devs (i.e sundaeswap, minswap, wingriders, etc ). Future CIP revisions can include DID's and Verifiable Credentials. +The standard doesn't prevent anyone from making a claim, so it's up to the different operator to their diligence work and make their own choices of whom they trust. The signature should give the most confidence as anyone can collect known public keys from known development companies. Future CIP revisions can include DID's and Verifiable Credentials to tackle this problem in a more elegant way. ### DIDs Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, usage of them in this initial CIP version has been descoped. From 08b0187c7725d376caede2a9e9832bbd0b87dc0b Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 11:40:34 +0200 Subject: [PATCH 37/63] word wrapping test --- CIP-0072/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 473eb85d55..95b75be887 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -495,8 +495,7 @@ On Cardano, there are parametrised scripts, meaning that before compilation take The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't see that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION or an UPDATE to the existing dApp. ### Often Changing Scripts -There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide off-chain metadata following the change, for scripts that are changing daily / hourly it is -envisaged that this process be automated by a dApp developer. +There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. From 0c8db08e65f8f185efdb74a23a06de7885208902 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 11:43:20 +0200 Subject: [PATCH 38/63] cosmetics --- CIP-0072/README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 95b75be887..655f427b0e 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -495,10 +495,7 @@ On Cardano, there are parametrised scripts, meaning that before compilation take The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't see that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION or an UPDATE to the existing dApp. ### Often Changing Scripts -There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. - - +There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide on-chain and off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. ## Path to Active TODO From d368c32f274efda3c3a17aedbc7d41e434150b2c Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 11:44:55 +0200 Subject: [PATCH 39/63] cosmetics --- CIP-0072/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 655f427b0e..7a901b38da 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -83,7 +83,7 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser *`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. -To avoid ambiguities, the hash is calculated by taking the entire metadata tree object and it MUST be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785) compatible json format. Once serialised resulting JSON MUST be hashed using blake2b-256 hashing algorithm. The result, a hash is then encoded as a hex string. +To avoid ambiguities, the hash is calculated by taking the entire metadata tree object and it MUST be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785) compatible JSON format. Once serialised resulting JSON MUST be hashed using blake2b-256 hashing algorithm. The result, a hash is then encoded as a hex string. *`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. @@ -469,11 +469,11 @@ all scripts including all script hashes belonging to a dApp. Release Name is a field, which dApp developers can use on top of release version, it has been debated whether field should be mandatory or optional but eventually it has been agreed that we do not want to enforce this field, dapp release is an optional field, dApp version, however, needs to follow semver and is a mandatory field. ### Canonical JSON -At the begining neither on-chain, nor off-chain storage has been following RFC 8785 (canonical json) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted +At the begining neither on-chain, nor off-chain storage has been following RFC 8785 (canonical JSON) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted according to RFC 8785 before taking a blake2b-256 hash of it. ### On-Chain Signature Scope -On-chain part has a signature, which has a role to verify that a certain dApp owner made changes. In the initial version, a blake2b-256 signature was needed only for `rootHash` but following discussion, due to security concerns, decision has been made that the signature should attest the whole on-chain canonical json except signature field itself (because it would end up in an infinite recursion). +On-chain part has a signature, which has a role to verify that a certain dApp owner made changes. In the initial version, a blake2b-256 signature was needed only for `rootHash` but following discussion, due to security concerns, decision has been made that the signature should attest the whole on-chain canonical JSON except signature field itself (because it would end up in an infinite recursion). ### Who Is The Owner? Smart contracts are ownerless, it has been debated that there could be multiple claims to the same dApps from different parties. @@ -488,7 +488,7 @@ Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, ### Purpouse Field As an Array or as a Single Item? It may have been visible that we have a `purpose` field, which can be: "SPEND" or "MINT", those fields directly map to what is allowed by a Cardano Smart Contract. As of the time of writing CIP - PlutusTx does not allow a script to be both of type: "SPEND" and "MINT", however, there are new -languages on Cardano being worked on where they already allow one validator to be both spending UTxOs and minting tokens - all with the same script hash. To be open for the future it has been agreed to turn `purpouse` field into `purpouses` and make it a json array. +languages on Cardano being worked on where they already allow one validator to be both spending UTxOs and minting tokens - all with the same script hash. To be open for the future it has been agreed to turn `purpouse` field into `purpouses` and make it a JSON array. ### Parametrised Scripts On Cardano, there are parametrised scripts, meaning that before compilation takes place, it is possible to pass certain parameters instead of using `Datum`. From b03411062c486241e9042dde39b0d1addb071d6c Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 13:11:23 +0200 Subject: [PATCH 40/63] Path to Active --- CIP-0072/README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 7a901b38da..5579ffe953 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -498,9 +498,17 @@ The consequence of this will be that as we pass different parameters, script has There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide on-chain and off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. ## Path to Active -TODO + ### Acceptance Criteria -TODO + +Currently CIP is available for: +- a review for dApp developers +- there is an open point, whether this CIP should be the first to have semver schema version (requires agreement on schema versions in CIPs first) +- `categories` field (enum) white list needs revision, current one is a proposal only +- authors need to go again through all comments on github and see if they have not missed something + +Once those remaining items are done, CIP can be merged and activated. There were no major disagreements on the last CIP editor meeting apart from a few small TODO comments mentioned above. + ### Implementation Plan N/A From 66f5d6e04377b968182f5916e022a0fd01e59bd9 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 12 Apr 2023 14:06:04 +0200 Subject: [PATCH 41/63] more community comments --- CIP-0072/README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 5579ffe953..10b60e05a7 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -87,7 +87,7 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree *`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. -*`signature`*: The signature of the certificate. The signature is done over the blake2b-256 hash of the certificate. The client should use the public key to verify the signature of the certificate. +*`signature`*: The signature of the certificate. The signature is done over whole on-chain JSON (canonical) without the signature part. The client should use the public key to verify the signature of the certificate. Fields used for signature: ["subject", "rootHash", "metadata", "type"]. ### dApp on-chain certificate JSON Schema ```json @@ -497,6 +497,18 @@ The consequence of this will be that as we pass different parameters, script has ### Often Changing Scripts There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide on-chain and off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. +### Beacon Tokens Instead of Metadata +It has been argued that since anybody can make claims to dApps, this CIP instead of using metadata should use tokens. dApp developers +would mint token, which would ensure they are the owners of a given dApp. It is a certainly an interesting approach but shortcomings +of the current solution can also be lifted by moving to DID based system and benefit of metadata is that it is easily queriable off chain +and currently stores can attest / validate multiple claims for the same dApp. Forcing dApp developers to MINT tokens would complicate this CIP +and potentially hinder it's adoption. + +### Datums Instead of Metadata +It has been suggested that we do not use metadata but rather Datums. Metadata cannot enforce format and Datums could. It has been rejected as +using Datums requires a smart contract and we want to keep this solution as accessible as possible. It is a GUI concern since if there is a +some app that can attest validity and conformance to JSON schema - dApp Registration / Update MUST never be done that does not conform to the schema. + ## Path to Active ### Acceptance Criteria @@ -505,10 +517,11 @@ Currently CIP is available for: - a review for dApp developers - there is an open point, whether this CIP should be the first to have semver schema version (requires agreement on schema versions in CIPs first) - `categories` field (enum) white list needs revision, current one is a proposal only -- authors need to go again through all comments on github and see if they have not missed something Once those remaining items are done, CIP can be merged and activated. There were no major disagreements on the last CIP editor meeting apart from a few small TODO comments mentioned above. +Last but not least, PR needs to be open and officially add 1667 metadata label to the registry here: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json + ### Implementation Plan N/A From 21698a39c6c65568bf19a79ece3f294e1483c207 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 13 Apr 2023 15:45:36 +0200 Subject: [PATCH 42/63] Fixes according to feedback --- CIP-0072/README.md | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 10b60e05a7..69a482dc1c 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -2,7 +2,8 @@ CIP: 72 Title: Cardano dApp Registration & Discovery Status: Proposed -Category: Metadata +Category: Metadata +Version: "1.0.0" Authors: - Bruno Martins - Mateusz Czeladka @@ -55,12 +56,13 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser { "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", + "version": "1.0.0", "metadata": [ "https://cip26.foundation.app/properties/d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", "https://example.com/metadata.json", - "ipfs://QmWmXcRqPzJn5yDh8cXqL1oYjHr4kZx1aYQ1w1yTfTJqNn", + "https://ipfs.blockfrost.io/api/v0/QmWmXcRqPzJn5yDh8cXqL1oYjHr4kZx1aYQ1w1yTfTJqNn", ], - "type": { + "type": { "action": "REGISTER", "releaseNumber": "1.0.0" }, @@ -80,6 +82,7 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser - *`action`*: The action that the certificate is asserting. It can take the following values: - *`REGISTER`*: The certificate is asserting that the dApp is being registered for the first time. - *`UPDATE`*: The certificate is asserting that the dApp is being updated. + - *`DE-REGISTER`*: The certificate is asserting that the dApp is being removed and authors wish it should not longer show on stores. *`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. @@ -111,7 +114,7 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree "items": { "type": "string", "description": "A valid url pointing to off-chain CIP-72 compatible metadata document.", - "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" } }, "type":{ @@ -120,8 +123,8 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree "properties":{ "action":{ "type":"string", - "enum":["REGISTER", "UPDATE"], - "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; or 'UPDATE' for a new release" + "enum":["REGISTER", "UPDATE", "DE-REGISTER"], + "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; 'UPDATE' for a new release or 'DE-REGISTER' for dApp de-listing request." }, "releaseNumber":{ "type":"string", @@ -198,7 +201,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "link": { "type":"string", "description": "Website presenting a dApp.", - "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" }, "projectName": { "type":"string", @@ -210,7 +213,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure }, "categories": { "type":"array", - "enum":["MARKETPLACE", "DEFI", "COLLECTION", "BRIDGE", "STABLECOIN", "NFT_MINTING_PLATFORM", "GAMING", "TOKEN_DISTRIBUTION", "COMMUNITY", "MOBILE_NETWORK", "SIDECHAIN", "LAYER_2"], + "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"], "description": "One or more categories. Category MUST be one of the following schema definition." }, "social": { @@ -219,22 +222,22 @@ The dApp Registration certificate itself doesn't enforce a particular structure "website": { "type":"string", "description": "dApps website link.", - "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" }, "twitter": { "type":"string", "description": "An optional Twitter link.", - "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" }, "github": { "type":"string", "description": "An optional Github link.", - "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" }, "discord": { "type":"string", "description": "An optional Discord link.", - "pattern": "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})" + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" }, }, "required": ["website"] @@ -295,8 +298,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure } }, "required": [ - "releaseNumber", - "scripts" + "releaseNumber" ] } ] @@ -375,7 +377,6 @@ The dApp Registration certificate itself doesn't enforce a particular structure "categories", "description", "releases", - "scripts" ] } ``` @@ -393,7 +394,7 @@ This schema describes the minimum required fields for a store to be able to disp "social": { "github": "https://mywebsite.com", "twitter": "https://twitter.com/my_dapp", - "github": "https://github.com/my_dapp" + "website": "https://github.com/my_dapp" }, "categories": ["GAMING"], "description": { From f8e31278ca6b434e3e125443b81e4d5d61715b01 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 13 Apr 2023 15:59:30 +0200 Subject: [PATCH 43/63] CIP version is mandatory, releases is optional, new algo to calculate signature --- CIP-0072/README.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 69a482dc1c..f2c464b21c 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -90,7 +90,7 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree *`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. -*`signature`*: The signature of the certificate. The signature is done over whole on-chain JSON (canonical) without the signature part. The client should use the public key to verify the signature of the certificate. Fields used for signature: ["subject", "rootHash", "metadata", "type"]. +*`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "version", "rootHash", "metadata","type"]. ### dApp on-chain certificate JSON Schema ```json @@ -117,6 +117,11 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" } }, + "version": { + "type": "string", + "description":"CIP version (semver).", + "pattern": "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[a-zA-Z\\d][-a-zA-Z.\\d]*)?(\\+[a-zA-Z\\d][-a-zA-Z.\\d]*)?" + }, "type":{ "type":"object", "description":"Describes the releases, if they are new or an updates. Also states the versioning of such releases.", @@ -128,7 +133,8 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree }, "releaseNumber":{ "type":"string", - "description":"An official version of the release following semver format (major.minor.patch)." + "description":"An official version of the release following semver format (major.minor.patch).", + "pattern": "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[a-zA-Z\\d][-a-zA-Z.\\d]*)?(\\+[a-zA-Z\\d][-a-zA-Z.\\d]*)?" }, "releaseName":{ "type":"string", @@ -171,6 +177,7 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree "required":[ "subject", "rootHash", + "version", "type", "signature" ] @@ -213,7 +220,10 @@ The dApp Registration certificate itself doesn't enforce a particular structure }, "categories": { "type":"array", - "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"], + "items": { + "type": "string", + "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"] + }, "description": "One or more categories. Category MUST be one of the following schema definition." }, "social": { @@ -319,7 +329,10 @@ The dApp Registration certificate itself doesn't enforce a particular structure }, "purposes":{ "type":"array", - "enum":["SPEND", "MINT"], + "items": { + "type": "string", + "enum":["SPEND", "MINT"] + }, "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages).", }, "type":{ @@ -361,7 +374,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure }, "required": [ "id", - "purpose", + "purposes", "type", "versions" ] @@ -375,8 +388,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "link", "social", "categories", - "description", - "releases", + "description" ] } ``` @@ -396,9 +408,9 @@ This schema describes the minimum required fields for a store to be able to disp "twitter": "https://twitter.com/my_dapp", "website": "https://github.com/my_dapp" }, - "categories": ["GAMING"], + "categories": ["Games"], "description": { - "short": "A story rich game where choices matter." + "short": "A story rich game where choices matter. This game is very addictive to play :)" }, "releases": [ { From f5efd4e2c8c7781ccf8e5627c9bc98f5d3564ee1 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 13 Apr 2023 16:03:34 +0200 Subject: [PATCH 44/63] signature generation: hex vs byte array clarification --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index f2c464b21c..087386f7da 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -90,7 +90,7 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree *`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. -*`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "version", "rootHash", "metadata","type"]. +*`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "version", "rootHash", "metadata","type"]. Please note that a signature should be generated of blake2b-256 hash as a byte array, not as a hex represented string(!). ### dApp on-chain certificate JSON Schema ```json From fca54d865b040c072876aecd0651a5d6e612c8cf Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 13 Apr 2023 16:10:40 +0200 Subject: [PATCH 45/63] formatting fixes --- CIP-0072/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 087386f7da..dfd1311088 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -54,11 +54,11 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser ```json { - "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", - "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", + "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", + "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", "version": "1.0.0", "metadata": [ - "https://cip26.foundation.app/properties/d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", + "https://cip26.foundation.app/properties/d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", "https://example.com/metadata.json", "https://ipfs.blockfrost.io/api/v0/QmWmXcRqPzJn5yDh8cXqL1oYjHr4kZx1aYQ1w1yTfTJqNn", ], From 4dbb2e0a50a96c9aa5fb0e4bb534211820f2b11e Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 13 Apr 2023 16:23:23 +0200 Subject: [PATCH 46/63] added version description and more decisions rationale --- CIP-0072/README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index dfd1311088..48390d9322 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -86,7 +86,7 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser *`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. -To avoid ambiguities, the hash is calculated by taking the entire metadata tree object and it MUST be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785) compatible JSON format. Once serialised resulting JSON MUST be hashed using blake2b-256 hashing algorithm. The result, a hash is then encoded as a hex string. +*`version`*: CIP version, which version of the CIP was the on-chain certificate generated from. This is very much needed for stores and clients to know what rules they should apply for a given REGISTRATION / UPDATE. *`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. @@ -147,7 +147,7 @@ To avoid ambiguities, the hash is calculated by taking the entire metadata tree ] }, "signature":{ - "description":"Signature of the whole canonical (RFC 8785) JSON document (except signature property).", + "description":"Signature of the blake2b-256 hash of whole canonical (RFC 8785) JSON document (except signature property).", "type":"object", "properties":{ "r":{ @@ -522,6 +522,23 @@ It has been suggested that we do not use metadata but rather Datums. Metadata ca using Datums requires a smart contract and we want to keep this solution as accessible as possible. It is a GUI concern since if there is a some app that can attest validity and conformance to JSON schema - dApp Registration / Update MUST never be done that does not conform to the schema. +### Scripts / Releases Fields Are Not Required +We made a decision to change the schema so that scripts and releases are no longer required. This could help to get initial registration from dApp developers faster and +some stores simply do not require dApps to add their scripts in order to be listed. + +### Schema Version or CIP Version +We want to take schema version further and actually attest the whole CIP version so we are introducing a top level field: version. Any changes to the document will require bumping the version. CIP version needs to be also +propagated in the on-chain JSON itself. + +### Tags +We briefly discussed tags and we will likely introduce tags in the near future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. + +### DE-REGISTER +We added DE-REGISTER in additon to `REGISTER` abnd `UPDATE`. The idea is that once dApp devs do not want their dApp to be shown, they can now unlist a dApp and stores should respect such a request. + +### Type Field +`Type` field can be `PLUTUS` or `NATIVE`, we made it optional and there are already two dApps at least on Cardano at the time of writing, which are only using NATIVE scripts. This optional field helps to differentiante between NATIVE script based and NON_NATIVE dApps. + ## Path to Active ### Acceptance Criteria From c2d7e2874a6bf02dfd25f57c25953480a7bd9369 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 13 Apr 2023 16:39:41 +0200 Subject: [PATCH 47/63] typo fix --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 48390d9322..e1c54a3c8a 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -483,7 +483,7 @@ Release Name is a field, which dApp developers can use on top of release version ### Canonical JSON At the begining neither on-chain, nor off-chain storage has been following RFC 8785 (canonical JSON) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted -according to RFC 8785 before taking a blake2b-256 hash of it. +according to RFC 8785 before taking a blake2b-256 hash of them. ### On-Chain Signature Scope On-chain part has a signature, which has a role to verify that a certain dApp owner made changes. In the initial version, a blake2b-256 signature was needed only for `rootHash` but following discussion, due to security concerns, decision has been made that the signature should attest the whole on-chain canonical JSON except signature field itself (because it would end up in an infinite recursion). From b4e9ad024b3888382fbdf779a9fa723119ccc6c8 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Mon, 17 Apr 2023 10:12:11 +0200 Subject: [PATCH 48/63] Fixed patterns for hex strings, added changed DE-REGISTER to DE_REGISTER and added new DE_REGISTER_ALL, schema version changed from 04 to 2019-07. --- CIP-0072/README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index e1c54a3c8a..7aafb08d1c 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -82,9 +82,10 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser - *`action`*: The action that the certificate is asserting. It can take the following values: - *`REGISTER`*: The certificate is asserting that the dApp is being registered for the first time. - *`UPDATE`*: The certificate is asserting that the dApp is being updated. - - *`DE-REGISTER`*: The certificate is asserting that the dApp is being removed and authors wish it should not longer show on stores. + - *`DE_REGISTER`*: The certificate is asserting that the dApp version is being removed and it is requested that stores no longer show it. + - *`DE_REGISTER_ALL`*: The certificate is asserting that all dApp version are being removed and it is requested that stores no longer show it. -*`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. +*`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. Please note that off-chain JSON must be converted into RFC 8765 canonical form before taking the hash! *`version`*: CIP version, which version of the CIP was the on-chain certificate generated from. This is very much needed for stores and clients to know what rules they should apply for a given REGISTRATION / UPDATE. @@ -128,8 +129,8 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser "properties":{ "action":{ "type":"string", - "enum":["REGISTER", "UPDATE", "DE-REGISTER"], - "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; 'UPDATE' for a new release or 'DE-REGISTER' for dApp de-listing request." + "enum":["REGISTER", "UPDATE", "DE_REGISTER", "DE_REGISTER_ALL"], + "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; 'UPDATE' for a new release or 'DE_REGISTER' for dApp version de-listing request and DE_REGISTER_ALL if a dApp developer wants to de-register all dApp versions in one call." }, "releaseNumber":{ "type":"string", @@ -152,18 +153,21 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser "properties":{ "r":{ "type":"string", - "description":"A hex representation of the R component of the signature." + "description":"A hex representation of the R component of the signature.", + "pattern":"[0-9a-fA-F]+" }, "s":{ "type":"string", - "description":"A hex representation of the S component of the signature." + "description":"A hex representation of the S component of the signature.", + "pattern":"[0-9a-fA-F]+" }, "algo":{ "const":"Ed25519−EdDSA" }, "pub":{ "type":"string", - "description":"A hex representation of the public key." + "description":"A hex representation of the public key.", + "pattern":"[0-9a-fA-F]+" } }, "required":[ @@ -194,7 +198,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure ```json { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "https://json-schema.org/draft/2019-09/schema", "type":"object", "properties": { "subject": { @@ -533,8 +537,8 @@ propagated in the on-chain JSON itself. ### Tags We briefly discussed tags and we will likely introduce tags in the near future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. -### DE-REGISTER -We added DE-REGISTER in additon to `REGISTER` abnd `UPDATE`. The idea is that once dApp devs do not want their dApp to be shown, they can now unlist a dApp and stores should respect such a request. +### DE_REGISTER +We added DE_REGISTER and DE_REGISTER_ALL in additon to already existing `REGISTER` and `UPDATE`. The idea is that once dApp devs do not want their dApp version to be shown, they can now unlist a whole dApp or a dApp version and stores should respect such a request. ### Type Field `Type` field can be `PLUTUS` or `NATIVE`, we made it optional and there are already two dApps at least on Cardano at the time of writing, which are only using NATIVE scripts. This optional field helps to differentiante between NATIVE script based and NON_NATIVE dApps. From 92e5bdc85cec737a929a817d0d16684e207be1ef Mon Sep 17 00:00:00 2001 From: Volodymyr Hulchenko <57362128+vhulchenko-iohk@users.noreply.github.com> Date: Thu, 20 Apr 2023 14:12:11 +0300 Subject: [PATCH 49/63] fixed several outdated things across CIP (#16) * removed several outdated things across CIP * addressed all comments on initial commit --- CIP-0072/README.md | 51 +++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 7aafb08d1c..67a937de1f 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -15,7 +15,7 @@ License: CC-BY-4.0 --- ## Abstract -dApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developer needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) and for users to verify the claims made by dApp developers. +dApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developer needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) on-chain and for users to verify the claims made by dApp developers. This proposal aims to standardise the process of dApp registration and verification, and to provide a set of claims that dApp developers can use to register their dApp(s). @@ -32,8 +32,7 @@ Also, having this formalisation facilitates any actor in the ecosystem to index - **metadata claim** - Generically any attempt to map off-chain metadata to an on-chain subject. This specification looks at dApp specific metadata claims. - **client** - Any ecosystem participant which follows on-chain data to consume metadata claims (i.e. dApp stores, wallets, auditors, block explorers, etc.). - **dApp Store** - A dApp aggregator application which follows on-chain data looking for and verifying dApp metadata claims, serving their users linked dApp metadata. -- **publishers** - Entities which publish metadata claims on-chain, in the case of dApps the publishers are likely the dApp developer(s). -- **auditors** - These are clients which maintain lists of trusted entities and metadata servers, checking metadata claims against these. +- **publishers** - Entities which publish metadata claims on-chain, in the case of dApps the publishers are likely the dApp developer(s). ### **Developers / Publishers** Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verified by stores, auditors and other ecosystem actors. @@ -41,16 +40,13 @@ Developers and publishers of dApps can register their dApps by submitting a tran ### **Stores / Auditors** Stores and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. -##### **Targetted Releases** -Each developer and publisher can choose where to write metadata based on the information available from known stores & auditors. This gives **developers** and **publishers** the ability to perform targeted releases. (i.e to which stores and auditors). - #### **Suggested Validations** -- **`integrity`**: The dApp's metadata off-chain should match the metadata **anchored** on-chain. +- **`integrity`**: The dApp's off-chain metadata should match the metadata **anchored** on-chain. - **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain and publish their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. These entities could be directly associated with developer/publisher or not. ### **On-chain dApp Registration Certificate** -The on chain dApp registration certificate MUST follow canonical JSON and be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785). This stipulation is to avoid any ambigiutines in the signature calculation. +The on-chain dApp registration certificate MUST follow canonical JSON and be serialised according to RFC 8785 (https://www.rfc-editor.org/rfc/rfc8785). This stipulation is to avoid any ambigiutines in the signature calculation. ```json { @@ -76,14 +72,13 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser ``` ### Properties -*`subject`*: Identifier of the claim subject (dApp). A UTF-8 encoded string. This uniqueness of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist, therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. +*`subject`*: Identifier of the claim subject (dApp). A UTF-8 encoded string, max 64 chars. The uniqueness of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist, therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. *`type`*: The type of the claim. This is a JSON object that contains the following properties: - *`action`*: The action that the certificate is asserting. It can take the following values: - - *`REGISTER`*: The certificate is asserting that the dApp is being registered for the first time. - - *`UPDATE`*: The certificate is asserting that the dApp is being updated. - - *`DE_REGISTER`*: The certificate is asserting that the dApp version is being removed and it is requested that stores no longer show it. - - *`DE_REGISTER_ALL`*: The certificate is asserting that all dApp version are being removed and it is requested that stores no longer show it. + - *`REGISTER`*: The certificate is asserting that the dApp is registered for the first time or is providing an update. + - *`DE_REGISTER_RELEASE`*: The certificate is asserting that the dApp release version is being removed and it is requested that stores no longer show it. + - *`DE_REGISTER_DAPP`*: The certificate is asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is expected. *`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. Please note that off-chain JSON must be converted into RFC 8765 canonical form before taking the hash! @@ -99,12 +94,12 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser "$schema":"https://json-schema.org/draft/2019-09/schema", "$id":"https://example.com/dApp.schema.json", "title": "Cardano dApp Claim", - "description": "Registration of update of Cardano dApp claim.", + "description": "Registration of Cardano dApp claim.", "type":"object", "properties":{ "subject":{ "type":"string", - "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string. Typically it is randomly generated hash by the dApp developer." + "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, max 64 chars. Typically it is randomly generated hash by the dApp developer." }, "rootHash":{ "type":"string", @@ -129,18 +124,14 @@ The on chain dApp registration certificate MUST follow canonical JSON and be ser "properties":{ "action":{ "type":"string", - "enum":["REGISTER", "UPDATE", "DE_REGISTER", "DE_REGISTER_ALL"], - "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dapp; 'UPDATE' for a new release or 'DE_REGISTER' for dApp version de-listing request and DE_REGISTER_ALL if a dApp developer wants to de-register all dApp versions in one call." + "enum":["REGISTER", "DE_REGISTER_RELEASE", "DE_REGISTER_DAPP"], + "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dApp or an update; 'DE_REGISTER_RELEASE', for dApp release version de-listing request; `DE_REGISTER_DAPP`, for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is expected." }, "releaseNumber":{ "type":"string", "description":"An official version of the release following semver format (major.minor.patch).", "pattern": "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[a-zA-Z\\d][-a-zA-Z.\\d]*)?(\\+[a-zA-Z\\d][-a-zA-Z.\\d]*)?" }, - "releaseName":{ - "type":"string", - "description":"An optional dApp release name." - } }, "required":[ "action", @@ -203,7 +194,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "properties": { "subject": { "type":"string", - "description": "A subject, it must match with subject stored on chain data." + "description": "A subject, it must match with subject stored on chain data. A UTF-8 encoded string, max 64 chars" }, "projectName": { "type":"string", @@ -478,15 +469,11 @@ We believe that CIP-26 is geared towards storing this type of off-chain metadata We went back and forth whether we should actually store link (links) to off-chain metadata, eventually we settled on a solution that this is required because there could be a situation that a dApp registration may have off-chain metadata stored somewhere but some stores have it, others don't have it. Now it is required that a dApp developer points to at least one store that has off-chain metadata (as a reference metadata). -### Limited fields dApp Registration (what is mandatory / what is not) -It has been debated whether scripts / versions should NOT be mandatory. There are use cases which require only basic dApp information, such as dApp developer, website, twitter link, etc, there are, however, also use cases that require analysing of this dApp performance data and basic information won't suffice. To encourage dApps to share scripts (which are hard to reverse engineer and analyse) for the moment this CIP enforces and makes it a requirement to list -all scripts including all script hashes belonging to a dApp. - ### Optional Release Name? -Release Name is a field, which dApp developers can use on top of release version, it has been debated whether field should be mandatory or optional but eventually it has been agreed that we do not want to enforce this field, dapp release is an optional field, dApp version, however, needs to follow semver and is a mandatory field. +Release Name is a field, which dApp developers can use on top of Release Version, it has been debated whether field should be mandatory or optional but eventually it has been agreed that we do not want to enforce this field, Release Name is an optional field, Release Version, however, needs to follow semver and is a mandatory field. ### Canonical JSON -At the begining neither on-chain, nor off-chain storage has been following RFC 8785 (canonical JSON) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted +At the begining neither on-chain, nor off-chain JSON has been following RFC 8785 (canonical JSON) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted according to RFC 8785 before taking a blake2b-256 hash of them. ### On-Chain Signature Scope @@ -509,10 +496,10 @@ languages on Cardano being worked on where they already allow one validator to b ### Parametrised Scripts On Cardano, there are parametrised scripts, meaning that before compilation takes place, it is possible to pass certain parameters instead of using `Datum`. -The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't see that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION or an UPDATE to the existing dApp. +The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't seem that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION to the existing dApp. ### Often Changing Scripts -There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `UPDATE` command and provide on-chain and off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. +There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `REGISTRATION` command and provide on-chain and off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. ### Beacon Tokens Instead of Metadata It has been argued that since anybody can make claims to dApps, this CIP instead of using metadata should use tokens. dApp developers @@ -538,7 +525,7 @@ propagated in the on-chain JSON itself. We briefly discussed tags and we will likely introduce tags in the near future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. ### DE_REGISTER -We added DE_REGISTER and DE_REGISTER_ALL in additon to already existing `REGISTER` and `UPDATE`. The idea is that once dApp devs do not want their dApp version to be shown, they can now unlist a whole dApp or a dApp version and stores should respect such a request. +We added DE_REGISTER_RELEASE and DE_REGISTER_DAPP in additon to already existing `REGISTER`. The idea is that once dApp devs do not want their dApp release version to be shown, they can now unlist a dApp release version or a whole dApp and stores should respect such a request. ### Type Field `Type` field can be `PLUTUS` or `NATIVE`, we made it optional and there are already two dApps at least on Cardano at the time of writing, which are only using NATIVE scripts. This optional field helps to differentiante between NATIVE script based and NON_NATIVE dApps. @@ -561,4 +548,4 @@ N/A ## Copyright [CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode -[Apache-2.0]: http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file +[Apache-2.0]: http://www.apache.org/licenses/LICENSE-2.0 From 3de24f5f4f30808652aa43b1dc1821abcd625b45 Mon Sep 17 00:00:00 2001 From: Marcin Mazurek Date: Fri, 21 Apr 2023 15:02:11 +0200 Subject: [PATCH 50/63] Allow to express longer metadata URLs as an array of strings (#17) --- CIP-0072/README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 67a937de1f..03145e6867 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -107,11 +107,18 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser }, "metadata": { "type": "array", + "description": "An array of valid URLs pointing to off-chain CIP-72 compatible metadata document. If an individual URL is longer than 64 characters, it must be expressed as an array of strings (where each string may contain at most 64 characters).", "items": { - "type": "string", - "description": "A valid url pointing to off-chain CIP-72 compatible metadata document.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - } + "anyOf": [{ + "type": "string", + }, { + "type": "array", + "items": { + "type": "string", + } + }], + "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] + }, }, "version": { "type": "string", From 8a71ed5ccad72e2bd9e205ed395afe30a9368f28 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Fri, 21 Apr 2023 15:14:19 +0200 Subject: [PATCH 51/63] latest changes as per last meeting agreements --- CIP-0072/README.md | 114 ++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 67a937de1f..1bf7ff114c 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -3,7 +3,6 @@ CIP: 72 Title: Cardano dApp Registration & Discovery Status: Proposed Category: Metadata -Version: "1.0.0" Authors: - Bruno Martins - Mateusz Czeladka @@ -50,9 +49,8 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser ```json { - "subject": "d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", - "rootHash": "8c4e9eec512f5f277ab811ba75c991d51600c80003e892e601c6b6c19aaf8a33", - "version": "1.0.0", + "subject": "b37aabd81024c043f53a069c91e51a5b52e4ea399ae17ee1fe3cb9c44db707eb", + "rootHash": "7abcda7de6d883e7570118c1ccc8ee2e911f2e628a41ab0685ffee15f39bba96", "metadata": [ "https://cip26.foundation.app/properties/d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", "https://example.com/metadata.json", @@ -63,10 +61,10 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "releaseNumber": "1.0.0" }, "signature": { - "r": "5114674f1ce8a2615f2b15138944e5c58511804d72a96260ce8c587e7220daa90b9e65b450ff49563744d7633b43a78b8dc6ec3e3397b50080", - "s": "a15f06ce8005ad817a1681a4e96ee6b4831679ef448d7c283b188ed64d399d6bac420fadf33964b2f2e0f2d1abd401e8eb09ab29e3ff280600", + "r": "27159ce7d992c98fb04d5e9a59e43e75f77882b676fc6b2ccb8e952c2373da3e", + "s": "16b59ab1a9e349cd68d232f7652f238926dc24a2e435949ebe2e402a6557cfb4", "algo": "Ed25519−EdDSA", - "pub": "b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde" + "pub": "b384b53d5fe9f499ecf088083e505f40d2a6c123bf7201608494fdb89a051b80" } } ``` @@ -77,21 +75,18 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser *`type`*: The type of the claim. This is a JSON object that contains the following properties: - *`action`*: The action that the certificate is asserting. It can take the following values: - *`REGISTER`*: The certificate is asserting that the dApp is registered for the first time or is providing an update. - - *`DE_REGISTER_RELEASE`*: The certificate is asserting that the dApp release version is being removed and it is requested that stores no longer show it. - - *`DE_REGISTER_DAPP`*: The certificate is asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is expected. + - *`DE_REGISTER`*: The certificate is asserting that the dApp is deprecated / archived. So, no further dApp's on-chain update is expected. *`rootHash`*: The hash of the entire offchain metadata tree object. This hash is used by clients to verify the integrity of the metadata tree object. When reading a metadata tree object, the client should calculate the hash of the object and compare it with the `rootHash` property. If the two hashes don't match, the client should discard the object. The metadata tree object is a JSON object that contains the dApp's metadata. The metadata tree object is described in the next section. Please note that off-chain JSON must be converted into RFC 8765 canonical form before taking the hash! -*`version`*: CIP version, which version of the CIP was the on-chain certificate generated from. This is very much needed for stores and clients to know what rules they should apply for a given REGISTRATION / UPDATE. - *`metadata`*: An array of links to the dApp's metadata. The metadata is a JSON compatible RFC 8785 object that contains the dApp's metadata. -*`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "version", "rootHash", "metadata","type"]. Please note that a signature should be generated of blake2b-256 hash as a byte array, not as a hex represented string(!). +*`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "rootHash", "metadata","type"]. Please note that a signature should be generated of blake2b-256 hash as a byte array, not as a hex represented string(!). ### dApp on-chain certificate JSON Schema ```json { - "$schema":"https://json-schema.org/draft/2019-09/schema", + "$schema":"https://json-schema.org/draft/2020-12/schema", "$id":"https://example.com/dApp.schema.json", "title": "Cardano dApp Claim", "description": "Registration of Cardano dApp claim.", @@ -99,11 +94,17 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "properties":{ "subject":{ "type":"string", - "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, max 64 chars. Typically it is randomly generated hash by the dApp developer." + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$", + "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be 64 chars. Typically it is randomly generated hash by the dApp developer." }, "rootHash":{ "type":"string", - "description":"blake2b hash of the metadata describing the dApp." + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$", + "description":"blake2b-256 hash of the metadata describing the off-chain part of the dApp." }, "metadata": { "type": "array", @@ -113,29 +114,19 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" } }, - "version": { - "type": "string", - "description":"CIP version (semver).", - "pattern": "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[a-zA-Z\\d][-a-zA-Z.\\d]*)?(\\+[a-zA-Z\\d][-a-zA-Z.\\d]*)?" - }, "type":{ "type":"object", "description":"Describes the releases, if they are new or an updates. Also states the versioning of such releases.", "properties":{ "action":{ "type":"string", - "enum":["REGISTER", "DE_REGISTER_RELEASE", "DE_REGISTER_DAPP"], - "description":"Describes the action this certificate is claiming. I.e 'REGISTER', for a new dApp or an update; 'DE_REGISTER_RELEASE', for dApp release version de-listing request; `DE_REGISTER_DAPP`, for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is expected." - }, - "releaseNumber":{ - "type":"string", - "description":"An official version of the release following semver format (major.minor.patch).", - "pattern": "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[a-zA-Z\\d][-a-zA-Z.\\d]*)?(\\+[a-zA-Z\\d][-a-zA-Z.\\d]*)?" - }, + "enum":["REGISTER", "DE_REGISTER"], + "pattern": "^(REGISTER|DE_REGISTER)$", + "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." + } }, "required":[ - "action", - "releaseNumber" + "action" ] }, "signature":{ @@ -145,12 +136,16 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "r":{ "type":"string", "description":"A hex representation of the R component of the signature.", - "pattern":"[0-9a-fA-F]+" + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" }, "s":{ "type":"string", "description":"A hex representation of the S component of the signature.", - "pattern":"[0-9a-fA-F]+" + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" }, "algo":{ "const":"Ed25519−EdDSA" @@ -158,7 +153,9 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "pub":{ "type":"string", "description":"A hex representation of the public key.", - "pattern":"[0-9a-fA-F]+" + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" } }, "required":[ @@ -172,7 +169,6 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "required":[ "subject", "rootHash", - "version", "type", "signature" ] @@ -189,11 +185,13 @@ The dApp Registration certificate itself doesn't enforce a particular structure ```json { - "$schema": "https://json-schema.org/draft/2019-09/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", "type":"object", "properties": { "subject": { "type":"string", + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$", "description": "A subject, it must match with subject stored on chain data. A UTF-8 encoded string, max 64 chars" }, "projectName": { @@ -281,6 +279,18 @@ The dApp Registration certificate itself doesn't enforce a particular structure "type": "string", "description": "An optional human readable release name, e.g. V1", }, + "tags": { + "type":"array", + "items": { + "type": "string", + "enum":["SECURITY_VULNERABILITY", "DESIGN_FLAW"], + "description": "dApp owners can mark an app with special tags to indicate, e.g. security vulnerability. Stores can mark releases in a special way depending in the context." + } + }, + "comment": { + "type": "string", + "description": "A free text field to provide comment about this particular release, e.g. new features it brings, etc." + }, "scripts": { "type": "array", "items": [ @@ -325,8 +335,8 @@ The dApp Registration certificate itself doesn't enforce a particular structure "purposes":{ "type":"array", "items": { - "type": "string", - "enum":["SPEND", "MINT"] + "type": "string", + "enum":["SPEND", "MINT"] }, "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages).", }, @@ -342,7 +352,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "properties":{ "version":{ "type":"integer", - "description":"Script version, monotically increasing.", + "description":"Script version, monotonically increasing.", }, "plutusVersion":{ "type":"integer", @@ -517,34 +527,34 @@ some app that can attest validity and conformance to JSON schema - dApp Registra We made a decision to change the schema so that scripts and releases are no longer required. This could help to get initial registration from dApp developers faster and some stores simply do not require dApps to add their scripts in order to be listed. -### Schema Version or CIP Version -We want to take schema version further and actually attest the whole CIP version so we are introducing a top level field: version. Any changes to the document will require bumping the version. CIP version needs to be also -propagated in the on-chain JSON itself. +### Schema Version +We discussed and analyzed idea of schema version and or even whole CIP version. It turns out that CIP is already versioned by CIP-??? where ??? is version number. During this CIP being in `PROPOSED` state we reserve our right to make small changes to the schema / document, after CIP becomes active, it will require a new CIP. This is the current process, which other CIPs are also following. ### Tags We briefly discussed tags and we will likely introduce tags in the near future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. ### DE_REGISTER -We added DE_REGISTER_RELEASE and DE_REGISTER_DAPP in additon to already existing `REGISTER`. The idea is that once dApp devs do not want their dApp release version to be shown, they can now unlist a dApp release version or a whole dApp and stores should respect such a request. +We added DE_REGISTER in additon to already existing `REGISTER`. The idea is that once dApp devs want to deprecate dApp they can now issue DE_REGISTER request. ### Type Field `Type` field can be `PLUTUS` or `NATIVE`, we made it optional and there are already two dApps at least on Cardano at the time of writing, which are only using NATIVE scripts. This optional field helps to differentiante between NATIVE script based and NON_NATIVE dApps. -## Path to Active +### Version Deprecation +We discussed scenario what to do in case a dApp team wants to deprecate a particular version. Upon a few iteration we settled on doing this in off-chain section. It can be done via tags, e.g. tag: "SECURITY_VULNERABILITY. `Tags` is newly introduced field, available only in the off-chain JSON. -### Acceptance Criteria - -Currently CIP is available for: -- a review for dApp developers -- there is an open point, whether this CIP should be the first to have semver schema version (requires agreement on schema versions in CIPs first) -- `categories` field (enum) white list needs revision, current one is a proposal only +## Path to Active -Once those remaining items are done, CIP can be merged and activated. There were no major disagreements on the last CIP editor meeting apart from a few small TODO comments mentioned above. +We will evaluate a months if we have not missed any details, collect feedback from dApp developers, stores. We reserve right to make small changes in this time, while the proposal +is in PROPOSED status. Upon period (no longer than 6 months) from time of merging PR in `PROPOSED` status to the main / master branch, we will +update the proposal to be in `ACTIVE` state. -Last but not least, PR needs to be open and officially add 1667 metadata label to the registry here: https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json +### Acceptance Criteria +- IOG and CF approval +- Community representative approval (Santiago / TxPipe && Marcel / Eternl wallet) +- PR to https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json ### Implementation Plan -N/A +- Reference implementation: https://github.com/Cardano-Fans/crfa-dapp-registration-and-certification-service (incubator) ## Copyright [CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode From 03b20564152dc4e1b6e3bd53ec18f3ac1bee279b Mon Sep 17 00:00:00 2001 From: matiwinnetou Date: Sun, 23 Apr 2023 12:03:51 +0200 Subject: [PATCH 52/63] Update README.md --- CIP-0072/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index c3bb6b90eb..07f50f572a 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -111,15 +111,15 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "description": "An array of valid URLs pointing to off-chain CIP-72 compatible metadata document. If an individual URL is longer than 64 characters, it must be expressed as an array of strings (where each string may contain at most 64 characters).", "items": { "anyOf": [{ - "type": "string", + "type": "string" }, { "type": "array", "items": { - "type": "string", + "type": "string" } }], "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] - }, + } }, "type":{ "type":"object", From 4d801a2c8e6f01e6ec244b468aaa98abaa8faa78 Mon Sep 17 00:00:00 2001 From: matiwinnetou Date: Sun, 23 Apr 2023 12:05:45 +0200 Subject: [PATCH 53/63] Update README.md --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 07f50f572a..dd96bd9f17 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -118,7 +118,7 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "type": "string" } }], - "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] + "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name/", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] } }, "type":{ From d7e582a6132be3b8f1fc1d0ce4c5a025eea54e7e Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Mon, 24 Apr 2023 15:56:16 +0200 Subject: [PATCH 54/63] CDDL --- CIP-0072/README.md | 471 +++++++++++++++++-------------- CIP-0072/version_1_offchain.json | 211 ++++++++++++++ CIP-0072/version_1_onchain.cddl | 30 ++ CIP-0072/version_1_onchain.json | 100 +++++++ 4 files changed, 594 insertions(+), 218 deletions(-) create mode 100644 CIP-0072/version_1_offchain.json create mode 100644 CIP-0072/version_1_onchain.cddl create mode 100644 CIP-0072/version_1_onchain.json diff --git a/CIP-0072/README.md b/CIP-0072/README.md index dd96bd9f17..c998822168 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -52,13 +52,10 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "subject": "b37aabd81024c043f53a069c91e51a5b52e4ea399ae17ee1fe3cb9c44db707eb", "rootHash": "7abcda7de6d883e7570118c1ccc8ee2e911f2e628a41ab0685ffee15f39bba96", "metadata": [ - "https://cip26.foundation.app/properties/d684512ccb313191dd08563fd8d737312f7f104a70d9c72018f6b0621ea738c5b8213c8365b980f2d8c48d5fbb2ec3ce642725a20351dbff9861ce9695ac5db8", - "https://example.com/metadata.json", - "https://ipfs.blockfrost.io/api/v0/QmWmXcRqPzJn5yDh8cXqL1oYjHr4kZx1aYQ1w1yTfTJqNn", + "https://cip26.foundation.app/my_dapp.json" ], "type": { - "action": "REGISTER", - "releaseNumber": "1.0.0" + "action": "REGISTER" }, "signature": { "r": "27159ce7d992c98fb04d5e9a59e43e75f77882b676fc6b2ccb8e952c2373da3e", @@ -83,6 +80,42 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser *`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "rootHash", "metadata","type"]. Please note that a signature should be generated of blake2b-256 hash as a byte array, not as a hex represented string(!). +### On chain CDDL for registration / de-registration +``` +string = bstr .size (1..64) ; tstr / string from 1 up to 64 chars only + +sig_256 = bstr .size (64..64) ; 256 bytes signature (256 / 64 = 4 bytes) + +transaction_metadata = { + "1667": on-chain_metadata +} + +on-chain_metadata = { + "subject": string + , "rootHash": sig_256 + , "metadata": [+ string] / [+ [+ string]] + , "type": registration / de-registration + , "signature": signature +} + +registration = { + "action": "REGISTRATION" +} + +de-registration = { + "action": "DE_REGISTRATION" +} + +signature = { + "r": string + , "s": string + , "algo": text .regexp "Ed25519-EdDSA" + , "pub": string +} +``` + +which can be expressed using JSON schema. + ### dApp on-chain certificate JSON Schema ```json { @@ -94,10 +127,10 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "properties":{ "subject":{ "type":"string", - "minLength": 64, + "minLength": 1, "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$", - "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be 64 chars. Typically it is randomly generated hash by the dApp developer." + "pattern":"^[0-9a-fA-F]{1,64}$", + "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be max 64 chars. Typically it is randomly generated hash by the dApp developer." }, "rootHash":{ "type":"string", @@ -111,11 +144,15 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "description": "An array of valid URLs pointing to off-chain CIP-72 compatible metadata document. If an individual URL is longer than 64 characters, it must be expressed as an array of strings (where each string may contain at most 64 characters).", "items": { "anyOf": [{ - "type": "string" - }, { + "type": "string", + "minLength": 1, + "maxLength": 64 + }, { "type": "array", "items": { - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 64 } }], "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name/", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] @@ -123,7 +160,7 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser }, "type":{ "type":"object", - "description":"Describes the releases, if they are new or an updates. Also states the versioning of such releases.", + "description":"Describes the releases, if they are new or an updates.", "properties":{ "action":{ "type":"string", @@ -192,217 +229,215 @@ The dApp Registration certificate itself doesn't enforce a particular structure ```json { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type":"object", - "properties": { - "subject": { - "type":"string", - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$", - "description": "A subject, it must match with subject stored on chain data. A UTF-8 encoded string, max 64 chars" - }, - "projectName": { - "type":"string", - "description": "A project name, e.g. My dApp." - }, - "link": { - "type":"string", - "description": "Website presenting a dApp.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - }, - "projectName": { - "type":"string", - "description": "A project name, e.g. My dApp." - }, - "logo": { - "type":"string", - "description": "URL to the logo or the base64 encoded image." - }, - "categories": { - "type":"array", - "items": { - "type": "string", - "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"] + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type":"object", + "properties": { + "subject": { + "type":"string", + "minLength": 1, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{1,64}$", + "description": "A subject, it must match with subject stored on chain data. A UTF-8 encoded string, 1 - 64 chars." }, - "description": "One or more categories. Category MUST be one of the following schema definition." - }, - "social": { - "type":"object", - "properties": { - "website": { - "type":"string", - "description": "dApps website link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - }, - "twitter": { - "type":"string", - "description": "An optional Twitter link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" - }, - "github": { - "type":"string", - "description": "An optional Github link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + "projectName": { + "type":"string", + "description": "A project name, e.g. My dApp." + }, + "link": { + "type":"string", + "description": "Website presenting a dApp.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "logo": { + "type":"string", + "description": "URL to the logo or the base64 encoded image." + }, + "categories": { + "type":"array", + "items": { + "type": "string", + "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"] }, - "discord": { - "type":"string", - "description": "An optional Discord link.", - "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + "description": "One or more categories. Category MUST be one of the following schema definition." + }, + "social": { + "type":"object", + "properties": { + "website": { + "type":"string", + "description": "dApps website link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "twitter": { + "type":"string", + "description": "An optional Twitter link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "github": { + "type":"string", + "description": "An optional Github link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "discord": { + "type":"string", + "description": "An optional Discord link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + } }, + "required": ["website"] }, - "required": ["website"] - }, - "description": { - "type": "object", - "properties": { - "short": { - "type": "string", - "description": "Short dApp description (no less than 40 and no longer than 168 characters).", - "minLength": 40, - "maxLength": 168 + "description": { + "type": "object", + "properties": { + "short": { + "type": "string", + "description": "Short dApp description (no less than 40 and no longer than 168 characters).", + "minLength": 40, + "maxLength": 168 + }, + "long": { + "type": "string", + "description": "An optional long dApp description (no less than 40 and no longer than 1008 characters).", + "minLength": 40, + "maxLength": 1008 + } }, - "long": { - "type": "string", - "description": "An optional long dApp description (no less than 40 and no longer than 1008 characters).", - "minLength": 40, - "maxLength": 1008 - } + "required": [ + "short" + ] }, - "required": [ - "short" - ] - }, - "releases": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "releaseNumber": { - "type": "string", - "description": "Semver compatible release number (major.minor.patch), e.g. 1.2.3, where 1 is major, 2 is a minor and 3 is a patch.", - }, - "releaseName": { - "type": "string", - "description": "An optional human readable release name, e.g. V1", - }, - "tags": { - "type":"array", - "items": { - "type": "string", - "enum":["SECURITY_VULNERABILITY", "DESIGN_FLAW"], - "description": "dApp owners can mark an app with special tags to indicate, e.g. security vulnerability. Stores can mark releases in a special way depending in the context." - } - }, - "comment": { - "type": "string", - "description": "A free text field to provide comment about this particular release, e.g. new features it brings, etc." - }, - "scripts": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "version": { - "type": "integer" - } - }, - "required": [ - "id", - "version" - ] + "releases": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "releaseNumber": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$", + "description": "Semver compatible release number (major.minor.patch), e.g. 1.2.3, where 1 is major, 2 is a minor and 3 is a patch." + }, + "releaseName": { + "type": "string", + "description": "An optional human readable release name, e.g. V1" + }, + "tags": { + "type":"array", + "items": { + "type": "string", + "enum":["SECURITY_VULNERABILITY", "DESIGN_FLAW"], + "description": "dApp owners can mark an app with special tags to indicate, e.g. security vulnerability. Stores can mark releases in a special way depending in the context." } - ] - } - }, - "required": [ - "releaseNumber" - ] - } - ] - }, - "scripts": { - "type": "array", - "items": [ - { - "type": "object", - "properties":{ - "id": { - "type":"string", - "description": "Unique Script ID (across all scripts from this dApp).", - }, - "name":{ - "type":"string", - "description": "An optional script name usually related to it's function.", - }, - "purposes":{ - "type":"array", - "items": { - "type": "string", - "enum":["SPEND", "MINT"] }, - "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages).", - }, - "type":{ - "enum":["PLUTUS", "NATIVE"], - "description": "Script Type. PLUTUS refers to the typical PlutusV1 or PlutusV2 scripts, where as NATIVE means there has been no Plutus directly used by this is a native script.", - }, - "versions":{ - "type":"array", - "items":[ - { - "type":"object", - "properties":{ - "version":{ - "type":"integer", - "description":"Script version, monotonically increasing.", - }, - "plutusVersion":{ - "type":"integer", - "enum":[1, 2], + "comment": { + "type": "string", + "description": "A free text field to provide comment about this particular release, e.g. new features it brings, etc." + }, + "scripts": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "integer" + } }, - "scriptHash":{ - "type":"string", - "description":"Full on-chain script hash (hex).", - "pattern":"[0-9a-fA-F]+" + "required": [ + "id", + "version" + ] + } + ] + } + }, + "required": [ + "releaseNumber" + ] + } + ] + }, + "scripts": { + "type": "array", + "items": [ + { + "type": "object", + "properties":{ + "id": { + "type":"string", + "description": "Unique Script ID (across all scripts from this dApp)." + }, + "name":{ + "type":"string", + "description": "An optional script name usually related to it's function." + }, + "purposes":{ + "type":"array", + "items": { + "type": "string", + "enum":["SPEND", "MINT"] + }, + "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages)." + }, + "type":{ + "enum":["PLUTUS", "NATIVE"], + "description": "Script Type. PLUTUS refers to the typical PlutusV1 or PlutusV2 scripts, where as NATIVE means there has been no Plutus directly used by this is a native script." + }, + "versions":{ + "type":"array", + "items":[ + { + "type":"object", + "properties":{ + "version":{ + "type":"integer", + "description":"Script version, monotonically increasing." + }, + "plutusVersion":{ + "type":"integer", + "enum":[1, 2] + }, + "scriptHash":{ + "type":"string", + "description":"Full on-chain script hash (hex).", + "pattern":"[0-9a-fA-F]+" + }, + "contractAddress": { + "type":"string", + "description":"An optional Bech32 contract address matching script's hash." + } }, - "contractAddress": { - "type":"string", - "description":"An optional Bech32 contract address matching script's hash.", - } - }, - "required": [ - "version", - "plutusVersion", - "scriptHash" - ] - } - ] - } - }, - "required": [ - "id", - "purposes", - "type", - "versions" - ] - } - ] - } - }, - "required": [ - "subject", - "projectName", - "link", - "social", - "categories", - "description" - ] -} + "required": [ + "version", + "plutusVersion", + "scriptHash" + ] + } + ] + } + }, + "required": [ + "id", + "purposes", + "type", + "versions" + ] + } + ] + } + }, + "required": [ + "subject", + "projectName", + "link", + "social", + "categories", + "description" + ] + } ``` This schema describes the minimum required fields for a store to be able to display and validate your dApp. You can add any other fields you want to the metadata, but we recommend that you use at least the ones described above. @@ -547,17 +582,17 @@ We added DE_REGISTER in additon to already existing `REGISTER`. The idea is that `Type` field can be `PLUTUS` or `NATIVE`, we made it optional and there are already two dApps at least on Cardano at the time of writing, which are only using NATIVE scripts. This optional field helps to differentiante between NATIVE script based and NON_NATIVE dApps. ### Version Deprecation -We discussed scenario what to do in case a dApp team wants to deprecate a particular version. Upon a few iteration we settled on doing this in off-chain section. It can be done via tags, e.g. tag: "SECURITY_VULNERABILITY. `Tags` is newly introduced field, available only in the off-chain JSON. +We discussed scenario what to do in case a dApp team wants to deprecate a particular version. Upon a few iteration we settled on doing this in off-chain section. It can be done via tags, e.g. tag: "SECURITY_VULNERABILITY. `Tags` is newly introduced field, available only in the off-chain JSON. Changes to any versions will require on-chain re-registration +since rootHash changes. ## Path to Active - -We will evaluate a months if we have not missed any details, collect feedback from dApp developers, stores. We reserve right to make small changes in this time, while the proposal -is in PROPOSED status. Upon period (no longer than 6 months) from time of merging PR in `PROPOSED` status to the main / master branch, we will +We will evaluate for a few months if we have not missed any details, collect feedback from dApp developers, stores. We reserve right to make small changes in this time, while the proposal +is in `PROPOSED` status. After certain period (no longer than 6 months), from time of merging PR in `PROPOSED` status to the main / master branch, we will update the proposal to be in `ACTIVE` state. ### Acceptance Criteria - IOG and CF approval -- Community representative approval (Santiago / TxPipe && Marcel / Eternl wallet) +- Community representative approval (Santiago / TxPipe and Marcel / Eternl wallet) - PR to https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json ### Implementation Plan diff --git a/CIP-0072/version_1_offchain.json b/CIP-0072/version_1_offchain.json new file mode 100644 index 0000000000..622eb16810 --- /dev/null +++ b/CIP-0072/version_1_offchain.json @@ -0,0 +1,211 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type":"object", + "properties": { + "subject": { + "type":"string", + "minLength": 1, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{1,64}$", + "description": "A subject, it must match with subject stored on chain data. A UTF-8 encoded string, 1 - 64 chars." + }, + "projectName": { + "type":"string", + "description": "A project name, e.g. My dApp." + }, + "link": { + "type":"string", + "description": "Website presenting a dApp.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "logo": { + "type":"string", + "description": "URL to the logo or the base64 encoded image." + }, + "categories": { + "type":"array", + "items": { + "type": "string", + "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"] + }, + "description": "One or more categories. Category MUST be one of the following schema definition." + }, + "social": { + "type":"object", + "properties": { + "website": { + "type":"string", + "description": "dApps website link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "twitter": { + "type":"string", + "description": "An optional Twitter link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "github": { + "type":"string", + "description": "An optional Github link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + }, + "discord": { + "type":"string", + "description": "An optional Discord link.", + "pattern": "(https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\/\/(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})" + } + }, + "required": ["website"] + }, + "description": { + "type": "object", + "properties": { + "short": { + "type": "string", + "description": "Short dApp description (no less than 40 and no longer than 168 characters).", + "minLength": 40, + "maxLength": 168 + }, + "long": { + "type": "string", + "description": "An optional long dApp description (no less than 40 and no longer than 1008 characters).", + "minLength": 40, + "maxLength": 1008 + } + }, + "required": [ + "short" + ] + }, + "releases": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "releaseNumber": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$", + "description": "Semver compatible release number (major.minor.patch) or (major.minor.patch-some_text) e.g. 1.2.3 or 1.1.1-alpha" + }, + "releaseName": { + "type": "string", + "description": "An optional human readable release name, e.g. V1" + }, + "tags": { + "type":"array", + "items": { + "type": "string", + "enum":["SECURITY_VULNERABILITY", "DESIGN_FLAW"], + "description": "dApp owners can mark an app with special tags to indicate, e.g. security vulnerability. Stores can mark releases in a special way depending in the context." + } + }, + "comment": { + "type": "string", + "description": "A free text field to provide comment about this particular release, e.g. new features it brings, etc." + }, + "scripts": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "version" + ] + } + ] + } + }, + "required": [ + "releaseNumber" + ] + } + ] + }, + "scripts": { + "type": "array", + "items": [ + { + "type": "object", + "properties":{ + "id": { + "type":"string", + "description": "Unique Script ID (across all scripts from this dApp)." + }, + "name":{ + "type":"string", + "description": "An optional script name usually related to it's function." + }, + "purposes":{ + "type":"array", + "items": { + "type": "string", + "enum":["SPEND", "MINT"] + }, + "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages)." + }, + "type":{ + "enum":["PLUTUS", "NATIVE"], + "description": "Script Type. PLUTUS refers to the typical PlutusV1 or PlutusV2 scripts, where as NATIVE means there has been no Plutus directly used by this is a native script." + }, + "versions":{ + "type":"array", + "items":[ + { + "type":"object", + "properties":{ + "version":{ + "type":"integer", + "description":"Script version, monotonically increasing." + }, + "plutusVersion":{ + "type":"integer", + "enum":[1, 2] + }, + "scriptHash":{ + "type":"string", + "description":"Full on-chain script hash (hex).", + "pattern":"[0-9a-fA-F]+" + }, + "contractAddress": { + "type":"string", + "description":"An optional Bech32 contract address matching script's hash." + } + }, + "required": [ + "version", + "plutusVersion", + "scriptHash" + ] + } + ] + } + }, + "required": [ + "id", + "purposes", + "type", + "versions" + ] + } + ] + } + }, + "required": [ + "subject", + "projectName", + "link", + "social", + "categories", + "description" + ] + } + \ No newline at end of file diff --git a/CIP-0072/version_1_onchain.cddl b/CIP-0072/version_1_onchain.cddl new file mode 100644 index 0000000000..d50ef86e80 --- /dev/null +++ b/CIP-0072/version_1_onchain.cddl @@ -0,0 +1,30 @@ +string = bstr .size (1..64) ; tstr / string from 1 up to 64 chars only + +sig_256 = bstr .size (64..64) ; 256 bytes signature (256 / 64 = 4 bytes) + +transaction_metadata = { + "1667": on-chain_metadata +} + +on-chain_metadata = { + "subject": string + , "rootHash": sig_256 + , "metadata": [+ string] / [+ [+ string]] + , "type": registration / de-registration + , "signature": signature +} + +registration = { + "action": "REGISTRATION" +} + +de-registration = { + "action": "DE_REGISTRATION" +} + +signature = { + "r": string + , "s": string + , "algo": text .regexp "Ed25519-EdDSA" + , "pub": string +} \ No newline at end of file diff --git a/CIP-0072/version_1_onchain.json b/CIP-0072/version_1_onchain.json new file mode 100644 index 0000000000..57867f96e4 --- /dev/null +++ b/CIP-0072/version_1_onchain.json @@ -0,0 +1,100 @@ +{ + "$schema":"https://json-schema.org/draft/2020-12/schema", + "$id":"https://example.com/dApp.schema.json", + "title": "Cardano dApp Claim", + "description": "Registration of Cardano dApp claim.", + "type":"object", + "properties":{ + "subject":{ + "type":"string", + "minLength": 1, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{1,64}$", + "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be max 64 chars. Typically it is randomly generated hash by the dApp developer." + }, + "rootHash":{ + "type":"string", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$", + "description":"blake2b-256 hash of the metadata describing the off-chain part of the dApp." + }, + "metadata": { + "type": "array", + "description": "An array of valid URLs pointing to off-chain CIP-72 compatible metadata document. If an individual URL is longer than 64 characters, it must be expressed as an array of strings (where each string may contain at most 64 characters).", + "items": { + "anyOf": [{ + "type": "string", + "minLength": 1, + "maxLength": 64 + }, { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 64 + } + }], + "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name/", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] + } + }, + "type":{ + "type":"object", + "description":"Describes the releases, if they are new or an updates.", + "properties":{ + "action":{ + "type":"string", + "enum":["REGISTER", "DE_REGISTER"], + "pattern": "^(REGISTER|DE_REGISTER)$", + "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." + } + }, + "required":[ + "action" + ] + }, + "signature":{ + "description":"Signature of the blake2b-256 hash of whole canonical (RFC 8785) JSON document (except signature property).", + "type":"object", + "properties":{ + "r":{ + "type":"string", + "description":"A hex representation of the R component of the signature.", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" + }, + "s":{ + "type":"string", + "description":"A hex representation of the S component of the signature.", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" + }, + "algo":{ + "const":"Ed25519-EdDSA" + }, + "pub":{ + "type":"string", + "description":"A hex representation of the public key.", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" + } + }, + "required":[ + "r", + "s", + "algo", + "pub" + ] + } + }, + "required":[ + "subject", + "rootHash", + "type", + "signature" + ] + } + \ No newline at end of file From 2e61c3749497f67491c2b7d955c39d00a77ed024 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Mon, 24 Apr 2023 16:56:12 +0200 Subject: [PATCH 55/63] CDDL fix --- CIP-0072/README.md | 2 +- CIP-0072/version_1_onchain.cddl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index c998822168..9578f0865f 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -93,7 +93,7 @@ transaction_metadata = { on-chain_metadata = { "subject": string , "rootHash": sig_256 - , "metadata": [+ string] / [+ [+ string]] + , "metadata": [+ string] / [+ string / [+ string]] , "type": registration / de-registration , "signature": signature } diff --git a/CIP-0072/version_1_onchain.cddl b/CIP-0072/version_1_onchain.cddl index d50ef86e80..5047c5192c 100644 --- a/CIP-0072/version_1_onchain.cddl +++ b/CIP-0072/version_1_onchain.cddl @@ -9,7 +9,7 @@ transaction_metadata = { on-chain_metadata = { "subject": string , "rootHash": sig_256 - , "metadata": [+ string] / [+ [+ string]] + , "metadata": [+ string] / [+ string / [+ string]] , "type": registration / de-registration , "signature": signature } From 4633c9641e2ea721fa3281e731bfa416dd89db5c Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 27 Apr 2023 09:31:25 +0200 Subject: [PATCH 56/63] cosmetics --- CIP-0072/README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 9578f0865f..9cd5480e51 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -515,7 +515,7 @@ whether those have been certified / explicitly mentioned in the audit. This one is rather obvious but for the sake of completeness worth documenting. We analyzed how much we should put on-chain vs off-chain and we quickly reached the conclusion that it is better to keep small amount of data on-chain and larger chunk off-chain for which is what exactly CIP-26 is meant for. ### CIP-26 as *ONE* of Storage Layers -We believe that CIP-26 is geared towards storing this type of off-chain metadata format but we don't want by any means to stipulate / police this form of storage. In fact it is possible to use offchain metadata storage alternatives such as direct http hosting / REST API/ IPFS / git, etc. +We believe that CIP-26 is geared towards storing this type of off-chain metadata format but we don't want by any means to stipulate / police this form of storage. In fact it is possible to use offchain metadata storage alternatives such as CIP-26 compatible server / direct http(s) hosting / IPFS, etc. ### How to Find Off-Chain Data? We went back and forth whether we should actually store link (links) to off-chain metadata, eventually we settled on a solution that this is required @@ -537,7 +537,7 @@ Smart contracts are ownerless, it has been debated that there could be multiple The standard doesn't prevent anyone from making a claim, so it's up to the different operator to their diligence work and make their own choices of whom they trust. The signature should give the most confidence as anyone can collect known public keys from known development companies. Future CIP revisions can include DID's and Verifiable Credentials to tackle this problem in a more elegant way. ### DIDs -Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, usage of them in this initial CIP version has been descoped. +Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, usage of them in this initial CIP version has been de-scoped. ### Categories `Categories` is a predefined enum with values defined in the CIP / schema, it is *NOT* a free text field, rationale for this is that dApp developers will have no idea what ontology / classification to use, which will likely result in many duplicates of the same thing. @@ -548,7 +548,7 @@ languages on Cardano being worked on where they already allow one validator to b ### Parametrised Scripts On Cardano, there are parametrised scripts, meaning that before compilation takes place, it is possible to pass certain parameters instead of using `Datum`. -The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't seem that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION to the existing dApp. +The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't seem that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION to the existing dApp with a requirement to add new version(s) in the dApp's off-chain metadata. ### Often Changing Scripts There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `REGISTRATION` command and provide on-chain and off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. @@ -566,14 +566,13 @@ using Datums requires a smart contract and we want to keep this solution as acce some app that can attest validity and conformance to JSON schema - dApp Registration / Update MUST never be done that does not conform to the schema. ### Scripts / Releases Fields Are Not Required -We made a decision to change the schema so that scripts and releases are no longer required. This could help to get initial registration from dApp developers faster and -some stores simply do not require dApps to add their scripts in order to be listed. +We made a decision to change the schema so that scripts and releases are no longer required. This could help to get initial registration from dApp developers faster and some stores simply do not require dApps to add their scripts in order to be listed. ### Schema Version We discussed and analyzed idea of schema version and or even whole CIP version. It turns out that CIP is already versioned by CIP-??? where ??? is version number. During this CIP being in `PROPOSED` state we reserve our right to make small changes to the schema / document, after CIP becomes active, it will require a new CIP. This is the current process, which other CIPs are also following. ### Tags -We briefly discussed tags and we will likely introduce tags in the near future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. +We briefly discussed tags and we will likely introduce tags in the future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. ### DE_REGISTER We added DE_REGISTER in additon to already existing `REGISTER`. The idea is that once dApp devs want to deprecate dApp they can now issue DE_REGISTER request. From 28b16c1f1b75a5ffcb859644986be61aa61c66f9 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 27 Apr 2023 10:45:22 +0200 Subject: [PATCH 57/63] initial categories update --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 9cd5480e51..dae62a279e 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -256,7 +256,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "type":"array", "items": { "type": "string", - "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"] + "enum":["Games", "Development", "DeFi", "NFT", "Security", "Marketplace", "Education", "Identity", "Other"] }, "description": "One or more categories. Category MUST be one of the following schema definition." }, From a4e3c680c8149bf682cb4b433d8ff73de9ce0f6d Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 27 Apr 2023 14:55:58 +0200 Subject: [PATCH 58/63] security_vulnerability field, added comment field in on-chain json and recommendation for keeping all past histories of off-chain snapshots. --- CIP-0072/README.md | 260 ++++++++++++++++--------------- CIP-0072/version_1_offchain.json | 10 +- CIP-0072/version_1_onchain.cddl | 28 ++-- CIP-0072/version_1_onchain.json | 6 + 4 files changed, 160 insertions(+), 144 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index dae62a279e..254cb9ce65 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -28,7 +28,7 @@ Also, having this formalisation facilitates any actor in the ecosystem to index ### **Definitions** - **anchor** - A hash written on-chain (rootHash) that can be used to verify the integrity (by way of a cryptographic hash) of the data that is found off-chain. - **dApp** - A decentralised application that is described by the combination of metadata, certificate and a set of used scripts. -- **metadata claim** - Generically any attempt to map off-chain metadata to an on-chain subject. This specification looks at dApp specific metadata claims. +- **metadata claim** - Generically any attempt to map off-chain metadata to an on-chain subject. This specification looks at dApp specific metadata claims. Caution: it is highly recommended that dApp developers provide links to a specific snapshot (version) without removing all previous snapshots / version links. Some stores may choose not to show a dApp if all off-chain historical versions are not available but instead only latest snapshot. - **client** - Any ecosystem participant which follows on-chain data to consume metadata claims (i.e. dApp stores, wallets, auditors, block explorers, etc.). - **dApp Store** - A dApp aggregator application which follows on-chain data looking for and verifying dApp metadata claims, serving their users linked dApp metadata. - **publishers** - Entities which publish metadata claims on-chain, in the case of dApps the publishers are likely the dApp developer(s). @@ -52,10 +52,11 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "subject": "b37aabd81024c043f53a069c91e51a5b52e4ea399ae17ee1fe3cb9c44db707eb", "rootHash": "7abcda7de6d883e7570118c1ccc8ee2e911f2e628a41ab0685ffee15f39bba96", "metadata": [ - "https://cip26.foundation.app/my_dapp.json" + "https://cip26.foundation.app/my_dapp_7abcda.json" ], "type": { - "action": "REGISTER" + "action": "REGISTER", + "comment": "New release adding zapping support." }, "signature": { "r": "27159ce7d992c98fb04d5e9a59e43e75f77882b676fc6b2ccb8e952c2373da3e", @@ -87,30 +88,32 @@ string = bstr .size (1..64) ; tstr / string from 1 up to 64 chars only sig_256 = bstr .size (64..64) ; 256 bytes signature (256 / 64 = 4 bytes) transaction_metadata = { - "1667": on-chain_metadata + 1667: on-chain_metadata } on-chain_metadata = { - "subject": string - , "rootHash": sig_256 - , "metadata": [+ string] / [+ string / [+ string]] - , "type": registration / de-registration - , "signature": signature + subject: string, + rootHash: sig_256, + metadata: [+ string] / [+ string / [+ string]], + type: registration / de-registration, + signature: signature, } registration = { - "action": "REGISTRATION" + action: "REGISTRATION", + ? comment: string, ; max 64 chars } de-registration = { - "action": "DE_REGISTRATION" + action: "DE_REGISTRATION", + ? comment: string, ; max 64 chars } signature = { - "r": string - , "s": string - , "algo": text .regexp "Ed25519-EdDSA" - , "pub": string + r: string, + s: string, + algo: text .regexp "Ed25519-EdDSA", + pub: string, } ``` @@ -119,105 +122,111 @@ which can be expressed using JSON schema. ### dApp on-chain certificate JSON Schema ```json { - "$schema":"https://json-schema.org/draft/2020-12/schema", - "$id":"https://example.com/dApp.schema.json", - "title": "Cardano dApp Claim", - "description": "Registration of Cardano dApp claim.", - "type":"object", - "properties":{ - "subject":{ - "type":"string", + "$schema":"https://json-schema.org/draft/2020-12/schema", + "$id":"https://example.com/dApp.schema.json", + "title": "Cardano dApp Claim", + "description": "Registration of Cardano dApp claim.", + "type":"object", + "properties":{ + "subject":{ + "type":"string", + "minLength": 1, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{1,64}$", + "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be max 64 chars. Typically it is randomly generated hash by the dApp developer." + }, + "rootHash":{ + "type":"string", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$", + "description":"blake2b-256 hash of the metadata describing the off-chain part of the dApp." + }, + "metadata": { + "type": "array", + "description": "An array of valid URLs pointing to off-chain CIP-72 compatible metadata document. If an individual URL is longer than 64 characters, it must be expressed as an array of strings (where each string may contain at most 64 characters).", + "items": { + "anyOf": [{ + "type": "string", "minLength": 1, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{1,64}$", - "description":"Identifier of the claim subject (dApp). A UTF-8 encoded string, must be max 64 chars. Typically it is randomly generated hash by the dApp developer." - }, - "rootHash":{ - "type":"string", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$", - "description":"blake2b-256 hash of the metadata describing the off-chain part of the dApp." - }, - "metadata": { - "type": "array", - "description": "An array of valid URLs pointing to off-chain CIP-72 compatible metadata document. If an individual URL is longer than 64 characters, it must be expressed as an array of strings (where each string may contain at most 64 characters).", - "items": { - "anyOf": [{ - "type": "string", - "minLength": 1, - "maxLength": 64 - }, { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 64 - } - }], - "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name/", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] - } - }, - "type":{ - "type":"object", - "description":"Describes the releases, if they are new or an updates.", - "properties":{ - "action":{ - "type":"string", - "enum":["REGISTER", "DE_REGISTER"], - "pattern": "^(REGISTER|DE_REGISTER)$", - "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." - } - }, - "required":[ - "action" - ] - }, - "signature":{ - "description":"Signature of the blake2b-256 hash of whole canonical (RFC 8785) JSON document (except signature property).", - "type":"object", - "properties":{ - "r":{ - "type":"string", - "description":"A hex representation of the R component of the signature.", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$" - }, - "s":{ - "type":"string", - "description":"A hex representation of the S component of the signature.", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$" - }, - "algo":{ - "const":"Ed25519−EdDSA" - }, - "pub":{ + "maxLength": 64 + }, { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 64 + } + }], + "examples": ["https://raw.githubusercontent.com/org/repo/offchain.json", ["https://raw.githubusercontent.com/long-org-name/", "long-repo-name/offchain.json"], "ipfs://QmbQDvKJeo2NgGcGdnUiUFibTzuKNK5Uij7jzmK8ZccmWp", ["ipfs://QmbQDvKJeo2NgGcGdnUiaAdADA", "UFibTzuKNKc0jA390alDAD5Uij7jzmK8ZccmWp"]] + } + }, + "type":{ + "type":"object", + "description":"Describes the releases, if they are new or an updates.", + "properties":{ + "action":{ "type":"string", - "description":"A hex representation of the public key.", - "minLength": 64, - "maxLength": 64, - "pattern":"^[0-9a-fA-F]{64}$" - } - }, - "required":[ - "r", - "s", - "algo", - "pub" - ] - } - }, - "required":[ - "subject", - "rootHash", - "type", - "signature" - ] -} -``` + "enum":["REGISTER", "DE_REGISTER"], + "pattern": "^(REGISTER|DE_REGISTER)$", + "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." + }, + "comment": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "A free text field to provide details about this particular changes (64 chars limited)." + } + }, + "required":[ + "action" + ] + }, + "signature":{ + "description":"Signature of the blake2b-256 hash of whole canonical (RFC 8785) JSON document (except signature property).", + "type":"object", + "properties":{ + "r":{ + "type":"string", + "description":"A hex representation of the R component of the signature.", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" + }, + "s":{ + "type":"string", + "description":"A hex representation of the S component of the signature.", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" + }, + "algo":{ + "const":"Ed25519-EdDSA" + }, + "pub":{ + "type":"string", + "description":"A hex representation of the public key.", + "minLength": 64, + "maxLength": 64, + "pattern":"^[0-9a-fA-F]{64}$" + } + }, + "required":[ + "r", + "s", + "algo", + "pub" + ] + } + }, + "required":[ + "subject", + "rootHash", + "type", + "signature" + ] + } + ``` ### Metadata Label When submitting the transaction metadata pick the following value for `transaction_metadatum_label`: @@ -256,7 +265,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "type":"array", "items": { "type": "string", - "enum":["Games", "Development", "DeFi", "NFT", "Security", "Marketplace", "Education", "Identity", "Other"] + "enum":["Games", "DeFi", "Gambling", "Exchanges", "Collectibles", "Marketplaces", "Social", "Other"] }, "description": "One or more categories. Category MUST be one of the following schema definition." }, @@ -315,19 +324,15 @@ The dApp Registration certificate itself doesn't enforce a particular structure "releaseNumber": { "type": "string", "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*))?$", - "description": "Semver compatible release number (major.minor.patch), e.g. 1.2.3, where 1 is major, 2 is a minor and 3 is a patch." + "description": "Semver compatible release number (major.minor.patch) or (major.minor.patch-some_text) e.g. 1.2.3 or 1.1.1-alpha" }, "releaseName": { "type": "string", "description": "An optional human readable release name, e.g. V1" }, - "tags": { - "type":"array", - "items": { - "type": "string", - "enum":["SECURITY_VULNERABILITY", "DESIGN_FLAW"], - "description": "dApp owners can mark an app with special tags to indicate, e.g. security vulnerability. Stores can mark releases in a special way depending in the context." - } + "security_vulnerability": { + "type": "boolean", + "description": "Indicates that a given version has a security vulnerability." }, "comment": { "type": "string", @@ -438,7 +443,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "description" ] } -``` + ``` This schema describes the minimum required fields for a store to be able to display and validate your dApp. You can add any other fields you want to the metadata, but we recommend that you use at least the ones described above. @@ -581,8 +586,15 @@ We added DE_REGISTER in additon to already existing `REGISTER`. The idea is that `Type` field can be `PLUTUS` or `NATIVE`, we made it optional and there are already two dApps at least on Cardano at the time of writing, which are only using NATIVE scripts. This optional field helps to differentiante between NATIVE script based and NON_NATIVE dApps. ### Version Deprecation -We discussed scenario what to do in case a dApp team wants to deprecate a particular version. Upon a few iteration we settled on doing this in off-chain section. It can be done via tags, e.g. tag: "SECURITY_VULNERABILITY. `Tags` is newly introduced field, available only in the off-chain JSON. Changes to any versions will require on-chain re-registration -since rootHash changes. +We discussed scenario what to do in case a dApp team wants to deprecate a particular version. Upon a few iteration we settled on doing this in off-chain section. + +### Version Security Vulnerability Flagging +It is not uncommon to see a dApp release a version and then release a fix in the new version and flag the previous version +as having security vulnerability. We are intoducing an optional field in the offchain json on the release level: `security_vulnerability": true. + +### Comment Field (on-chain JSON) +We are introducing a field in the on-chain JSON only, which allows dApp development teams to provide a free text field +comment about changes they are making in a given (re-)registration request. ## Path to Active We will evaluate for a few months if we have not missed any details, collect feedback from dApp developers, stores. We reserve right to make small changes in this time, while the proposal diff --git a/CIP-0072/version_1_offchain.json b/CIP-0072/version_1_offchain.json index 622eb16810..e3b77a7b40 100644 --- a/CIP-0072/version_1_offchain.json +++ b/CIP-0072/version_1_offchain.json @@ -91,13 +91,9 @@ "type": "string", "description": "An optional human readable release name, e.g. V1" }, - "tags": { - "type":"array", - "items": { - "type": "string", - "enum":["SECURITY_VULNERABILITY", "DESIGN_FLAW"], - "description": "dApp owners can mark an app with special tags to indicate, e.g. security vulnerability. Stores can mark releases in a special way depending in the context." - } + "security_vulnerability": { + "type": "boolean", + "description": "Indicates that a given version has a security vulnerability." }, "comment": { "type": "string", diff --git a/CIP-0072/version_1_onchain.cddl b/CIP-0072/version_1_onchain.cddl index 5047c5192c..88be84c377 100644 --- a/CIP-0072/version_1_onchain.cddl +++ b/CIP-0072/version_1_onchain.cddl @@ -3,28 +3,30 @@ string = bstr .size (1..64) ; tstr / string from 1 up to 64 chars only sig_256 = bstr .size (64..64) ; 256 bytes signature (256 / 64 = 4 bytes) transaction_metadata = { - "1667": on-chain_metadata + 1667: on-chain_metadata } on-chain_metadata = { - "subject": string - , "rootHash": sig_256 - , "metadata": [+ string] / [+ string / [+ string]] - , "type": registration / de-registration - , "signature": signature + subject: string, + rootHash: sig_256, + metadata: [+ string] / [+ string / [+ string]], + type: registration / de-registration, + signature: signature, } registration = { - "action": "REGISTRATION" + action: "REGISTRATION", + ? comment: string, } de-registration = { - "action": "DE_REGISTRATION" + action: "DE_REGISTRATION", + ? comment: string, } signature = { - "r": string - , "s": string - , "algo": text .regexp "Ed25519-EdDSA" - , "pub": string -} \ No newline at end of file + r: string, + s: string, + algo: text .regexp "Ed25519-EdDSA", + pub: string, +} diff --git a/CIP-0072/version_1_onchain.json b/CIP-0072/version_1_onchain.json index 57867f96e4..ce480fadd1 100644 --- a/CIP-0072/version_1_onchain.json +++ b/CIP-0072/version_1_onchain.json @@ -47,6 +47,12 @@ "enum":["REGISTER", "DE_REGISTER"], "pattern": "^(REGISTER|DE_REGISTER)$", "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." + }, + "comment": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "A free text field to provide details about this particular changes (64 chars limited)." } }, "required":[ From 4278f7f7c335e0fbeb38dc14e8f42a3248ce1a9a Mon Sep 17 00:00:00 2001 From: matiwinnetou Date: Fri, 28 Apr 2023 12:36:56 +0200 Subject: [PATCH 59/63] Update CIP-0072/README.md Co-authored-by: Marcin Mazurek --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 254cb9ce65..4b6f712ca0 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -330,7 +330,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "type": "string", "description": "An optional human readable release name, e.g. V1" }, - "security_vulnerability": { + "securityVulnerability": { "type": "boolean", "description": "Indicates that a given version has a security vulnerability." }, From 7ddd6e0de2f979dd5c9b820c329d72f91670c144 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Fri, 28 Apr 2023 13:10:17 +0200 Subject: [PATCH 60/63] latest comment fixes --- CIP-0072/README.md | 13 ++++++------- CIP-0072/version_1_offchain.json | 2 +- CIP-0072/version_1_onchain.cddl | 4 ++-- CIP-0072/version_1_onchain.json | 1 - 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 4b6f712ca0..0eeb1bbbb9 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -52,7 +52,7 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "subject": "b37aabd81024c043f53a069c91e51a5b52e4ea399ae17ee1fe3cb9c44db707eb", "rootHash": "7abcda7de6d883e7570118c1ccc8ee2e911f2e628a41ab0685ffee15f39bba96", "metadata": [ - "https://cip26.foundation.app/my_dapp_7abcda.json" + "https://foundation.app/my_dapp_7abcda.json" ], "type": { "action": "REGISTER", @@ -100,13 +100,13 @@ on-chain_metadata = { } registration = { - action: "REGISTRATION", - ? comment: string, ; max 64 chars + action: "REGISTER", + ? comment: string, } de-registration = { - action: "DE_REGISTRATION", - ? comment: string, ; max 64 chars + action: "DE_REGISTER", + ? comment: string, } signature = { @@ -168,7 +168,6 @@ which can be expressed using JSON schema. "action":{ "type":"string", "enum":["REGISTER", "DE_REGISTER"], - "pattern": "^(REGISTER|DE_REGISTER)$", "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." }, "comment": { @@ -590,7 +589,7 @@ We discussed scenario what to do in case a dApp team wants to deprecate a partic ### Version Security Vulnerability Flagging It is not uncommon to see a dApp release a version and then release a fix in the new version and flag the previous version -as having security vulnerability. We are intoducing an optional field in the offchain json on the release level: `security_vulnerability": true. +as having security vulnerability. We are intoducing an optional field in the offchain json on the release level: `securityVulnerability": true. ### Comment Field (on-chain JSON) We are introducing a field in the on-chain JSON only, which allows dApp development teams to provide a free text field diff --git a/CIP-0072/version_1_offchain.json b/CIP-0072/version_1_offchain.json index e3b77a7b40..d1e8b306df 100644 --- a/CIP-0072/version_1_offchain.json +++ b/CIP-0072/version_1_offchain.json @@ -91,7 +91,7 @@ "type": "string", "description": "An optional human readable release name, e.g. V1" }, - "security_vulnerability": { + "securityVulnerability": { "type": "boolean", "description": "Indicates that a given version has a security vulnerability." }, diff --git a/CIP-0072/version_1_onchain.cddl b/CIP-0072/version_1_onchain.cddl index 88be84c377..f605418180 100644 --- a/CIP-0072/version_1_onchain.cddl +++ b/CIP-0072/version_1_onchain.cddl @@ -15,12 +15,12 @@ on-chain_metadata = { } registration = { - action: "REGISTRATION", + action: "REGISTER", ? comment: string, } de-registration = { - action: "DE_REGISTRATION", + action: "DE_REGISTER", ? comment: string, } diff --git a/CIP-0072/version_1_onchain.json b/CIP-0072/version_1_onchain.json index ce480fadd1..ef9bf510d6 100644 --- a/CIP-0072/version_1_onchain.json +++ b/CIP-0072/version_1_onchain.json @@ -45,7 +45,6 @@ "action":{ "type":"string", "enum":["REGISTER", "DE_REGISTER"], - "pattern": "^(REGISTER|DE_REGISTER)$", "description":"Describes the action this certificate is claiming; i.e 'REGISTER', for a new dApp or an update, DE_REGISTER for asserting that the dApp's development is stopped, and it is deprecated. So, no further dApp's on-chain update is to be expected." }, "comment": { From 4bf454d3ba12d5c38fafeeaa98d31788b3532017 Mon Sep 17 00:00:00 2001 From: Matthias Benkort <5680256+KtorZ@users.noreply.github.com> Date: Tue, 30 May 2023 09:25:37 +0200 Subject: [PATCH 61/63] Apply suggestions from code review Co-authored-by: Ryan Williams <44342099+Ryun1@users.noreply.github.com> --- CIP-0072/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index 0eeb1bbbb9..fe5f58a99e 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -384,7 +384,7 @@ The dApp Registration certificate itself doesn't enforce a particular structure "type": "string", "enum":["SPEND", "MINT"] }, - "description": "Purpouses of the script, SPEND or MINT (notice it can be both for some modern Cardano languages)." + "description": "Purposes of the script, SPEND or MINT (notice it can be both for some modern Cardano languages)." }, "type":{ "enum":["PLUTUS", "NATIVE"], @@ -546,9 +546,9 @@ Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, ### Categories `Categories` is a predefined enum with values defined in the CIP / schema, it is *NOT* a free text field, rationale for this is that dApp developers will have no idea what ontology / classification to use, which will likely result in many duplicates of the same thing. -### Purpouse Field As an Array or as a Single Item? +### Purpose Field As an Array or as a Single Item? It may have been visible that we have a `purpose` field, which can be: "SPEND" or "MINT", those fields directly map to what is allowed by a Cardano Smart Contract. As of the time of writing CIP - PlutusTx does not allow a script to be both of type: "SPEND" and "MINT", however, there are new -languages on Cardano being worked on where they already allow one validator to be both spending UTxOs and minting tokens - all with the same script hash. To be open for the future it has been agreed to turn `purpouse` field into `purpouses` and make it a JSON array. +languages on Cardano being worked on where they already allow one validator to be both spending UTxOs and minting tokens - all with the same script hash. To be open for the future it has been agreed to turn `purpose` field into `purposes` and make it a JSON array. ### Parametrised Scripts On Cardano, there are parametrised scripts, meaning that before compilation takes place, it is possible to pass certain parameters instead of using `Datum`. @@ -609,5 +609,4 @@ update the proposal to be in `ACTIVE` state. - Reference implementation: https://github.com/Cardano-Fans/crfa-dapp-registration-and-certification-service (incubator) ## Copyright -[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode -[Apache-2.0]: http://www.apache.org/licenses/LICENSE-2.0 +[CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode) From d664ed293562102a4cdb86096c2c8659f58b0715 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 8 Jun 2023 21:53:51 +0200 Subject: [PATCH 62/63] changes according to the recent comments --- CIP-0072/README.md | 68 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index fe5f58a99e..df2db0b420 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -6,7 +6,7 @@ Category: Metadata Authors: - Bruno Martins - Mateusz Czeladka -Implementors: [] +Implementors: ["Lace Wallet dApp Store", "DappsOnCardano dApp Store"] Discussions: - https://github.com/cardano-foundation/CIPs/pull/355 Created: 2022-10-18 @@ -14,11 +14,13 @@ License: CC-BY-4.0 --- ## Abstract + dApp developers do not have a standardised method to record immutable, persistent claims about their dApp(s) that their users can verify. A dApp developer needs to "register" their dApp by providing a set of claims about their dApp(s) that can be verified by the user. This CIP describes a standardised method for dApp developers to register their dApp(s) on-chain and for users to verify the claims made by dApp developers. This proposal aims to standardise the process of dApp registration and verification, and to provide a set of claims that dApp developers can use to register their dApp(s). ## Motivation: why is this CIP necessary? + dApps can express a plethora of information. Some of this information could be claims about who the developer is, what the dApp's associated metadata is, and more. This data lacks standardisation, persistence, and immutability. Data without these features, means that dApp users cannot verify if the dApp's expressed information is consistent across time. The goal of this CIP is to formalise how dApps register their information with a new transaction metadata format that can record the dApp's metadata, ownership, and potentially developer's identity. This formalisation means dApp users can verify if the data expressed by a dApp is consistent with what was registered on-chain. Also, having this formalisation facilitates any actor in the ecosystem to index and query this data, and provide a better user experience when it comes to dApp discovery and usage. @@ -26,6 +28,7 @@ Also, having this formalisation facilitates any actor in the ecosystem to index ## Specification ### **Definitions** + - **anchor** - A hash written on-chain (rootHash) that can be used to verify the integrity (by way of a cryptographic hash) of the data that is found off-chain. - **dApp** - A decentralised application that is described by the combination of metadata, certificate and a set of used scripts. - **metadata claim** - Generically any attempt to map off-chain metadata to an on-chain subject. This specification looks at dApp specific metadata claims. Caution: it is highly recommended that dApp developers provide links to a specific snapshot (version) without removing all previous snapshots / version links. Some stores may choose not to show a dApp if all off-chain historical versions are not available but instead only latest snapshot. @@ -34,12 +37,15 @@ Also, having this formalisation facilitates any actor in the ecosystem to index - **publishers** - Entities which publish metadata claims on-chain, in the case of dApps the publishers are likely the dApp developer(s). ### **Developers / Publishers** + Developers and publishers of dApps can register their dApps by submitting a transaction on-chain that can be indexed and verified by stores, auditors and other ecosystem actors. ### **Stores / Auditors** + Stores and auditors should be able to follow the chain and find when a new dApp registration is **anchored** on-chain. They should then perform *integrity* and *trust* validations on the dApp's certificate and metadata. #### **Suggested Validations** + - **`integrity`**: The dApp's off-chain metadata should match the metadata **anchored** on-chain. - **`trust`**: The dApp's certificate should be signed by a trusted entity. It's up to the store/auditor to decide which entities are trusted and they should maintain and publish their own list of trusted entities. Although this entities might be well known, it's not the responsibility of this CIP to maintain this list. These entities could be directly associated with developer/publisher or not. @@ -58,19 +64,21 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser "action": "REGISTER", "comment": "New release adding zapping support." }, - "signature": { - "r": "27159ce7d992c98fb04d5e9a59e43e75f77882b676fc6b2ccb8e952c2373da3e", - "s": "16b59ab1a9e349cd68d232f7652f238926dc24a2e435949ebe2e402a6557cfb4", - "algo": "Ed25519−EdDSA", - "pub": "b384b53d5fe9f499ecf088083e505f40d2a6c123bf7201608494fdb89a051b80" - } + "signature": { + "r": "27159ce7d992c98fb04d5e9a59e43e75f77882b676fc6b2ccb8e952c2373da3e", + "s": "16b59ab1a9e349cd68d232f7652f238926dc24a2e435949ebe2e402a6557cfb4", + "algo": "Ed25519−EdDSA", + "pub": "b384b53d5fe9f499ecf088083e505f40d2a6c123bf7201608494fdb89a051b80" + } } ``` ### Properties + *`subject`*: Identifier of the claim subject (dApp). A UTF-8 encoded string, max 64 chars. The uniqueness of this property cannot be guaranteed by the protocol and multiple claims for the same subject may exist, therefore it is required to exist some mechanism to assert trust in the *veracity* of this property. *`type`*: The type of the claim. This is a JSON object that contains the following properties: + - *`action`*: The action that the certificate is asserting. It can take the following values: - *`REGISTER`*: The certificate is asserting that the dApp is registered for the first time or is providing an update. - *`DE_REGISTER`*: The certificate is asserting that the dApp is deprecated / archived. So, no further dApp's on-chain update is expected. @@ -82,6 +90,7 @@ The on-chain dApp registration certificate MUST follow canonical JSON and be ser *`signature`*: The signature of the certificate. The publishers generate the signature is by first turning on-chain JSON into a canonical form (RFC 8765), hashing it with blake2b-256 and generating a signature of the hash. Stores / clients can verify the signature by repeating the process, they can use the public key to verify the signature of the certificate. Fields used for canonical JSON: ["subject", "rootHash", "metadata","type"]. Please note that a signature should be generated of blake2b-256 hash as a byte array, not as a hex represented string(!). ### On chain CDDL for registration / de-registration + ``` string = bstr .size (1..64) ; tstr / string from 1 up to 64 chars only @@ -120,6 +129,7 @@ signature = { which can be expressed using JSON schema. ### dApp on-chain certificate JSON Schema + ```json { "$schema":"https://json-schema.org/draft/2020-12/schema", @@ -228,11 +238,13 @@ which can be expressed using JSON schema. ``` ### Metadata Label + When submitting the transaction metadata pick the following value for `transaction_metadatum_label`: - `1667`: dApp Registration ### Off-chain Metadata Format + The dApp Registration certificate itself doesn't enforce a particular structure to the metadata you might fetch off-chain. However, we recommend that you use the following structure: ```json @@ -495,11 +507,13 @@ This schema describes the minimum required fields for a store to be able to disp ``` ### **Stores Custom fields** + Each store might have their own requirements for the metadata. For example, some stores might require a field for logo, or screenshots links. The store's should adviertise what fields they require in their documentation so that developers are aware and they can include them in the metadata. ### **Offchain Metadata Storage** There are multiple options to store metadata offchain. The most common options are: + - [CIP-26](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0026) compliant servers - [IPFS](https://ipfs.tech/) - [Bitbucket](https://bitbucket.org/) @@ -508,6 +522,7 @@ There are multiple options to store metadata offchain. The most common options a ## Rationale: how does this CIP achieve its goals? ### Decoupling of dApp Registration From Certifications / Audits + We quickly reached a conclusion that it is better to separate them and keep scope of CIP smaller. During discussions it became clear that while there is some overlap of certifications / audits with dApp registration, this overlap is small and can be even removed. At one point we wanted to couple certifications CIP to this CIP (e.g. via some link or dApp version) but we analyzed how dApp developers are currently following the process and we noticed @@ -516,48 +531,61 @@ that dApp registration and certifications are different CIPs but they are very l whether those have been certified / explicitly mentioned in the audit. ### Small Metadata Anchor On Chain + This one is rather obvious but for the sake of completeness worth documenting. We analyzed how much we should put on-chain vs off-chain and we quickly reached the conclusion that it is better to keep small amount of data on-chain and larger chunk off-chain for which is what exactly CIP-26 is meant for. ### CIP-26 as *ONE* of Storage Layers + We believe that CIP-26 is geared towards storing this type of off-chain metadata format but we don't want by any means to stipulate / police this form of storage. In fact it is possible to use offchain metadata storage alternatives such as CIP-26 compatible server / direct http(s) hosting / IPFS, etc. ### How to Find Off-Chain Data? + We went back and forth whether we should actually store link (links) to off-chain metadata, eventually we settled on a solution that this is required because there could be a situation that a dApp registration may have off-chain metadata stored somewhere but some stores have it, others don't have it. Now it is required that a dApp developer points to at least one store that has off-chain metadata (as a reference metadata). ### Optional Release Name? + Release Name is a field, which dApp developers can use on top of Release Version, it has been debated whether field should be mandatory or optional but eventually it has been agreed that we do not want to enforce this field, Release Name is an optional field, Release Version, however, needs to follow semver and is a mandatory field. ### Canonical JSON + At the begining neither on-chain, nor off-chain JSON has been following RFC 8785 (canonical JSON) but we reached a point that, due to consistency checks, we need to take hash of both on-chain and off-chain and this forced us to stipulate that both on-chain and off-chain metadata documents need to be converted according to RFC 8785 before taking a blake2b-256 hash of them. ### On-Chain Signature Scope + On-chain part has a signature, which has a role to verify that a certain dApp owner made changes. In the initial version, a blake2b-256 signature was needed only for `rootHash` but following discussion, due to security concerns, decision has been made that the signature should attest the whole on-chain canonical JSON except signature field itself (because it would end up in an infinite recursion). ### Who Is The Owner? + Smart contracts are ownerless, it has been debated that there could be multiple claims to the same dApps from different parties. The standard doesn't prevent anyone from making a claim, so it's up to the different operator to their diligence work and make their own choices of whom they trust. The signature should give the most confidence as anyone can collect known public keys from known development companies. Future CIP revisions can include DID's and Verifiable Credentials to tackle this problem in a more elegant way. ### DIDs + Since DIDs / Verifiable Credetials are not yet widely used in Cardano ecosystem, usage of them in this initial CIP version has been de-scoped. ### Categories + `Categories` is a predefined enum with values defined in the CIP / schema, it is *NOT* a free text field, rationale for this is that dApp developers will have no idea what ontology / classification to use, which will likely result in many duplicates of the same thing. ### Purpose Field As an Array or as a Single Item? + It may have been visible that we have a `purpose` field, which can be: "SPEND" or "MINT", those fields directly map to what is allowed by a Cardano Smart Contract. As of the time of writing CIP - PlutusTx does not allow a script to be both of type: "SPEND" and "MINT", however, there are new languages on Cardano being worked on where they already allow one validator to be both spending UTxOs and minting tokens - all with the same script hash. To be open for the future it has been agreed to turn `purpose` field into `purposes` and make it a JSON array. ### Parametrised Scripts + On Cardano, there are parametrised scripts, meaning that before compilation takes place, it is possible to pass certain parameters instead of using `Datum`. The consequence of this will be that as we pass different parameters, script hash will be changing. This is especially troublesome for things like certifications / audits but also dApp registration. This topic is being debated as part of CIP: https://github.com/cardano-foundation/CIPs/pull/385, however, it doesn't seem that there has been conclusion how to tackle this problem. For the moment, a new script hash (despite changing only a parameter) requires a re REGISTRATION to the existing dApp with a requirement to add new version(s) in the dApp's off-chain metadata. ### Often Changing Scripts + There are cases on Cardano main-net that script hashes are changing every day, most probably due to parameterised scripts. It is responsibility of the developers to issue an `REGISTRATION` command and provide on-chain and off-chain metadata following the change, for scripts that are changing daily / hourly it is envisaged that this process be automated by a dApp developer. ### Beacon Tokens Instead of Metadata + It has been argued that since anybody can make claims to dApps, this CIP instead of using metadata should use tokens. dApp developers would mint token, which would ensure they are the owners of a given dApp. It is a certainly an interesting approach but shortcomings of the current solution can also be lifted by moving to DID based system and benefit of metadata is that it is easily queriable off chain @@ -565,48 +593,60 @@ and currently stores can attest / validate multiple claims for the same dApp. Fo and potentially hinder it's adoption. ### Datums Instead of Metadata + It has been suggested that we do not use metadata but rather Datums. Metadata cannot enforce format and Datums could. It has been rejected as using Datums requires a smart contract and we want to keep this solution as accessible as possible. It is a GUI concern since if there is a some app that can attest validity and conformance to JSON schema - dApp Registration / Update MUST never be done that does not conform to the schema. ### Scripts / Releases Fields Are Not Required + We made a decision to change the schema so that scripts and releases are no longer required. This could help to get initial registration from dApp developers faster and some stores simply do not require dApps to add their scripts in order to be listed. ### Schema Version + We discussed and analyzed idea of schema version and or even whole CIP version. It turns out that CIP is already versioned by CIP-??? where ??? is version number. During this CIP being in `PROPOSED` state we reserve our right to make small changes to the schema / document, after CIP becomes active, it will require a new CIP. This is the current process, which other CIPs are also following. ### Tags + We briefly discussed tags and we will likely introduce tags in the future. An array of tags to help stores / dApp developers categories where their dApp should show. This will complement `categories` field. ### DE_REGISTER + We added DE_REGISTER in additon to already existing `REGISTER`. The idea is that once dApp devs want to deprecate dApp they can now issue DE_REGISTER request. ### Type Field + `Type` field can be `PLUTUS` or `NATIVE`, we made it optional and there are already two dApps at least on Cardano at the time of writing, which are only using NATIVE scripts. This optional field helps to differentiante between NATIVE script based and NON_NATIVE dApps. ### Version Deprecation + We discussed scenario what to do in case a dApp team wants to deprecate a particular version. Upon a few iteration we settled on doing this in off-chain section. ### Version Security Vulnerability Flagging + It is not uncommon to see a dApp release a version and then release a fix in the new version and flag the previous version as having security vulnerability. We are intoducing an optional field in the offchain json on the release level: `securityVulnerability": true. ### Comment Field (on-chain JSON) + We are introducing a field in the on-chain JSON only, which allows dApp development teams to provide a free text field comment about changes they are making in a given (re-)registration request. ## Path to Active -We will evaluate for a few months if we have not missed any details, collect feedback from dApp developers, stores. We reserve right to make small changes in this time, while the proposal -is in `PROPOSED` status. After certain period (no longer than 6 months), from time of merging PR in `PROPOSED` status to the main / master branch, we will -update the proposal to be in `ACTIVE` state. + +We will evaluate for a few months if we have not missed any details, collect feedback from dApp developers, stores. We reserve right to make small changes in this time, while the proposal is in the `PROPOSED` status / state. +Once `Acceptance Criteria` are met and all comments / feedback from dApp developers is addressed, we will update the proposal to be in `ACTIVE` state. ### Acceptance Criteria -- IOG and CF approval -- Community representative approval (Santiago / TxPipe and Marcel / Eternl wallet) -- PR to https://github.com/cardano-foundation/CIPs/blob/master/CIP-0010/registry.json + +- At least 3 dApps register via following this CIP +- At least one Implementator (main-net) implements the store indexing this CIP metadata from on-chain ### Implementation Plan -- Reference implementation: https://github.com/Cardano-Fans/crfa-dapp-registration-and-certification-service (incubator) + +- DappsOnCardano dApp Store: https://github.com/Cardano-Fans/crfa-dapp-registration-and-certification-service for DappsOnCardano.com +- Lace's Wallet dApp Store: https://github.com/input-output-hk/lace ## Copyright + [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode) From 07c1723c7d19d2a8a72a15b16e9581932a2a651a Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Thu, 8 Jun 2023 21:55:16 +0200 Subject: [PATCH 63/63] correction on Acceptance Criteria --- CIP-0072/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0072/README.md b/CIP-0072/README.md index df2db0b420..bc234d1f0a 100644 --- a/CIP-0072/README.md +++ b/CIP-0072/README.md @@ -639,7 +639,7 @@ Once `Acceptance Criteria` are met and all comments / feedback from dApp develop ### Acceptance Criteria -- At least 3 dApps register via following this CIP +- At least 3 non trivial dApps from 3 different teams register on-chain / off-chain via following this CIP - At least one Implementator (main-net) implements the store indexing this CIP metadata from on-chain ### Implementation Plan