diff options
| author | fiatjaf_ <fiatjaf@gmail.com> | 2023-04-24 17:02:11 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-24 17:02:11 -0300 |
| commit | 8168f546c3dc3b043395c2b0f27b94f5744bccd9 (patch) | |
| tree | bdfa38c2787fb0f49695c8c8457dbe756bd74cf2 | |
| parent | 5d0cbcbebfde5b3a32bf8c6fda12cfde40c1bb65 (diff) | |
| parent | 61475db6f43068c535b275ef48e0faecf461ac76 (diff) | |
Merge pull request #473 from arkin0x/patch-1
| -rw-r--r-- | 13.md | 74 |
1 files changed, 52 insertions, 22 deletions
| @@ -10,13 +10,15 @@ This NIP defines a way to generate and interpret Proof of Work for nostr notes. | |||
| 10 | 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. | 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 | 12 | ||
| 13 | `002f...` is `0000 0000 0010 1111...` in binary, which has 10 leading zeroes. Do not forget to count leading zeroes for hex digits <= `7`. | ||
| 14 | |||
| 13 | Mining | 15 | Mining |
| 14 | ------ | 16 | ------ |
| 15 | 17 | ||
| 16 | To generate PoW for a `NIP-01` note, a `nonce` tag is used: | 18 | To generate PoW for a `NIP-01` note, a `nonce` tag is used: |
| 17 | 19 | ||
| 18 | ```json | 20 | ```json |
| 19 | {"content": "It's just me mining my own business", "tags": [["nonce", "1", "20"]]} | 21 | {"content": "It's just me mining my own business", "tags": [["nonce", "1", "21"]]} |
| 20 | ``` | 22 | ``` |
| 21 | 23 | ||
| 22 | 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. | 24 | 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. |
| @@ -36,7 +38,7 @@ Example mined note | |||
| 36 | [ | 38 | [ |
| 37 | "nonce", | 39 | "nonce", |
| 38 | "776797", | 40 | "776797", |
| 39 | "20" | 41 | "21" |
| 40 | ] | 42 | ] |
| 41 | ], | 43 | ], |
| 42 | "content": "It's just me mining my own business", | 44 | "content": "It's just me mining my own business", |
| @@ -47,33 +49,61 @@ Example mined note | |||
| 47 | Validating | 49 | Validating |
| 48 | ---------- | 50 | ---------- |
| 49 | 51 | ||
| 50 | Here is some reference C code for calculating the difficulty (aka number of leading zero bits) in a nostr note id: | 52 | Here is some reference C code for calculating the difficulty (aka number of leading zero bits) in a nostr event id: |
| 51 | 53 | ||
| 52 | ```c | 54 | ```c |
| 53 | int zero_bits(unsigned char b) | 55 | #include <stdio.h> |
| 54 | { | 56 | #include <stdlib.h> |
| 55 | int n = 0; | 57 | #include <string.h> |
| 58 | |||
| 59 | int countLeadingZeroes(const char *hex) { | ||
| 60 | int count = 0; | ||
| 61 | |||
| 62 | for (int i = 0; i < strlen(hex); i++) { | ||
| 63 | int nibble = (int)strtol((char[]){hex[i], '\0'}, NULL, 16); | ||
| 64 | if (nibble == 0) { | ||
| 65 | count += 4; | ||
| 66 | } else { | ||
| 67 | count += __builtin_clz(nibble) - 28; | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | } | ||
| 56 | 71 | ||
| 57 | if (b == 0) | 72 | return count; |
| 58 | return 8; | 73 | } |
| 74 | |||
| 75 | int main(int argc, char *argv[]) { | ||
| 76 | if (argc != 2) { | ||
| 77 | fprintf(stderr, "Usage: %s <hex_string>\n", argv[0]); | ||
| 78 | return 1; | ||
| 79 | } | ||
| 59 | 80 | ||
| 60 | while (b >>= 1) | 81 | const char *hex_string = argv[1]; |
| 61 | n++; | 82 | int result = countLeadingZeroes(hex_string); |
| 83 | printf("Leading zeroes in hex string %s: %d\n", hex_string, result); | ||
| 62 | 84 | ||
| 63 | return 7-n; | 85 | return 0; |
| 64 | } | 86 | } |
| 87 | ``` | ||
| 65 | 88 | ||
| 66 | /* find the number of leading zero bits in a hash */ | 89 | Here is some JavaScript code for doing the same thing: |
| 67 | int count_leading_zero_bits(unsigned char *hash) | 90 | |
| 68 | { | 91 | ```javascript |
| 69 | int bits, total, i; | 92 | // hex should be a hexadecimal string (with no 0x prefix) |
| 70 | for (i = 0, total = 0; i < 32; i++) { | 93 | function countLeadingZeroes(hex) { |
| 71 | bits = zero_bits(hash[i]); | 94 | let count = 0; |
| 72 | total += bits; | 95 | |
| 73 | if (bits != 8) | 96 | for (let i = 0; i < hex.length; i++) { |
| 74 | break; | 97 | const nibble = parseInt(hex[i], 16); |
| 75 | } | 98 | if (nibble === 0) { |
| 76 | return total; | 99 | count += 4; |
| 100 | } else { | ||
| 101 | count += Math.clz32(nibble) - 28; | ||
| 102 | break; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | return count; | ||
| 77 | } | 107 | } |
| 78 | ``` | 108 | ``` |
| 79 | 109 | ||