Note A NIP PR has been open here, the conversation should move to the PR
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).
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), but to an impartial, decentralized system (like the bitcoin blockchain).
A user can register its public key in a 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 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/2n 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.
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/22 + 2 * 1/24 + 4 * 1/25), whereas public key 1acf... (purple rectangles) has purchased 3 rating options with a mass of 0.1875 (3 * 1/24). The total mass of the tree will always be 1 (eg: 0.8125 + 0.1875), because everybody knows that 1+2+4+⋯+2𝑛 = 2𝑛+1 - 1.
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), 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/25). 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/21, more intense).
Ratings in nostr can be achieved by publishing a particular event (see this NIP-32 PR 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) and have these additional tags representing the rating mass:
{
"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 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 keyin theleafmust be the same as thepublic keyof the event creator.
Note Rating events without a
rating massor which have a very long path (are almost free) should not be taken into consideration
-
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 massassigned to each rating event- this can be part of the relay, or a standalone service
-
integrate with social media clients, market clients, etc

Other suggested solutions for ratings (and their limitations):
Use proof-of-work
nostrnetwork (relays) would have to do difficulty adjustment as devices get more powerfulImport reputation
Importing reputation from a centralized system (like Twitter) has some problems:
nostr.Dedicated centralized reputation servers
Micropayments
A user can make a small lightning payment to show its appreciation. Unfortunately the system can be gamed and the reciever can just pay itself with almost no cost (except routing fees)