Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIP-0029 | Phase-1 Monetary Scripts Serialization Formats #117

Merged
merged 4 commits into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions CIP-0029/CIP-0029.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
CIP: 29
Title: Phase-1 Monetary Scripts Serialization Formats
Authors: Matthias Benkort <matthias.benkort@iohk.io>
Comments-URI: https://github.com/cardano-foundation/CIPs/pulls/117
Status: Draft
Type: Standards
Created: 2020-08-17
License: CC-BY-4.0
---

# Abstract

This specification describes how to serialize Phase-1 monetary scripts (a.k.a. _"native scripts"_) to various formats (JSON, CBOR) to facilitate inter-operability between applications.

# Motivation

While the existence of scripts is well-known, and have an unambiguous on-chain representation. There's no agreed upon format for off-chain or higher-level interfaces for which a binary string is a poor fit. This CIP regroups both the on-chain binary format and other, more verbose, formats like JSON.

# Specification

This specification covers at present two serialization formats: JSON and CBOR. The CBOR matches exactly the on-chain representation and is extracted from the cardano-ledger-specs source code and put here as a convenient place to lookup while the source can change location over time.

## CBOR

The CBOR serialization format is given as a [CDDL specification in annexe](./phase-1-monetary-scripts.cddl). When a hash of the phase-1 monetary script is needed, it usually refers to a Blake2b-192 digest of the corresponding serialized script byte-string prefixed with a null byte: `\x00`.

## JSON

The JSON format is given as a [JSON schema in annexe](./phiase-1-monetary-scripts.json). It is preferred in user interfaces such as command-lines or APIs, where some level of human inspection may be required.

## Notes

- Scripts may contain unbounded integers! Implementation parsing them, either from CBOR or JSON shall be prepared to handle possible big integers (>= 2^64).

# Rationale

- The preimage for computing script hashes is prefixed with `\x00` to distinguish them from phase-2 monetary scripts (a.k.a Plutus Script) which are then prefixed with `\x01`. This is merely a discriminator tag.

- The current JSON format is based off the cardano-cli's format which has been used widely for minting tokens and is likely the most widely accepted format at the moment.

# Backward Compatibility

N/A

# Reference Implementation(s)

- [cardano-cli](https://github.com/input-output-hk/cardano-node/tree/master/cardano-cli) & [cardano-api](https://github.com/input-output-hk/cardano-node/tree/master/cardano-api)

## Test Vectors

```yaml
- json:
{ "type": "sig"
, "keyHash": "00000000000000000000000000000000000000000000000000000000"
}
cbor:
"8200581c00000000000000000000000000000000000000000000000000000000"

- json:
{ "type": "all"
, "scripts":
[ { "type": "sig"
, "keyHash": "00000000000000000000000000000000000000000000000000000000"
}
, { "type": "any"
, "scripts":
[ { "type": "after"
, "slot": 42
}
, { "type": "sig"
, "keyHash": "00000000000000000000000000000000000000000000000000000001"
}
]
}
]
}
cbor:
"8201828200581c000000000000000000000000000000000000000000000000000000008202828204182a8200581c00000000000000000000000000000000000000000000000000000001"

- json:
{ "type": "before"
, "slot": 42
}
cbor:
"8205182a"

- json:
{ "type": "atLeast"
, "required": 2
, "scripts":
[ { "type": "sig", "keyHash": "00000000000000000000000000000000000000000000000000000000" }
, { "type": "sig", "keyHash": "00000000000000000000000000000000000000000000000000000001" }
, { "type": "sig", "keyHash": "00000000000000000000000000000000000000000000000000000002" }
]
}
cbor:
"00830302838200581c000000000000000000000000000000000000000000000000000000008200581c000000000000000000000000000000000000000000000000000000018200581c00000000000000000000000000000000000000000000000000000002"
```

# Copyright

CC-BY-4.0
33 changes: 33 additions & 0 deletions CIP-0029/phase-1-monetary-scripts.cddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
script =
[ script_key
// script_all
// script_any
// script_n_of_k
// script_after
// script_before
KtorZ marked this conversation as resolved.
Show resolved Hide resolved
]

script_key =
(0, keyhash)

script_all =
(1, [ * script ])

script_any =
(2, [ * script ])

script_n_of_k =
(3, n: uint, [ * script ])

; Timelock validity intervals are half-open intervals [a, b).
; This field specifies the left (included) endpoint a.
script_after =
(4, uint)

; Timelock validity intervals are half-open intervals [a, b).
; This field specifies the right (excluded) endpoint b.
script_before =
(5, uint)

keyhash =
bytes .size 28
109 changes: 109 additions & 0 deletions CIP-0029/phase-1-monetary-scripts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
{ "$schema": "<https://json-schema.org/draft-07/schema>"
, "title": "Phase-1 Monetary Scripts"
, "oneOf":
[ { "$ref": "#/definitions/Script@keyHash" }
, { "$ref": "#/definitions/Script@after" }
, { "$ref": "#/definitions/Script@before" }
, { "$ref": "#/definitions/Script@any" }
, { "$ref": "#/definitions/Script@all" }
, { "$ref": "#/definitions/Script@atLeast" }
]
, "definitions":
{ "Script@keyHash":
{ "type": "object"
, "additionalProperties": false
, "required": [ "type", "keyHash" ]
, "properties":
{ "type":
{ "type": "string"
, "enum": [ "sig" ]
}
, "keyHash":
{ "type": "string"
, "encoding": "base16"
, "minLength": 56
, "maxLength": 56
}
}
}
, "Script@before":
{ "type": "object"
, "additionalProperties": false
, "required": [ "type", "slot" ]
, "properties":
{ "type":
{ "type": "string"
, "enum": [ "before" ]
}
, "slot":
{ "type": "integer"
, "minimum": 1
}
}
}
, "Script@after":
{ "type": "object"
, "additionalProperties": false
, "required": [ "type", "slot" ]
, "properties":
{ "type":
{ "type": "string"
, "enum": [ "after" ]
}
, "slot":
{ "type": "integer"
, "minimum": 1
}
}
}
, "Script@any":
{ "type": "object"
, "additionalProperties": false
, "required": [ "type", "scripts" ]
, "properties":
{ "type":
{ "type": "string"
, "enum": [ "any" ]
}
, "scripts":
{ "type": "array"
, "items": { "$ref": "#" }
}
}
}
, "Script@all":
{ "type": "object"
, "additionalProperties": false
, "required": [ "type", "scripts" ]
, "properties":
{ "type":
{ "type": "string"
, "enum": [ "all" ]
}
, "scripts":
{ "type": "array"
, "items": { "$ref": "#" }
}
}
}
, "Script@atLeast":
{ "type": "object"
, "additionalProperties": false
, "required": [ "type", "required", "scripts" ]
, "properties":
{ "type":
{ "type": "string"
, "enum": [ "atLeast" ]
}
, "required":
{ "type": "integer"
, "minimum": 0
}
, "scripts":
{ "type": "array"
, "items": { "$ref": "#" }
}
}
}
}
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The current process is described in details in [CIP1 - "CIP Process"](./CIP-0001
| 23 | [Fair Min Fees](./CIP-0023/CIP-0023.md) | Draft |
| 24 | [Non-Centralizing Rankings](./CIP-0024/CIP-0024.md) | Draft |
| 25 | [NFT Metadata Standard](./CIP-0025/CIP-0025.md) | Draft |
| 29 | [Phase-1 Monetary Scripts Serialization Formats](./CIP-0029/CIP-0029.md) | Draft |
| 1852 | [HD (Hierarchy for Deterministic) Wallets for Cardano](./CIP-1852/CIP-1852.md) | Draft |
| 1853 | [HD (Hierarchy for Deterministic) Stake Pool Cold Keys for Cardano](./CIP-1853/CIP-1853.md) | Draft |
| 1854 | [Multi-signatures HD Wallets](./CIP-1854/CIP-1854.md) | Draft |
Expand Down