-
Notifications
You must be signed in to change notification settings - Fork 578
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
NIP-13: Proof of Work #3
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
NIP-13 | ||
====== | ||
|
||
Proof of Work | ||
------------- | ||
|
||
`draft` `optional` `author:jb55` `author:cameri` | ||
|
||
This 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. | ||
|
||
`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. | ||
|
||
Mining | ||
------ | ||
|
||
To generate PoW for a `NIP-01` note, a `nonce` tag is used: | ||
|
||
```json | ||
{"content": "It's just me mining my own business", "tags": [["nonce", "1", "20"]]} | ||
``` | ||
|
||
When 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. | ||
|
||
The 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. | ||
|
||
Example mined note | ||
------------------ | ||
|
||
```json | ||
{ | ||
"id": "000006d8c378af1779d2feebc7603a125d99eca0ccf1085959b307f64e5dd358", | ||
"pubkey": "a48380f4cfcc1ad5378294fcac36439770f9c878dd880ffa94bb74ea54a6f243", | ||
"created_at": 1651794653, | ||
"kind": 1, | ||
"tags": [ | ||
[ | ||
"nonce", | ||
"776797", | ||
"20" | ||
] | ||
], | ||
"content": "It's just me mining my own business", | ||
"sig": "284622fc0a3f4f1303455d5175f7ba962a3300d136085b9566801bc2e0699de0c7e31e44c81fb40ad9049173742e904713c3594a1da0fc5d2382a25c11aba977" | ||
} | ||
``` | ||
|
||
Validating | ||
---------- | ||
|
||
Here is some reference C code for calculating the difficulty (aka number of leading zero bits) in a nostr note id: | ||
|
||
```c | ||
int zero_bits(unsigned char b) | ||
{ | ||
int n = 0; | ||
|
||
if (b == 0) | ||
return 8; | ||
|
||
while (b >>= 1) | ||
n++; | ||
|
||
return 7-n; | ||
} | ||
|
||
/* find the number of leading zero bits in a hash */ | ||
int count_leading_zero_bits(unsigned char *hash) | ||
{ | ||
int bits, total, i; | ||
for (i = 0, total = 0; i < 32; i++) { | ||
bits = zero_bits(hash[i]); | ||
total += bits; | ||
if (bits != 8) | ||
break; | ||
} | ||
return total; | ||
} | ||
``` | ||
|
||
Querying relays for PoW notes | ||
----------------------------- | ||
|
||
Since relays allow searching on prefixes, you can use this as a way to filter notes of a certain difficulty: | ||
|
||
``` | ||
$ echo '["REQ", "subid", {"ids": ["000000000"]}]' | websocat wss://some-relay.com | jq -c '.[2]' | ||
{"id":"000000000121637feeb68a06c8fa7abd25774bdedfa9b6ef648386fb3b70c387", ...} | ||
``` | ||
|
||
Delegated Proof of Work | ||
----------------------- | ||
|
||
Since 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 | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section here was inspiration for https://oak-node.net/pow :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is cool 👍 amazing work