Как мы делили игру между блокчейном и сервером: подписи, «водяная отметка» и плагины
Когда мы проектировали Blockchain Cuties, подсматривать было не у кого. Блокчейн-игры того времени вроде CryptoKitties были очень простыми и целиком жили в блокчейне. Мы хотели гораздо большего: вещи, которые можно надевать, приключения, в которые можно ходить. Сразу стало понятно, что делать всё это в блокчейне — дорого и медленно, и рост это не выдержит.
Значит, надо было решить, где резать. Я сидел с модулями на бумажке и проводил линии: сами кьютики — NFT в блокчейне, вещи и приключения — в нашей базе данных. А дальше самое сложное — как эти две половины будут друг с другом общаться?
Одноразовые подписи. Некоторые вещи должны были менять состояние в блокчейне: например, зелья чуть-чуть меняют геном кьютика. Значит, сервер подписывает действие, а контракт проверяет подпись, прежде чем его применить. Чтобы одну подпись нельзя было использовать дважды, у каждой есть уникальный ID. Сейчас это стандартная схема; в 2018 году мы придумывали её сами.
«Водяная отметка» вместо растущего списка. Наивный путь — хранить в контракте все использованные ID и вечно платить за эту память. Вместо этого сервер время от времени сообщал контракту текущий минимальный sign ID: всё, что меньше, контракт просто не принимает. Это решило сразу две проблемы:
- память контракта не росла с каждым действием;
- вещи перестали зависать. Когда игрок начинает использовать зелье, оно замораживается в нашей базе, пока мы не увидим транзакцию в логах блокчейна. Если игрок передумал или у него не хватило денег на комиссию, зелье осталось бы замороженным навсегда. А когда отметка проходит его ID, мы точно знаем, что контракт эту подпись уже никогда не примет, — и вещь можно спокойно разморозить.
Плагины вместо апгрейдов. Поверх этого я сделал систему плагинов: маленьких контрактов, подключённых к основному и говорящих на том же протоколе подписей. Рынок вещей был плагином, разные зелья — тоже, и ежедневное голосование, где игроки отправляли крошечную транзакцию, а случайный проголосовавший получал награду. Новые фичи могли чуть-чуть поменять геном или параметры кьютика, не трогая основной контракт, — без прокси и без миграций.
Что я сказал бы команде, которая сегодня начинает Web3-продукт: кладите в блокчейн только то, чем игрок должен владеть, всё остальное подтверждайте подписями — и продумывайте не только то, как состояние блокируется, но и как оно освобождается.