From 1839347459759fb3b23cc747ec4368b724fee008 Mon Sep 17 00:00:00 2001 From: Nsable-sh Date: Tue, 11 Aug 2026 14:13:26 -0300 Subject: tools: harden chain audit scripts --- scripts/verify-fair-launch.py | 346 ++++-------------------------------------- 1 file changed, 30 insertions(+), 316 deletions(-) (limited to 'scripts/verify-fair-launch.py') diff --git a/scripts/verify-fair-launch.py b/scripts/verify-fair-launch.py index ce396fb..c33c8be 100644 --- a/scripts/verify-fair-launch.py +++ b/scripts/verify-fair-launch.py @@ -1,299 +1,12 @@ #!/usr/bin/env python3 -"""Produce a deterministic Bitflash fair-launch audit report. - -This verifier is intentionally self-contained. It parses Bitflash block files -directly, without Berkeley DB, without the node binary, and without network -access. The canonical JSON output is stable for the same inputs and can be -timestamped later with OpenTimestamps or any other external notary. -""" +"""Produce a deterministic Bitflash fair-launch audit report.""" import argparse -import datetime as _dt import hashlib -import json -import os -import struct import sys from pathlib import Path - -MAGIC = bytes([0xBF, 0x20, 0x5C, 0xFD]) -COIN = 100_000_000 -GENESIS_HASH = "5bd7cb255d814e48cebcdfb72da4dc87b34bd774227f8ceb546c5640f4bdc169" -GENESIS_MERKLE = "1a45b4482532abb29b10e234d3f13132230525a339ecea91658ffa675a5b1325" -GENESIS_TIME = 1_753_315_200 -GENESIS_BITS = 0x1F0FFFFF -GENESIS_NONCE = 3141 -GENESIS_TEXT = "Bitflash 24/Jul/2026 Fair launch: one CPU one vote, no premine" - - -class ParseError(Exception): - pass - - -class Reader: - def __init__(self, data): - self.data = data - self.pos = 0 - - def take(self, n): - if self.pos + n > len(self.data): - raise ParseError("unexpected end of data") - out = self.data[self.pos:self.pos + n] - self.pos += n - return out - - def u8(self): - return self.take(1)[0] - - def u32(self): - return struct.unpack(" 1: - nxt = [] - for i in range(0, len(layer), 2): - left = layer[i] - right = layer[i + 1] if i + 1 < len(layer) else left - nxt.append(sha256d(left + right)) - layer = nxt - return layer[0][::-1].hex() - - -def parse_block(payload, file_name="", offset=0): - r = Reader(payload) - header = r.take(80) - version, = struct.unpack(" len(data): - break - size = struct.unpack(" len(data): - break - blocks.append(parse_block(data[start:end], path.name, start)) - if limit and len(blocks) >= limit: - return blocks - pos = end - return blocks - - -def genesis_transaction(): - script_sig = ( - bytes.fromhex("04ffff001d") - + b"\x01\x04" - + bytes([len(GENESIS_TEXT)]) - + GENESIS_TEXT.encode("ascii") - ) - pubkey_num = bytes.fromhex( - "5f1df16b2b704c8a578d0bbaf74d385cde12c11ee50455f3c438ef4c3fbcf649" - "b6de611feae06279a60939e028a8d65c10b73071a6f16719274855feb0fd8a6704" - ) - # The genesis source uses CScript << CBigNum("0x..."), and CBigNum::getvch() - # returns the minimal little-endian script number representation. - script_pub_key = bytes([65]) + pubkey_num[::-1] + b"\xac" - tx = { - "version": 1, - "vin": [{ - "prevout_hash": "0" * 64, - "prevout_n": 0xFFFFFFFF, - "script_sig_hex": script_sig.hex(), - "sequence": 0xFFFFFFFF, - }], - "vout": [{ - "value_satoshis": 50 * COIN, - "value_btf": format_money(50 * COIN), - "script_pub_key_hex": script_pub_key.hex(), - }], - "lock_time": 0, - } - tx["txid"] = hash_hex(ser_tx(tx)) - return tx - - -def reconstructed_genesis(): - tx = genesis_transaction() - header = ( - struct.pack("