Guía paso a paso del curso
Distingue la prueba del laboratorio de la evidencia del despliegue. Los ejercicios locales de ECVRF, VDF y lotería se ejecutan sin pagar. En la vitrina de la lotería, identifica el entorno y examina la evidencia del sorteo. UNI usa una cadena simulada. Una transacción de Base debe comprobarse en Base. La entrada documentada en LIVE es una plaza gratuita por trabajo mediante
enterFromWork; los boletos de pago están desactivados.
Audiencia: desarrolladores que necesitan aleatoriedad que el propio jugador de lotería pueda verificar — antes de cablear
lottery/en Base. Idiomas:COURSE_LANG=en|ru|es· cadenas de UI eni18n/· esta guía en español. English: step-by-step.md · Русский: step-by-step.ru.md
Por qué este curso
La mayoría de las loterías y sorteos «aleatorios» confían en un operador que puede volver a tirar en silencio un resultado desfavorable. Este curso muestra la criptografía que elimina esa confianza: un sorteo caótico verificable, una función de retardo verificable (VDF) que demuestra el trabajo transcurrido, una prueba ECVRF que verificas sin conexión a partir de 80 bytes, y un time-lock RSW que oculta un valor hasta que un trabajo demostrable lo abre. Después construyes una lotería sesgada, la rompes y la arreglas con un sorteo que el operador no puede iterar — exactamente el patrón que consumen los contratos AIMarket lottery/ en Base.
Cada lab habla con un oráculo real de AIMarket — Platon, Chronos, Sortes, Aestus — ejecutándose en local, no con un mock. Cada uno imprime un bloque trace para que el artefacto verificable (prueba, beta, puzzle, vector VDF) sea algo que puedas inspeccionar, no aceptar a ciegas.
Índice
- Elige tu track
- Instalación (10 min)
- M1 — Chaos VRF con Platon
- M2 — Tiempo VDF con Chronos
- M3 — ECVRF y Sortes
- M4 — Time-lock RSW con Aestus
- M5 — Commit–reveal y ataques de sesgo
- M6 — Verificación on-chain
- Leer la traza (en cada lab)
- Ejercicios y certificado
- Puente: del curso a la lotería en Base
- Lista de autocomprobación
- Problemas frecuentes
Elige tu track
| Track | Módulos | Tiempo | Oráculos |
|---|---|---|---|
| Básico | M1 → M2 → M3 → M4 | ~2 h | Platon, Chronos, Sortes, Aestus (en local) |
| Economía | Básico + M5 | +30 min | Sortes (lotería justa vs sesgada) |
| Avanzado | Economía + M6 | +30 min | Chronos + Sortes → vector para la testnet de Base |
Tras cada lab revisa el bloque trace — es su registro de auditoría.
Instalación (10 min)
Paso 1 — Clonar e instalar
Los comandos exactos de inicio rápido (fíjate en el extra [oracles,dev] — oracles trae Platon/Chronos/Sortes/Aestus, dev trae pytest):
git clone https://github.com/alexar76/aimarket-courses.git
cd aimarket-courses/verifiable-randomness-course
pip install -e ".[oracles,dev]"
Desde el monorepo aicom (recomendado para colaboradores): los paquetes de oráculos se resuelven automáticamente por rutas hermanas en oracles/ — courselib/oracle_paths.py sube hasta la raíz del monorepo y añade oracles/oracles/{chronos,sortes,aestus} y oracles/oracles/platon/backend a sys.path. No necesitas instalar nada más allá de numpy para Platon.
cd courses/verifiable-randomness-course
pip install -e ".[oracles,dev]"
Paso 2 — Verificar tests
pytest -q
Esperado: todos los tests en verde (paridad i18n en/ru/es, helpers de aleatoriedad, comprobaciones de ejercicios).
Paso 3 — Elige idioma (opcional)
Las cadenas de UI (títulos, etiquetas prueba/verificación/traza, nombres de billetes) salen de i18n/{en,ru,es,fr,zh}.json. Cambia con COURSE_LANG:
export COURSE_LANG=es # o ru, por defecto en
python labs/lab01_platon_chaos.py
Paso 4 — Alternativa Colab
- Abre el sitio del curso → Open in Colab en cualquier lab.
- Ejecuta la celda de setup (clone +
pip install -e ".[oracles,dev]"). - Si quieres una ejecución localizada, pon
os.environ["COURSE_LANG"] = "es"en la celda de setup. - Ejecuta la celda del lab.
M1 — Chaos VRF con Platon
Concepto: aleatoriedad insesgable desde un oráculo caótico verificable — chaos-state + client seed + entropía del SO, ligados por una firma Ed25519.
Lab: labs/lab01_platon_chaos.py · ~15 min · requiere numpy + Platon
Pasos
- Lee el docstring al inicio de
labs/lab01_platon_chaos.py(sector: lotería, gaming). python labs/lab01_platon_chaos.py- Observa la salida: el esquema en
prueba, los primeros bytes del sorteo y el resultado deverificación. courselib/randomness.py→chaos_draw(): unSignertemporal, unstatecaótico,draw_randomness(...)y luegoverify_randomness(...).
Salida esperada
proof: scheme=platon-chaos-vrf/v1, sorteo firmado de 32 bytes,verify: True- bloque
tracecon un eventochaos_draw(verified=True, bytes=32)
Autocomprobación
- [ ] Explicas por qué un client seed + firma hacen insesgable el sorteo
- [ ] Ves los 32 bytes y
verify: Truecontra la clave pública
M2 — Tiempo VDF con Chronos
Concepto: un VDF de Wesolowski demuestra trabajo secuencial transcurrido sobre un grupo de orden desconocido RSA-2048 — prueba de trabajo transcurrido, no confianza en el reloj del sistema.
Lab: labs/lab02_chronos_vdf.py · ~20 min · requiere M1
Pasos
python labs/lab02_chronos_vdf.py- Lee la línea
prueba: la prueba de Wesolowskipiy el primol;verify: True. - Fíjate en la demo de manipulación: el lab llama a
vdf.verify(g, y+1, …)sobre una salida corrupta — imprimeFalse. courselib/randomness.py→vdf_eval():hash_to_group→evaluate→prove→verify. Usadifficulty=700(~700 cuadrados) para que corra en segundos.
Salida esperada
proof: pi=…… l=<primo>,verify: True,verificación de VDF manipulado: Falsetracecon eventosvdf_evalytamper_check
Autocomprobación
- [ ] Enuncias qué demuestra un VDF (trabajo secuencial) y qué no (tiempo real)
- [ ] Viste cómo la verificación rechaza una salida manipulada
M3 — ECVRF y Sortes
Concepto: una prueba ECVRF según RFC 9381. Para una pareja fija (clave pública, alpha) existe exactamente una beta válida — el operador no puede iterar buscando una salida favorable. La prueba mide 80 bytes y se verifica sin conexión, sin volver a llamar al oráculo.
Lab: labs/lab03_sortes_ecvrf.py · ~20 min · requiere M1
Pasos
python labs/lab03_sortes_ecvrf.py- Confirma que la prueba mide exactamente 80 bytes (
80 bytes = <hex>…). - Observa
beta(la salida aleatoria verificable) yverify: True. courselib/randomness.py→ecvrf_draw():sk_to_pk→prove(sk, alpha)→verify(pk, alpha, pi).
Salida esperada
proof: 80 bytes = <hex>…,result: beta=<hex>…,verify: Truetracecon un eventoecvrf(proof_len=80, verified=True)
Autocomprobación
- [ ] Explicas «una beta por (pk, alpha)» y por qué bloquea la iteración
- [ ] Verificaste que la prueba mide 80 bytes (la cifra de verificación sin conexión del tagline)
M4 — Time-lock RSW con Aestus
Concepto: un puzzle time-lock RSW. Sella un valor ahora; cualquiera puede abrirlo solo tras T cuadrados secuenciales — cifra ahora, descifra tras un retardo demostrable. El bloque básico para pujas selladas y commit-reveal donde nadie debe espiar antes de tiempo.
Lab: labs/lab04_aestus_timelock.py · ~20 min · requiere M2
Pasos
python labs/lab04_aestus_timelock.py- Observa el ciclo seal → open:
T=350cuadrados, luego el payload abierto yverify: True. courselib/randomness.py→timelock_seal():rsw.seal(message, T=...)→rsw.open_puzzle(puzzle);message_matchconfirma que el texto plano volvió intacto.
Salida esperada
proof: T=350 squarings,result: <payload abierto>,verify: Truetracecon un eventotimelock(T=350, opened=True)
Autocomprobación
- [ ] Explicas por qué un time-lock oculta un valor sin tercero de confianza
- [ ] Viste el mensaje sellado recuperado tras
Tcuadrados
M5 — Commit–reveal y ataques de sesgo
Concepto: el módulo clave. Construye una lotería que un operador deshonesto puede iterar, demuestra el sesgo, y luego sustituye el sorteo por un Sortes ECVRF que el operador no puede iterar.
Lab: labs/lab05_commit_reveal.py · ~25 min · track: economía · requiere M3
Pasos
python labs/lab05_commit_reveal.py- Compara los dos billetes:
billete sesgadovsbillete VRF justo. La líneaverify VRF: Trueprueba que el sorteo justo lleva una prueba verificable. - Lee la nota de auditoría que imprime el lab: «El sorteo justo vincula una beta por cada seed — el operador no puede iterar.»
courselib/randomness.py→BiasedLottery(hasta 200 intentos iterandooperator_secret|player_seed|attemptpor un jackpot) vsFairLottery(un sorteo ECVRF → un billete, iteración imposible).
Salida esperada
billete sesgado: <n>ybillete VRF justo: <n>,verify VRF: True, la línea de la nota de auditoríatracecon eventoscommitydraw(vrf_ok=True)
Autocomprobación
- [ ] Describes el ataque de iteración que realiza
BiasedLottery - [ ] Explicas por qué
FairLottery(una beta por seed) es inmune
M6 — Verificación on-chain
Concepto: empaqueta las pruebas para un consumidor on-chain — un vector VDF de Wesolowski con la forma que espera un verificador en Solidity, más una palabra de lotería de 32 bytes derivada de la beta de Sortes ECVRF.
Lab: labs/lab06_onchain_consumer.py · ~20 min · track: avanzado · requiere M2, M3
Pasos
python labs/lab06_onchain_consumer.py- Fíjate en la línea
protocolo: wesolowski-vdf,verify: Truey lapalabra de lotería: 0x…de 32 bytes. courselib/randomness.py→onchain_vdf_vector()(emitescheme/seed/difficulty/y/pi/l/validcomo cadenas listas para un verificador) ylottery_word_from_vrf()(los primeros 32 bytes de la beta ECVRF).- Puente: el lab imprime una nota de despliegue que apunta a lottery/docs/deployments-base.md — el verificador
ChronosVDF.solen vivo en Base.
Salida esperada
protocol: wesolowski-vdf,verify: True,palabra de lotería: 0x<hex>…, la línea de la nota de desplieguetracecon eventosonchain_vdfylottery_word
Autocomprobación
- [ ] Nombras los dos artefactos que necesita un consumidor on-chain (vector VDF + palabra VRF)
- [ ] Sabes dónde encontrar la documentación de despliegue en Base
Leer la traza (en cada lab)
Concepto: cada lab registra una pequeña Trace (ver courselib/trace.py) para que el comportamiento del agente/oráculo sea inspeccionable, no magia.
Pasos (tras cada lab)
- Baja al bloque
trace (<n> eventos):al final de la salida del lab. - Lee cada evento —
kindmás los campos que registró el lab (chaos_draw→verified, bytes;vdf_eval→difficulty, valid;tamper_check→valid=False). - Mapea cada evento a una línea de stdout encima. La traza es el «registro de tests unitarios» de la aleatoriedad verificable.
Autocomprobación
- [ ] Señalas el evento que prueba que un sorteo se verificó
- [ ] En M2 encuentras el evento
tamper_checkconvalid=False
Ejercicios y certificado
Tras los labs, ejecuta las comprobaciones DIY. Cada módulo tiene un ejercicio autocontenido en courselib/exercises.py (M2 manipula un VDF y comprueba que la verificación falla; M3 comprueba que la prueba mide exactamente 80 bytes; M5 comprueba que el sorteo justo verifica):
python labs/run_exercises.py # corre los seis, imprime ✓/✗ por módulo
python labs/run_exercises.py --module m3 # corre solo la comprobación de un módulo
Cuando los seis pasen, emite tu certificado:
python labs/run_exercises.py --certificate "Tu Nombre" --lang es # o --lang en / ru
Escribe certificate.html — ábrelo en un navegador y Print → Save as PDF. El ID de credencial se deriva de forma determinista del nombre + la fecha de emisión (courselib/certificate.py). El certificado queda bloqueado hasta que pasen los ejercicios, salvo que pases --skip-check.
Puente: del curso a la lotería en Base
Objetivo: las mismas pruebas que produjiste en local son las que verifican los contratos AIMarket lottery/ en Base.
| Curso | Lotería en Base |
|---|---|
| M2 vector Chronos VDF | verificador de Wesolowski ChronosVDF.sol |
| M3 beta Sortes ECVRF | palabra de lotería de 32 bytes (M6 lottery_word_from_vrf) |
| M5 sorteo justo vs sesgado | por qué el consumidor usa VRF y no un beacon de confianza |
M6 onchain_vdf_vector() |
el vector exacto {y, pi, l} que consume el verificador |
Las direcciones de despliegue y el verificador en Solidity están en lottery/docs/deployments-base.md.
Lista de autocomprobación
Track básico:
- [ ] Ejecutas lab01–lab04 en local (y en Colab) en EN, RU, ES
- [ ] Explicas chaos VRF, VDF, ECVRF y time-lock en una frase cada uno
- [ ] Muestras que un VDF manipulado falla la verificación (M2)
- [ ] Enuncias por qué una prueba ECVRF de 80 bytes se verifica sin conexión (M3)
Tracks economía + avanzado:
- [ ] Ejecutas lab05 y describes el ataque de iteración + el arreglo con VRF
- [ ] Ejecutas lab06 y produces un vector VDF + palabra de lotería listos para Base
- [ ]
pytest -qen verde ypython labs/run_exercises.pytodo ✓
Problemas frecuentes
| Problema | Solución |
|---|---|
No module named 'chronos' |
pip install -e ".[oracles]", o ejecuta desde el monorepo aicom |
No module named 'oracle_core' |
oracles/core debe estar en la ruta — automático en el monorepo; lo trae [oracles] para Sortes/Platon |
Oracle package '…' not installed |
fuera del monorepo y sin el extra — instala .[oracles] o clona junto a oracles/ |
| Falla el import de Platon | instala numpy; comprueba que existe oracles/oracles/platon/backend |
| Lab VDF lento | los labs usan ~700 cuadrados (M2) / T=350 (M4) — baja la dificultad solo en tu propio ejercicio |
| Cadenas RU/ES vacías | export COURSE_LANG=ru|es; las claves de i18n/ru.json deben coincidir con i18n/en.json |
Fallo i18n en pytest |
añade la clave que falta a los tres catálogos (en/ru/es) |
| Código viejo en Colab | reejecuta la celda de setup; fija la rama main |
Regenerar sitio y notebooks
Tras editar labs o i18n:
python3 scripts/build_course_assets.py
Las guías en docs/ se mantienen a mano — actualiza EN primero, luego los espejos RU/ES.