Skip to content

Commit

Permalink
Merge pull request cardano-foundation#2 from GeorgeFlerovsky/nft-meta…
Browse files Browse the repository at this point in the history
…data-oracle-cddl

CDDL files
  • Loading branch information
nicolasayotte authored Jan 25, 2023
2 parents 1964b26 + 182ccd1 commit fcb3cab
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 0 deletions.
153 changes: 153 additions & 0 deletions CIP-????/cddl/version_1.cddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
; "????" to be replaced by the CIP number, as a `uint`.
metadata = { ???? => action }

; =========================================================================
; CIP-???? actions

action =
{
? assign_metadata_oracle : action_oracle,
? simple_metadata_update : action_simple,
? regex_metadata_update : action_regex,
? tabular_metadata_update : action_tabular
}

action_oracle = { * policy_id => oracle_assignment }

oracle_assignment =
{
? main_address : address,
? update_address : address
}

action_simple = { * policy_id => { * asset_name => metadata_details } }

action_regex = { * policy_id => { * asset_regex => metadata_details } }

action_tabular = { * policy_id => csv_update_opaque }

; Technically, both policy IDs and asset names should be 32 bytes long.
; However, this isn't enforced for asset names, and CIP-25v1 already treats
; these as `text_64`, so we don't enforce the more narrow `bytes_32` type
; here.
policy_id = text_64
asset_name = text_64

asset_regex = text_regex_extendable

; =========================================================================
; Backwards compatibility with CIP-25 (simple and regex metadata updates)
; Definitions for the following fields in `metadata_details` should follow
; the same schema as in CIP-25, except that `name` and `image` are optional.
; Other fields can have arbitrary `transaction_metadatum` values.
metadata_details =
{
? name : text_64,
? image : text_extendable,
? mediaType : text_64,
? description : text_extendable,
? files : [* files_details],
* ( label_64 => transaction_metadatum )
}

files_details =
{
name : text_64,
mediaType : text_64,
src : text_extendable
}

; =========================================================================
; Tabular updates' CSV schema

; Cardano ledger imposes a fixed size of 64 on text and bytestrings,
; which prevents us from directly encoding a CSV table as a single long
; text. This means that, formally, the CSV in a tabular update
; is just an opaque extendable text (i.e. a fixed text or an array of fixed
; texts).
csv_update_opaque = text_extendable

; Informally, if we concatenate the `csv_update_opaque` value to a single long
; text, and then split it on unescaped newline characters, then it should comply
; with the following cddl schema.
; (Newline characters inside of a double-quoted field value are considered
; escaped, which means that they do no indicate the start of a new record.)
csv_update = [ header, * record ]
header = [ "tokenName", * header_field ]
record = [ text_64, * record_field ]
header_field = text
record_field = text

; For a given `policy_id`, a `csv_update` value can be transformed into a
; `metadata_details` value as follows:
; 1. Pair each `record_field` with its corresponding `header_field`
; (i.e. like zipping two lists).
; 2. Transform each `header_field` into a `[header_field_part]` array, by
; splitting it on the '.' character.
; 3. For each pair of `record_field` and `[header_field_part]` values, construct
; the following nested object:
; csv_nested_object =
; { header_field_part[0] =>
; { header_field_part[1] =>
; { header_field_part[2] =>
; ...
; { header_field_part[N] => `record_field` }
; ...
; }
; }
; }
; 4. For each record, combine and normalize its record fields' constructed
; nested objects into a single unified object for that record. Nest the
; unified object under the record's "tokenName" value:
; csv_record_object = { text_64 => Union([csv_nested_object]) }
; 5. Unify the `record_object`s into a single object, and then nest it under
; the `policy_id`:
; csv_policy_object = { policy_id => Union([csv_record_object]) }
; 6. Combine the `action_simple_single` values into a single `action_simple`
; value:
; csv_update_simple = Union([csv_policy_object])
;
; The effect of a `csv_update_opaque` on the token metadata state in the
; CIP-???? indexer must be the same as the effect of the corresponding
; `csv_update_simple` (applied as a simple update action).

; =========================================================================
; Imported from cardano-ledger/.../babbage.cddl
transaction_metadatum =
{ * transaction_metadatum => transaction_metadatum }
/ [ * transaction_metadatum ]
/ int
/ bytes_64
/ text_64

address = bytes

; =========================================================================
; Convenient type aliases

; Fixed-size text and bytes
label_32 = bytes_32 / text_32
bytes_32 = bytes .size (0..32)
text_32 = text .size (0..32)

label_64 = bytes_64 / text_64
bytes_64 = bytes .size (0..64)
text_64 = text .size (0..64)

; Extendable text and bytes
text_extendable = text_64 / [ * text_64 ]
bytes_extendable = bytes_64 / [ * bytes 64 ]

; Regex (fixed-size)
; Tag 35 is for regular expressions in Perl Compatible Regular
; Expressions (PCRE) / JavaScript syntax [ECMA262].
; https://www.rfc-editor.org/rfc/rfc7049#section-2.4.4.3
; https://www.ecma-international.org/publications-and-standards/standards/ecma-262/
text_regex = #6.35(text_64)

; Regex (extendable size)
; Technically, CBOR maps can have arrays as keys. This prevents them from being
; directly convertable to JSON, but we can recover JSON-convertability by
; concatenating the array-valued key into a single UTF-8 text.
; The resulting concatenated text should be interpreted as `#6.35(text)`.
text_regex_extendable = text_extendable
85 changes: 85 additions & 0 deletions CIP-????/cddl/version_2.cddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
; "????" to be replaced by the CIP number, as a `uint`.
metadata = { ???? => action }

; =========================================================================
; CIP-???? actions

; When version 2 mode is enabled for a CIP-???? action, all `policy_id` and
; `asset_name` values are interpreted as `bytes_64`, similar to CIP-25v2.
action =
{
version = 2,
? assign_metadata_oracle : action_oracle,
? simple_metadata_update : action_simple,
}

; Regex and tabular updates are disallowed in version 2, because it is unclear
; how to apply regular expressions to non-UTF-8 bytestrings (or their
; corresponding hex encodings) and it is unclear how to embed raw bytestrings
; in CSV.

action_oracle = { * policy_id => oracle_assignment }

oracle_assignment =
{
? main_address : address,
? update_address : address
}

action_simple = { * policy_id => { * asset_name => metadata_details } }

; Technically, both policy IDs and asset names should be 32 bytes long.
; However, this isn't enforced for asset names, and CIP-25v2 already treats
; these as `bytes_64`, so we don't enforce the more narrow `bytes_32` type
; here.
policy_id = bytes_64
asset_name = bytes_64

; =========================================================================
; Backwards compatibility with CIP-25 (simple and regex metadata updates)
; Definitions for the following fields in `metadata_details` should follow
; the same schema as in CIP-25, except that `name` and `image` are optional.
; Other fields can have arbitrary `transaction_metadatum` values.
metadata_details =
{
? name : text_64,
? image : text_extendable,
? mediaType : text_64,
? description : text_extendable,
? files : [* files_details],
* ( label_64 => transaction_metadatum )
}

files_details =
{
name : text_64,
mediaType : text_64,
src : text_extendable
}

; =========================================================================
; Imported from cardano-ledger/.../babbage.cddl
transaction_metadatum =
{ * transaction_metadatum => transaction_metadatum }
/ [ * transaction_metadatum ]
/ int
/ bytes_64
/ text_64

address = bytes

; =========================================================================
; Convenient type aliases

; Fixed-size text and bytes
label_32 = bytes_32 / text_32
bytes_32 = bytes .size (0..32)
text_32 = text .size (0..32)

label_64 = bytes_64 / text_64
bytes_64 = bytes .size (0..64)
text_64 = text .size (0..64)

; Extendable text and bytes
text_extendable = text_64 / [ * text_64 ]
bytes_extendable = bytes_64 / [ * bytes 64 ]

0 comments on commit fcb3cab

Please sign in to comment.