mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-11-13 23:39:08 -05:00
80 lines
5.7 KiB
Markdown
80 lines
5.7 KiB
Markdown
# 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 |