#!/usr/bin/env python3 """BAGIMSIZ DOGRULAMA BETIGI -- otonomsinyal kanit zinciri. Bu dosyayi ve kanit_zincir.jsonl'i indirip calistirin: python3 dogrula_kanit.py kanit_zincir.jsonl Ne yapar: 1. Zincirdeki her kaydin hash'ini YENIDEN hesaplar. Tek bir hanesi degistirilmis kayit varsa o satirda durur ve hangisi oldugunu yazar. 2. Muhur dosyalari verilmisse, muhurdeki bas_hash'in zincirle uyusup uyusmadigini soyler. Baska hicbir sey yapmaz: ag baglantisi kurmaz, kayit tutmaz. Bu betigin dogru calistigini gormek icin zincirdeki bir rakami elle degistirip tekrar calistirin -- gecmesi imkansizdir. Bitcoin zaman damgasini ayrica dogrulamak icin (opsiyonel): pip install opentimestamps-client ots verify 2026-08-10.txt.ots -f 2026-08-10.txt """ import hashlib import json import os import sys BASLANGIC_HASH = "0" * 64 def kanonik(kayit): return json.dumps(kayit, sort_keys=True, ensure_ascii=False, separators=(",", ":")) def satir_hash(onceki, kayit): return hashlib.sha256( (onceki + kanonik(kayit)).encode("utf-8")).hexdigest() def oku(yol): with open(yol, encoding="utf-8") as f: return [json.loads(s) for s in f if s.strip()] def main(): if len(sys.argv) < 2: print(__doc__) return 2 zincir = oku(sys.argv[1]) if not zincir: print("zincir bos") return 1 onceki = BASLANGIC_HASH for i, d in enumerate(zincir): if d.get("onceki_hash") != onceki: print(f"KOPUK: {i}. kayitta zincir baglantisi tutmuyor") return 1 beklenen = satir_hash(onceki, d["kayit"]) if d.get("hash") != beklenen: print(f"DEGISTIRILMIS: {i}. kayit " f"(id={d['kayit'].get('id')})") print(f" dosyadaki : {d.get('hash')}") print(f" hesaplanan: {beklenen}") return 1 onceki = d["hash"] print(f"ZINCIR SAGLAM -- {len(zincir)} kayit") print(f"bas hash: {onceki}") # Muhur dosyalari ayni klasordeyse bas_hash'i karsilastir. klasor = os.path.dirname(os.path.abspath(sys.argv[1])) muhurler = sorted(a for a in os.listdir(klasor) if a.endswith(".txt") and a[:4].isdigit()) for ad in muhurler: with open(os.path.join(klasor, ad), encoding="utf-8") as f: metin = f.read() h = "" for satir in metin.splitlines(): if satir.startswith("bas_hash:"): h = satir.split(":", 1)[1].strip() varmi = any(d["hash"] == h for d in zincir) print(f" muhur {ad}: {'zincirde VAR' if varmi else 'ZINCIRDE YOK'}") return 0 if __name__ == "__main__": sys.exit(main())