"""Produce a hashed variant of eddycoin_old_keys.py (same API, same behaviour) that contains no plain addresses: ADDRESSES / SUPERSEDED become set-like objects that compare SHA-256(address) - the public exes then hold only hashes.""" import re, sys, hashlib, ast src = open(sys.argv[1], encoding="utf-8").read() def hset(name): m = re.search(r"^%s = frozenset\((\[.*?\])\)\s*$" % name, src, re.M); assert m, name addrs = ast.literal_eval(m.group(1)); assert all(re.fullmatch(r"eddy1[0-9a-f]{40}", a) for a in addrs) hs = sorted(hashlib.sha256(a.encode()).hexdigest() for a in addrs) return m.group(0), "%s = _HashedSet(%r) # SHA-256 of the %d addresses (no plain addresses in the program)" % (name, hs, len(hs)), addrs out = src helper = ('class _HashedSet(object):\n' ' """set of addresses stored only as SHA-256 hex digests; "addr in S" hashes the given address"""\n' ' def __init__(self, hashes): self._h = frozenset(hashes)\n' ' def __contains__(self, a):\n' ' try: return hashlib.sha256(str(a).encode()).hexdigest() in self._h\n' ' except Exception: return False\n' ' def __len__(self): return len(self._h)\n' ' def __bool__(self): return bool(self._h)\n') assert "import hashlib\n" in out out = out.replace("import hashlib\n", "import hashlib\n" + helper, 1) allA = [] for n in ("ADDRESSES", "SUPERSEDED"): old, new, a = hset(n); out = out.replace(old, new, 1); allA += a assert not re.search(r"eddy1[0-9a-f]{40}", out) open(sys.argv[2], "w", encoding="utf-8").write(out) # behaviour check: original vs hashed module import types def load(code): m = types.ModuleType("m"); exec(compile(code, "m", "exec"), m.__dict__); return m o, h = load(src), load(out) probe = allA + [a.upper() for a in allA[:5]] + [" " + allA[0] + " "] + ["eddy1" + "0" * 40, "", "x"] fns = [f for f in ("refusal", "is_old", "is_superseded", "is_mainnet") if hasattr(o, f)] for f in fns: for p in probe: assert getattr(o, f)(p) == getattr(h, f)(p), (f, p) print("hashed module OK: %d addresses, functions %s identical on %d probes" % (len(set(allA)), fns, len(probe)))