Пошаговое руководство по курсу
Различайте доказательство из лабораторной и данные развёртывания. Локальные упражнения ECVRF, VDF и лотерея выполняются без оплаты. В витрине лотереи сначала проверьте окружение и доказательства розыгрыша. UNI использует имитацию блокчейна. Транзакцию Base проверяйте в Base. Документированный вход в LIVE — бесплатное место за работу через
enterFromWork, платные билеты выключены.
Для кого: разработчики, изучающие паттерны лотерейных смарт-контрактов до выхода на Base mainnet.
Язык лаб:COURSE_LANG=en|ru|es· строки UI вi18n/· этот гайд на русском.
English: step-by-step.md · Español: step-by-step.es.md
Зачем этот курс
On-chain лотереи ломаются, когда оператор может незаметно перекатывать розыгрыш, пока ему не понравится победитель, — это атака grinding. Контракты lottery/ на Base закрывают её проверяемой случайностью (ECVRF через оракул Sortes) и VDF-маяком Wesolowski из оракула Chronos, а выплаты проходят через escrow-канал AIMarketEscrow со списанием по чеку. Курс разбирает каждый из этих примитивов как небольшой запускаемый порт на Python без LLM. Вы проверяете тот же Foundry-вектор, что и Solidity-контракты (ChronosVDF.t.sol), проходите раунд релейера от начала до конца и завершаете капстоуном, который симулирует полный честный раунд с проверяемыми артефактами — всё это напрямую отображается на код lottery/.
Честно о криптографии: примитивы оракулов — уровень research/prototype (crypto-maturity); для testnet и обучения — да, для mainnet TVL без внешнего аудита — нет.
Содержание
- Выбор трека
- Установка (10 минут)
- M1 — Несмещаемый розыгрыш лотереи
- M2 — Проверка VDF on-chain
- M3 — Escrow и платёжные каналы
- M4 — Жизненный цикл раунда релейера
- M5 — Капстоун: честный раунд
- Упражнения и сертификат
- Наблюдаемость в каждой лабе
- Мост: от курса к lottery/
- Чеклист самопроверки
- Типичные проблемы
Выбор трека
| Трек | Модули | Время | Оракулы |
|---|---|---|---|
| Базовый | M1 → M4 | ~1,5 ч | Sortes + Chronos (fallback, если не установлены) |
| Продвинутый | Базовый + M5 капстоун | +30 мин | Sortes + путь Chronos VDF |
| Мост к lottery/ | После M4 или M5 | +30 мин | Живой forge test + контракты на Base |
После каждой лабы смотрите блок Trace (раздел «Наблюдаемость»).
Установка (10 минут)
Шаг 1 — Клон и установка
git clone https://github.com/alexar76/aimarket-courses.git
cd aimarket-courses/smart-contracts-course
pip install -e ".[oracles,dev]"
Экстра [oracles] подключает пакеты оракулов Sortes (ECVRF) и Chronos (VDF). Если экстра недоступна в вашем окружении, лабы всё равно работают — courselib переключается на детерминированную реализацию из stdlib, и трейс помечает oracle=fallback. Нужен Python 3.11+.
Шаг 2 — Тесты
pytest -q
Ожидается: все тесты проходят (паритет i18n по en/ru/es, примитивы контрактов, вложенный Foundry-вектор, рендеринг сертификата).
Шаг 3 — Первая лаба
python labs/lab01_unbiasable_draw.py
python labs/run_exercises.py
Шаг 4 — Язык интерфейса лаб (опционально)
export COURSE_LANG=ru # или es, по умолчанию en
python labs/lab01_unbiasable_draw.py
COURSE_LANG меняет только печатаемые строки лабы (названия модулей, метки, подсказки) — код, команды, номера билетов и Foundry-вектор одинаковы на всех языках.
Шаг 5 — Google Colab
- Откройте сайт курса → Open in Colab на любой лабе.
- Выполните setup-ячейку (clone +
pip install -e ".[oracles,dev]"). - При необходимости в setup-ячейке:
os.environ["COURSE_LANG"] = "ru". - Запустите ячейку лабы.
M1 — Несмещаемый розыгрыш лотереи
Концепция: Commit–reveal и ECVRF закрывают grinding-атаки оператора.
Лаба: labs/lab01_unbiasable_draw.py · ~15 мин
Шаги
python labs/lab01_unbiasable_draw.py- Сравните два розыгрыша в выводе:
- Смещённая лотерея (grinding оператора) —
grindable=True: оператор перехеширует с секретом, пока не выпадет нужный билет (BiasedLottery.operator_can_grind). - Честная лотерея (ECVRF) — одно
alphaдаёт ровно одноbeta,verified=True. Перекатить нельзя.
- Смещённая лотерея (grinding оператора) —
- Откройте
courselib/contracts.py—BiasedLottery,FairLottery,_sortes_draw(путь Sortes ECVRF с fallback из stdlib). - Упражнение:
python labs/run_exercises.py --module m1— честный розыгрыш проверяется, смещённый поддаётся grinding.
Что доказывает: проверяемый розыгрыш убирает произвол оператора. On-chain потребитель: lottery/docs/ и AIAgentLottery.sol.
M2 — Проверка VDF on-chain
Концепция: Доказательства Wesolowski из Chronos совпадают с тест-векторами Foundry.
Лаба: labs/lab02_vdf_verify.py · ~15 мин · нужен M1
Шаги
python labs/lab02_vdf_verify.py- Лаба грузит вложенный Foundry-вектор (
courselib/fixtures/chronos_vector.json, копияlottery/contracts/test/vectors/chronos_vector.json) и проверяетπ^l·g^r ≡ y (mod N). Вывод:verify: True (AB_equals_y=True). - Если оракул Chronos установлен,
verify_wesolowski_vectorещё и заново выводит доказательство вживую (hash_to_group → evaluate → prove → verify). - Упражнение:
python labs/run_exercises.py --module m2.
Что доказывает: Python- и Solidity-верификаторы согласны по одним и тем же байтам. Запустите forge test в lottery/contracts — ChronosVDF.t.sol использует тот же вектор.
M3 — Escrow и платёжные каналы
Концепция: Удержание средств до поставки; списание по чеку, как в AIMarketEscrow.
Лаба: labs/lab03_escrow_channel.py · ~20 мин · нужен M1
Шаги
python labs/lab03_escrow_channel.py- Жизненный цикл канала: open (депозит) → debit (по чеку) → settle (раздел между hub и возвратом).
- Строка Повтор чека: второй
debitс тем жеreceipt_idотклоняется (blocked=True) — это защита от повтора,EscrowChannel.used_receipts. courselib/contracts.py→EscrowChannelмоделируетAIMarketEscrowopen/debit/settle (Protocol v2 §6): подпись, nonce, совпадение hub, проверка баланса.- Упражнение:
python labs/run_exercises.py --module m3— спишите дважды по одному чеку, второе должно упасть.
M4 — Жизненный цикл раунда релейера
Концепция: baseSeed, розыгрыш Sortes, опциональный путь VDF on-chain.
Лаба: labs/lab04_relayer_round.py · ~20 мин · нужны M1–M2
Шаги
python labs/lab04_relayer_round.py- Три фазы в выводе и в блоке
Trace:- Сид Chronos —
base_seed = sha256(roundId ‖ blockhash ‖ platonRandom). - Билет Sortes — проверяемый розыгрыш раунда (
verified=True). - Вектор VDF — при
onchain_vdf=Trueраунд прикрепляет маякVdfProofи заново проверяет Foundry-вектор (vector_valid=True).
- Сид Chronos —
- Сверьтесь:
lottery/relayer/ailottery_relayer/economy_draw.py— боевой розыгрыш, который зеркалит эта лаба. - Упражнение:
python labs/run_exercises.py --module m4— проследите трейсbaseSeed → Sortes → VDF-маяк.
M5 — Капстоун: честный раунд
Концепция: Симуляция полного раунда лотереи с проверяемыми артефактами.
Лаба: labs/lab05_lottery_capstone.py · ~30 мин · нужны M1–M4 · трек: продвинутый
Шаги
python labs/lab05_lottery_capstone.py- Лаба вызывает
simulate_fair_round(onchain_vdf=True, client_seed=...)и печатает артефакты раунда:ticket,vdf_path=onchain,chronos_vector=True. - Сравните артефакты с реальным логом
lottery/relayer— у каждого поля есть боевой аналог. - Упражнение:
python labs/run_exercises.py --module m5— запуститеsimulate_fair_roundсonchain_vdf=True.
Что доказывает: примитивы M1–M4 собираются в один аудируемый раунд — проверяемый билет, VDF-маяк и проверяемый вектор: артефакты, которым игрок верит, не доверяя оператору.
Упражнения и сертификат
python labs/run_exercises.py # все модули
python labs/run_exercises.py --module m3 # один модуль
Каждый модуль печатает ✓ или ✗; исправьте сбои и перезапустите. Когда всё зелёное — сертификат:
python labs/run_exercises.py --certificate "Иван Петров" --lang ru
Создаётся certificate.html (переопределяется через -o). Откройте в браузере и Печать → Сохранить как PDF. ID диплома выводится из имени и даты (courselib/certificate.py). Сертификат также можно получить в разделе Сертификат на сайте курса.
Наблюдаемость в каждой лабе
После каждой лабы (5 мин):
- Блок trace в конце вывода.
- Сопоставьте
eventsс шагами в stdout:biased_draw,fair_draw,vdf_verify,open/debit/settle,base_seed/sortes_draw/vdf_beacon,capstone. - В M4 свяжите три события трейса с тремя напечатанными фазами.
Trace — это «лог on-chain событий» раунда: по нему вы находите событие, доказывающее честность розыгрыша.
Мост: от курса к lottery/
-
Foundry-вектор —
lottery/contracts/test/vectors/chronos_vector.json(вложен вcourselib/fixtures/). Верификатор курса читает тот же файл, что и Solidity-тест. -
On-chain верификатор —
lottery/contracts/src/ChronosVDF.sol, тестChronosVDF.t.sol:cd lottery/contracts && forge test -
Розыгрыш релейера —
lottery/relayer/ailottery_relayer/economy_draw.py(зеркало M4). -
Сопоставление:
Курс lottery/ M1 честный розыгрыш Sortes ECVRF + AIAgentLottery.solM2 проверка VDF ChronosVDF.sol+ChronosVDF.t.solM3 escrow-канал AIMarketEscrowopen/debit/settleM4 раунд релейера economy_draw.pyM5 капстоун Полный раунд + VDF-маяк on-chain -
Документация: lottery/docs/.
Чеклист самопроверки
Базовый трек:
- [ ] lab01–lab04 локально и в Colab
- [ ] Объясняете, почему проверяемый розыгрыш бьёт grinding оператора
- [ ] Проверяете Foundry-вектор Chronos и связываете его с
ChronosVDF.t.sol - [ ] Описываете escrow open → debit → settle и защиту от повтора
- [ ] Читаете блок
Traceи находите событие честности
Продвинутый трек:
- [ ] lab05 + перечисление артефактов честного раунда
- [ ]
forge testвlottery/contractsи его связь с M2
Типичные проблемы
| Проблема | Решение |
|---|---|
ModuleNotFoundError: courselib |
Запуск из корня репозитория |
Импорт оракула падает / ошибка pip install ".[oracles]" |
Лабы работают на fallback из stdlib (oracle=fallback); для живого ECVRF/VDF запускайте из монорепо aicom, где резолвится oracles/ |
verify: False в M2 |
Проверьте целостность courselib/fixtures/chronos_vector.json (valid и AB_equals_y должны быть true) |
| Пустые RU/ES строки | export COURSE_LANG=ru; ключи i18n/ru.json должны совпадать с en.json |
| Падение паритета i18n в pytest | Добавьте недостающий ключ во все пять i18n/{en,ru,es,fr,zh}.json |
| В Colab старый код | Перезапустите setup-ячейку; зафиксируйте ветку main |
Деплой lottery/ и on-chain: lottery/docs/.
Гайды в docs/ правятся вручную — сначала EN, затем зеркала RU/ES.