From c55dee5755e1a8ce5332778edb6fc9f9344ee02b Mon Sep 17 00:00:00 2001 From: jeffthibault Date: Tue, 27 Dec 2022 20:15:53 -0500 Subject: [PATCH] add nip-13: proof of work --- nostr/pow.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 nostr/pow.py diff --git a/nostr/pow.py b/nostr/pow.py new file mode 100644 index 0000000..6566fd0 --- /dev/null +++ b/nostr/pow.py @@ -0,0 +1,43 @@ +import time +from .event import Event + +def zero_bits(b: int) -> int: + n = 0 + + if b == 0: + return 8 + + while b >> 1: + b = b >> 1 + n += 1 + + return 7 - n + +def count_leading_zero_bits(event_id: str) -> int: + total = 0 + for i in range(0, len(event_id) - 2, 2): + bits = zero_bits(int(event_id[i:i+2], 16)) + total += bits + + if bits != 8: + break + + return total + +def mine_event(content: str, difficulty: int, public_key: str, kind: int, tags: list=[]) -> Event: + all_tags = [["nonce", "1", str(difficulty)]] + all_tags.extend(tags) + + created_at = int(time.time()) + event_id = Event.compute_id(public_key, created_at, kind, all_tags, content) + num_leading_zero_bits = count_leading_zero_bits(event_id) + + attempts = 1 + while num_leading_zero_bits < difficulty: + attempts += 1 + all_tags[0][1] = str(attempts) + created_at = int(time.time()) + event_id = Event.compute_id(public_key, created_at, kind, all_tags, content) + num_leading_zero_bits = count_leading_zero_bits(event_id) + + return Event(public_key, content, created_at, kind, all_tags, event_id)