Auditabilidad de los partidos
Cada vez que se cierra un partido en ProdeCity, generamos un snapshot inmutable con las predicciones del grupo y un hash SHA-256 que lo identifica de forma única. Una vez creado, el snapshot no se modifica nunca.
El hash es un código de 64 caracteres que funciona como huella digital del contenido. Si una sola coma del contenido cambia, el hash cambia por completo.
Vista pública del partido
Cualquiera puede consultar la auditoría pública de un partido en
prodecity.com/auditoria/{uuid-del-partido}
. Vas a ver:
- Los datos del partido: equipos, fase, fecha del kickoff, momento exacto del cierre.
- El conteo total de predicciones y de comodines que se activaron al cierre del partido.
- El hash SHA-256 del snapshot.
La vista pública es un fingerprint del partido: sirve para confirmar que cuántas predicciones se cerraron y a qué hora, sin exponer datos personales.
Vista del grupo
Si pertenecés a un grupo, podés ver la auditoría del grupo para un
partido en
app.prodecity.com/auditoria/{uuid-del-partido}/{uuid-del-grupo}
. Iniciando sesión vas a ver:
- La lista completa de predicciones del grupo: nombre del usuario, marcador que predijo, si usó comodín, momento en que cargó la predicción.
- El hash SHA-256 propio del snapshot del grupo.
Es exactamente lo que se reveló al grupo en la app al cerrarse el partido. La auditoría del grupo es privada: solo los miembros pueden verla.
Para qué sirve
El hash te permite confirmar que el snapshot publicado coincide exactamente con el que se generó en el cierre del partido. Cuando un grupo tiene webhook configurado (Discord, Telegram o URL propia), el hash también se postea al canal en el momento del cierre — comparando ese hash con el que devuelve la auditoría, cualquiera puede verificar que la información del partido es la misma que se selló al cerrarse.
Cómo verificar el hash
El hash se calcula con SHA-256 sobre el payload del snapshot, normalizado de manera reproducible (keys ordenadas alfabéticamente de forma recursiva, listas conservan su orden). Cualquiera puede recalcularlo en cualquier lenguaje. Ejemplo en Python:
import json, hashlib, urllib.request
url = "https://api.prodecity.com/api/v1/public/audit/{uuid-del-partido}"
data = json.load(urllib.request.urlopen(url))
def normalize(v):
if isinstance(v, list):
return [normalize(x) for x in v]
if isinstance(v, dict):
return {k: normalize(v[k]) for k in sorted(v.keys())}
return v
canonical = json.dumps(
normalize(data["data"]["payload"]),
ensure_ascii=False,
separators=(",", ":"),
)
computed = hashlib.sha256(canonical.encode()).hexdigest()
assert computed == data["data"]["payload_hash"]