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

NUT-10: Spending conditions #50

Merged
merged 5 commits into from
Oct 13, 2023
Merged
Changes from 2 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
74 changes: 74 additions & 0 deletions 10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
NUT-10: Spending conditions
==========================

`optional` `author: calle`

---

An ordinary ecash token is a set of `Proofs` each with a random string `secret`. To spend such a token in a [split][06] or a [melt][05] operation, wallets include `proofs` in their request each with a unique `secret`. To autorize a transaction, the mint requires that the `secret` has not been seen before. This is the most fundamental spending condition in Cashu, which ensures that a token can't be double-spent.

In this NUT, we define a well-known format of `secret` that can be used to express more complex spending conditions. These conditions need to be met before the mint authorizes a transaction. Note that the specific type of spending condition is not part of this document but will be explained in other documents. Here, we describe the structure of `secret` which is expressed as a JSON `Secret` with a specific format.

Spending conditions are enfored by the mint which means that, upon encountering a `Proof` where `Proof.secret` can be parsed into the well-known format, the mint can require additional conditions to be met.

## Basic components
An ecash transaction, i.e., a [split][06] or a [melt][05] operation, with a spending condition consists of the following components:

- Inputs referring to the `Proofs` being spent
- `Secret` containing the rules for unlocking a `Proof`
- Signatures or additional witness data satisfying the unlock conditions
- Outputs referring to the `BlindMessages` with new unlock conditions to which the `Proofs` are spent to

Spending conditions are defined for each individual `Proof` and not on a transaction level that can consist of multiple `Proofs`. Similarly, spending conditions must be satisfied by providing signatures or additional witness data for each `Proof` separately. For a transaction to be valid, all `Proofs` in that transaction must be unlocked successfully.

New `Secret`s of the outputs to which the inputs are spent to are provided as `BlindMessages` which means that they are blind-signed and not visible to the mint until they are actually spent.

## Well-known Secret

Spending conditions are expressed in a well-known secret format that is revealed to the mint when spending (unlocking) a token, not when the token is minted (locked). The mint parses each `Proof`'s `secret`. If it can deserialize it into the following format, and if all `Proofs` have the same `kind`, it executes additional spending conditions that are further specified below.

The well-known `Secret` stored in `Proof.secret` is a JSON of the format:

```json
[
kind <str>,
{
"nonce": <str>,
"data": <str>,
"tags": [[ "key", "value1", "value2", ...], ... ], // (optional)
}
]
```

- `kind` is the kind of the spending condition
- `nonce` is a unique random string
- `data` expresses the spending condition specific to each kind
- `tags` hold additional data committed to and can be used for feature extensions

## Examples

Example use cases of this secret format are

- [NUT-11][11]: Pay-to-Public-Key (P2PK)

[00]: 00.md
[01]: 01.md
[02]: 02.md
[03]: 03.md
[04]: 04.md
[05]: 05.md
[06]: 06.md
[07]: 07.md
[08]: 08.md
[09]: 09.md
[10]: 10.md
[11]: 11.md
[12]: 12.md
[13]: 13.md
[14]: 14.md
[15]: 15.md
[16]: 16.md
[17]: 17.md
[18]: 18.md
[19]: 19.md
[20]: 20.md