nips/320.md
2023-06-13 17:41:33 +03:00

80 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nostr Rating Mass
## Problem
Ratings give the reputation for a **person**, **service** or **product**. They are important for creating an open and free-market.
It helps participants make decisions based on what their peers previously experienced with that person, services or product.
Having a rating system in an open and decentralized system (like `nostr`) is hard because anyone can join and give ratings.
Thus bots will be created to overtake the honest human's votes.
Some solutions have been proposed for this problem, but none of them is satisfactory (see [first comment](https://gist.github.com/motorina0/874912282d2419be4eaf89de8d0c4464?permalink_comment_id=4597165#gistcomment-4597165)).
## Suggested Solution
In order to avoid spam, each rating must have associated with it the proof that a tiny fee has been paid. The fee should not be paid to a centralized service that can cheat (see [first comment](https://gist.github.com/motorina0/874912282d2419be4eaf89de8d0c4464?permalink_comment_id=4597165#gistcomment-4597165)), but to an impartial, decentralized system (like the bitcoin blockchain).
### Rating Mass
A user can register its `public key` in a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) and the root of the tree is then persisted (by a specialized service) on the bitcoin blockchain using the `OP_RETURN` operator (thus paying a fee). Similarly with what [open-timestamps](https://opentimestamps.org/) does.
If the `public key` is registered as the root of the tree then the `rating mass` is `1`, if it is registered on the second level then the `rating mass` is `1/2` (there can be two leaves). The lower one goes in the tree, the more leaves it can register, but also the less each leaf is worth (`rating mass` is `1/2`<sup>`n`</sup> where `n` is the depth - starting at `0`).
The properties of the tree are:
- Each leaf is of the form: `[<tree-level>, <leaf-index>, <public-key>]`.
- Leaves can exist at any level. The closer to the tree root a leaf is, the more valuable it is.
<hr>
![rating-points-tree drawio(4)](https://user-images.githubusercontent.com/2951406/245187057-bb6ba330-e766-4c59-9519-1f2b09b4501c.png)
Highlighted in the image is the path to leaf `[4, 0, a728...]` which is composed of `4` elements: `[hash([4,1,a728...]), H2, H7, H9]`. This path has a `rating mass` of `1/4`.
For the above example (image), the public key `a728...` (yellow rectangles) has purchased `9 rating options` with a total mass of `0.8125` (`2 * 1/2`<sup>`2`</sup> + `2 * 1/2`<sup>`4`</sup> + `4 * 1/2`<sup>`5`</sup>), whereas public key `1acf...` (purple rectangles) has purchased `3 rating options` with a mass of `0.1875` (`3 * 1/2`<sup>`4`</sup>). The total mass of the tree will always be `1` (eg: `0.8125 + 0.1875`), because everybody knows that `1+2+4+⋯+2`<sup>`𝑛`</sup> = `2`<sup>`𝑛+1`</sup>` - 1`.
### Rating Mass is not the Rating Value
The `rating value` can be an integer between `1 and 5`, or it can be a float between `0 and 1` (see this [NIP-32 PR](https://github.com/nostr-protocol/nips/pull/532)), or any other rating system.
The `rating mass` represents the importance or intensity that a user gives to a particular rating. It also guarantees that the rating is not spam.
For example I might dislike a film and give it a `rating value` of `2 stars` and a `rating mass` of `0.03125` (consume a leaf on level `5` of the tree: `1/2`<sup>`5`</sup>). Or I might dislike that the Uber driver just dropped me off in a bad neighborhood and give it a `rating value` of `2 stars`, but a `rating mass` of `0.5` (consume a leaf on level `1` of the tree: `1/2`<sup>`1`</sup>, more intense).
### Using Rating Mass in Nostr
Ratings in `nostr` can be achieved by publishing a particular event (see this [NIP-32 PR](https://github.com/nostr-protocol/nips/pull/532) to get an idea of how the event could look like) and attaching a `rating mass` to the event.
This rating event should be a [Parameterized Replaceable Events (NIP-33)](https://github.com/nostr-protocol/nips/blob/master/33.md) and have these additional tags representing the `rating mass`:
```json
{
"kind": 30030,
"pubkey": <public key of the event creator>,
"tags": [
["tx-id", <id of the transaction where the `OP_RETURN` was included>],
["output-index", <index of the `OP_RETURN` output>],
["leaf", <tree-level>, <leaf-index>, <public-key of the event creator>],
["leaf-path", <hash1>, <hash2>, ...],
["d", <hash(tx-id, output-index, <tree-level>, <leaf-index>, <public-key>, <hash1>, <hash2>, ...)>],
...
],
"content": "...",
...
}
```
The `d` tag is the most important one because it aggregates all the other values and because it is the one used to replace the [NIP-33](https://github.com/nostr-protocol/nips/blob/master/33.md) event. This means that the same `leaf` **cannot be used in two different rating events**. Trying to reuse the `leaf` will simply replace the previous rating event. On the other hand, if I have "consumed" one of my ratings for liking a song that I later discover it was plagiarised then I can take that rating back and reuse it one something else.
> **Note**
> The `public key` in the `leaf` must be the same as the `public key` of the event creator.
> **Note**
> Rating events without a `rating mass` or which have a very long path (are almost free) should not be taken into consideration
### Next Steps
- detailed doc for the tree structures
- create a services that allows users to buy `rating mass`
- the user selects the levels it wants to register it public key at
- the services computes the cost
- the user pays the invoice and receives the full tree
- create a service that computes ratings based on the `rating mass` assigned to each rating event
- this can be part of the relay, or a standalone service
- integrate with social media clients, market clients, etc