upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Casarin <jb55@jb55.com>2022-05-05 10:45:27 -0700
committerfiatjaf <fiatjaf@gmail.com>2022-05-06 22:04:57 -0300
commitd7a4aad4a0039285f2bc4723c2898593dca0d6c4 (patch)
treea94332ce141580d2d27bb0aeeb81ed11b277fe22
parentad1eb96c2147d30f148480aac32aa98631f1d0b5 (diff)
Proof of Work
Thanks-to: Cameri and scsibug for the initial idea of using the id for PoW Thanks-to: David A. Harding for the difficulty commitment idea Signed-off-by: William Casarin <jb55@jb55.com>
-rw-r--r--13.md93
-rw-r--r--README.md1
2 files changed, 94 insertions, 0 deletions
diff --git a/13.md b/13.md
new file mode 100644
index 0000000..63e5169
--- /dev/null
+++ b/13.md
@@ -0,0 +1,93 @@
1NIP-13
2======
3
4Proof of Work
5-------------
6
7`draft` `optional` `author:jb55` `author:cameri`
8
9This NIP defines a way to generate and interpret Proof of Work for nostr notes. Proof of Work (PoW) is a way to add a proof of computational work to a note. This is a bearer proof which all relays and clients can universally validate with a small amount of code. This proof can be used as a means of spam deterrence.
10
11`difficulty` is defined to be the number of leading zero bits in the `NIP-01` id. For example, an id of `000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2d` has a difficulty of `36` with `36` leading 0 bits.
12
13Mining
14------
15
16To generate PoW for a `NIP-01` note, a `nonce` tag is used:
17
18```json
19{"content": "It's just me mining my own business", "tags": [["nonce", "1", "20"]]}
20```
21
22When mining, the second entry to the nonce tag is updated, and then the id is recalculated (see [NIP-01](./01.md)). If the id has the desired number of leading zero bits, the note has been mined. It is recommended to update the `created_at` as well during this process.
23
24The third entry to the nonce tag `SHOULD` contain the target difficulty. This allows clients to protect against situations where bulk spammers targeting a lower difficulty get lucky and match a higher difficulty. For example, if you require 40 bits to reply to your thread and see a committed target of 30, you can safely reject it even if the note has 40 bits difficulty. Without a committed target difficulty you could not reject it. Committing to a target difficulty is something all honest miners should be ok with, and clients `MAY` reject a note matching a target difficulty if it is missing a difficulty commitment.
25
26Example mined note
27------------------
28
29```json
30{
31 "id": "000006d8c378af1779d2feebc7603a125d99eca0ccf1085959b307f64e5dd358",
32 "pubkey": "a48380f4cfcc1ad5378294fcac36439770f9c878dd880ffa94bb74ea54a6f243",
33 "created_at": 1651794653,
34 "kind": 1,
35 "tags": [
36 [
37 "nonce",
38 "776797",
39 "20"
40 ]
41 ],
42 "content": "It's just me mining my own business",
43 "sig": "284622fc0a3f4f1303455d5175f7ba962a3300d136085b9566801bc2e0699de0c7e31e44c81fb40ad9049173742e904713c3594a1da0fc5d2382a25c11aba977"
44}
45```
46
47Validating
48----------
49
50Here is some reference C code for calculating the difficulty (aka number of leading zero bits) in a nostr note id:
51
52```c
53int zero_bits(unsigned char b)
54{
55 int n = 0;
56
57 if (b == 0)
58 return 8;
59
60 while (b >>= 1)
61 n++;
62
63 return 7-n;
64}
65
66/* find the number of leading zero bits in a hash */
67int count_leading_zero_bits(unsigned char *hash)
68{
69 int bits, total, i;
70 for (i = 0, total = 0; i < 32; i++) {
71 bits = zero_bits(hash[i]);
72 total += bits;
73 if (bits != 8)
74 break;
75 }
76 return total;
77}
78```
79
80Querying relays for PoW notes
81-----------------------------
82
83Since relays allow searching on prefixes, you can use this as a way to filter notes of a certain difficulty:
84
85```
86$ echo '["REQ", "subid", {"ids": ["000000000"]}]' | websocat wss://some-relay.com | jq -c '.[2]'
87{"id":"000000000121637feeb68a06c8fa7abd25774bdedfa9b6ef648386fb3b70c387", ...}
88```
89
90Delegated Proof of Work
91-----------------------
92
93Since the `NIP-01` note id does not commit to any signature, PoW can be outsourced to PoW providers, perhaps for a fee. This provides a way for clients to get their messages out to PoW restricted relays without having to do any work themselves, which is useful for energy constrained devices like on mobile
diff --git a/README.md b/README.md
index 3c4eb30..8f703e3 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
14- [NIP-10: Conventions for clients' use of `e` and `p` tags in text events.](10.md) 14- [NIP-10: Conventions for clients' use of `e` and `p` tags in text events.](10.md)
15- [NIP-11: Relay Information Document](11.md) 15- [NIP-11: Relay Information Document](11.md)
16- [NIP-12: Generic Tag Queries](12.md) 16- [NIP-12: Generic Tag Queries](12.md)
17- [NIP-13: Proof of Work](13.md)
17 18
18## Event Kinds 19## Event Kinds
19 20