diff options
Diffstat (limited to 'docs/utxo-commitment.md')
| -rw-r--r-- | docs/utxo-commitment.md | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/docs/utxo-commitment.md b/docs/utxo-commitment.md new file mode 100644 index 0000000..ab43deb --- /dev/null +++ b/docs/utxo-commitment.md | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | # Bitflash UTXO-set commitment | ||
| 2 | |||
| 3 | `scripts/verify-utxo-set.py` reconstructs a deterministic commitment to the | ||
| 4 | current UTXO set from local `blk*.dat` files. | ||
| 5 | |||
| 6 | This is intentionally not a consensus rule yet. It is an audit tool: independent | ||
| 7 | operators can run it against the same chain prefix and compare the resulting | ||
| 8 | root and canonical JSON hash. | ||
| 9 | |||
| 10 | ```bash | ||
| 11 | python3 scripts/verify-utxo-set.py --max-blocks 1000 --out utxo-report.json --json | ||
| 12 | ``` | ||
| 13 | |||
| 14 | Use `--max-blocks 0` or omit the option to scan every available block file: | ||
| 15 | |||
| 16 | ```bash | ||
| 17 | python3 scripts/verify-utxo-set.py --out utxo-report.json --json | ||
| 18 | ``` | ||
| 19 | |||
| 20 | ## What It Verifies | ||
| 21 | |||
| 22 | The verifier: | ||
| 23 | |||
| 24 | - parses Bitflash block files directly with the shared Python chain parser; | ||
| 25 | - streams `blk*.dat` records instead of loading full block files into memory; | ||
| 26 | - reconstructs the best chain rooted at the Bitflash genesis block; | ||
| 27 | - ignores side blocks that may also be present in `blk*.dat`; | ||
| 28 | - verifies every scanned block merkle root; | ||
| 29 | - applies spends and creates outputs in deterministic order; | ||
| 30 | - reports current UTXO count, current supply, mined coinbase total, fees, and | ||
| 31 | historical duplicate-output overwrites; | ||
| 32 | - computes a deterministic UTXO root. | ||
| 33 | |||
| 34 | ## Commitment Algorithm | ||
| 35 | |||
| 36 | The UTXO map is keyed by: | ||
| 37 | |||
| 38 | ```text | ||
| 39 | txid:vout | ||
| 40 | ``` | ||
| 41 | |||
| 42 | Keys are sorted lexicographically. Each leaf is: | ||
| 43 | |||
| 44 | ```text | ||
| 45 | SHA256("BTFUTXO1|" || outpoint || "|" || value_satoshis || "|" || | ||
| 46 | script_pub_key_hex || "|" || created_height || "|" || created_txid) | ||
| 47 | ``` | ||
| 48 | |||
| 49 | The tree is then reduced pairwise. If a level has an odd number of hashes, the | ||
| 50 | last hash is duplicated. Each parent is: | ||
| 51 | |||
| 52 | ```text | ||
| 53 | SHA256("BTFNODE1|" || left_hash || right_hash) | ||
| 54 | ``` | ||
| 55 | |||
| 56 | The final hash is the UTXO-set root. | ||
| 57 | |||
| 58 | ## Inclusion Proofs | ||
| 59 | |||
| 60 | After a root has been computed, `scripts/prove-utxo.py` can create a compact | ||
| 61 | inclusion proof for one unspent output: | ||
| 62 | |||
| 63 | ```bash | ||
| 64 | python3 scripts/prove-utxo.py TXID:VOUT --out utxo-proof.json --json | ||
| 65 | python3 scripts/verify-utxo-proof.py utxo-proof.json | ||
| 66 | ``` | ||
| 67 | |||
| 68 | The verifier does not need local block files. It recomputes the target leaf, | ||
| 69 | walks the sibling path, and compares the result with the expected root. See | ||
| 70 | [UTXO inclusion proofs](utxo-proofs.md). | ||
| 71 | |||
| 72 | ## Deterministic Output | ||
| 73 | |||
| 74 | `--json` and `--out` write canonical JSON with sorted keys, fixed separators, | ||
| 75 | ASCII escaping, and one trailing newline. It contains no local path and no | ||
| 76 | generation timestamp, so two auditors scanning the same chain prefix should | ||
| 77 | produce byte-identical reports. | ||
| 78 | |||
| 79 | ```bash | ||
| 80 | python3 scripts/verify-utxo-set.py --out utxo-report.json --json | ||
| 81 | sha256sum utxo-report.json | ||
| 82 | ``` | ||
| 83 | |||
| 84 | ## OpenTimestamps | ||
| 85 | |||
| 86 | The canonical JSON can be timestamped in Bitcoin without adding any dependency | ||
| 87 | to Bitflash consensus: | ||
| 88 | |||
| 89 | ```bash | ||
| 90 | ots stamp utxo-report.json | ||
| 91 | ots verify utxo-report.json.ots | ||
| 92 | ``` | ||
| 93 | |||
| 94 | ## Historical Duplicates | ||
| 95 | |||
| 96 | Bitflash inherited early Bitcoin behavior around duplicate transaction IDs. | ||
| 97 | The verifier reports duplicate-output overwrites as warnings and uses | ||
| 98 | last-write-wins semantics for the UTXO map, matching the legacy index model. | ||
| 99 | Those warnings are part of the report so auditors can see the historical debt | ||
| 100 | instead of relying on a polished summary. | ||
| 101 | |||
| 102 | For synthetic chains or future clean consensus ranges, auditors can make | ||
| 103 | duplicates a hard failure: | ||
| 104 | |||
| 105 | ```bash | ||
| 106 | python3 scripts/verify-utxo-set.py --strict-duplicates | ||
| 107 | ``` | ||
| 108 | |||
| 109 | The default remains compatible with the current historical chain because it has | ||
| 110 | known legacy duplicate-output overwrites. | ||
| 111 | |||
| 112 | ## Shared Parser | ||
| 113 | |||
| 114 | The audit scripts share `scripts/bitflash_chain.py` for block parsing, | ||
| 115 | main-chain selection, UTXO application, canonical JSON, and genesis | ||
| 116 | reconstruction. That keeps `verify-utxo-set.py`, `verify-fair-launch.py`, | ||
| 117 | `prove-utxo.py`, and the explorer on the same serialization rules. | ||
| 118 | |||
| 119 | ## Future Consensus Path | ||
| 120 | |||
| 121 | This tool is the low-risk first step toward consensus commitments. A future | ||
| 122 | hard-fork design can commit this root, or a Utreexo-style accumulator root, in | ||
| 123 | coinbase or block headers after a fixed activation height. Until then this | ||
| 124 | script provides reproducible supply and state commitments without changing what | ||
| 125 | nodes accept. | ||