Розробка NFT-механік для ігор — це постійний баланс між дешевизною газу та прозорістю on-chain. Типова помилка: намагатися записати кожну дію гравця в блокчейн. Скажімо, в MMO-RPG з 10 000 активних користувачів, де кожен виконує 500 дій на годину, повний on-chain запис вимагатиме 5 млн транзакцій на годину — вартість газу за поточних цін може становити сотні тисяч доларів на місяць. Ми використовуємо гібридну архітектуру: ownership та підсумкові стани зберігаються на ланцюзі, а проміжні ігрові події обробляються на сервері. Такий підхід скорочує витрати на газ на 90% порівняно з повним on-chain записом. Наш досвід — понад 50 впроваджень для ігор із власною токеномікою. Наші інженери аудитують контракти та оптимізують логіку. Отримайте консультацію з архітектури вашої гри — розрахуємо економію на ваших навантаженнях.
On-chain vs off-chain: що і де зберігати
On-chain верифіковано та постійно. У контракті зберігаємо:
- Ownership через ERC-721
- Core stats — рівень, клас, рідкість (впливають на торгову цінність)
- Earned traits — досягнення, підтверджені settlement
- Resource balances — накопичені ресурси
Off-chain (ігровий сервер або L3) обробляє:
- Позиції та рухи в реальному часі
- Бойові розрахунки та тимчасові ефекти
- Черги подій та проміжні результати
- Поточні HP/MP
| Характеристика | On-chain | Off-chain |
|---|---|---|
| Верифікація | Повна (будь-хто може перевірити) | Немає (довіра до сервера) |
| Вартість газу | Висока (кожна транзакція) | Нульова |
| Швидкість | ~12 сек (Ethereum) | Миттєво |
| Приклад даних | Володіння, фінальні стати | Проміжні ігрові події |
Періодично (daily settlement або при значущій події) агреговані результати записуються on-chain. Гібридна архітектура в 5 разів дешевша за повний on-chain логування для ігор з високою частотою подій.
Як працює on-chain settlement
Повний on-chain запис кожного кліку веде до витрат, порівнянних з деплоєм контракту. Settlement консолідує тисячі подій в одну транзакцію, фіксуючи лише підсумкові зміни характеристик. Наприклад, персонаж може виконати 1000 PvE-боїв за день, але на блокчейн запишеться лише фінальний рівень та отримані предмети. Це економить >99% газу для активних гравців.
Як реалізувати динамічні NFT?
Динамічний NFT — це ERC-721, чиї метадані змінюються залежно від ігрових подій. Ми використовуємо стандарт ERC-4906 для сповіщення маркетплейсів про оновлення без перевипуску токена. Приклад контракту персонажа з on-chain статами:
contract GameCharacter is ERC721, AccessControl {
bytes32 public constant GAME_SERVER_ROLE = keccak256("GAME_SERVER_ROLE");
struct CharacterStats {
uint16 level;
uint32 experience;
uint8 strength;
uint8 agility;
uint8 intelligence;
uint64 lastSettled;
}
mapping(uint256 => CharacterStats) public stats;
mapping(uint256 => uint256) public achievementFlags;
function settleExperience(
uint256 tokenId,
uint32 expGained,
uint256 newAchievements
) external onlyRole(GAME_SERVER_ROLE) {
CharacterStats storage char = stats[tokenId];
char.experience += expGained;
while (char.experience >= expForNextLevel(char.level)) {
char.experience -= expForNextLevel(char.level);
char.level++;
_applyLevelUpBonus(tokenId, char.level);
}
achievementFlags[tokenId] |= newAchievements;
char.lastSettled = uint64(block.timestamp);
// ERC-4906: уведомление маркетплейсов об обновлении метаданных
emit MetadataUpdate(tokenId);
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
// Генерация динамического URI на основе текущих статов
return string(abi.encodePacked(BASE_URI, tokenId.toString(), '?level=', stats[tokenId].level.toString()));
}
}
Item crafting та composability: ERC-1155 та equip
ERC-1155 підходить для fungible/semi-fungible предметів: 1000 залізних мечів — однакові, кожен легендарний — унікальний. Реалізуємо крафт з рецептами та спалюванням матеріалів:
contract GameItems is ERC1155, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
struct CraftingRecipe {
uint256[] inputIds;
uint256[] inputAmounts;
uint256 outputId;
uint256 outputAmount;
}
mapping(uint256 => CraftingRecipe) public recipes;
function craft(uint256 recipeId) external {
CraftingRecipe storage recipe = recipes[recipeId];
_burnBatch(msg.sender, recipe.inputIds, recipe.inputAmounts);
_mint(msg.sender, recipe.outputId, recipe.outputAmount, "");
emit ItemCrafted(msg.sender, recipeId, recipe.outputId);
}
}
Equip-система блокує предмет при екіпіруванні — його не можна передати, доки не знімеш. Ми гарантуємо безпеку через override _update.
Seaport zone для захисту покупця
Проблема: гравець лістить персонажа 50-го рівня, а під час лістингу рівень падає. Рішення — кастомна зона Seaport, яка перевіряє мінімальні стати при здійсненні угоди:
contract CharacterStatsZone is ZoneInterface {
function validateOrder(ZoneParameters calldata zoneParameters) external view override returns (bytes4 validOrderMagicValue) {
(uint256 tokenId, uint16 minLevel) = abi.decode(zoneParameters.extraData, (uint256, uint16));
CharacterStats memory current = characterContract.stats(tokenId);
require(current.level >= minLevel, "Character level too low");
return ZoneInterface.validateOrder.selector;
}
}
Це довірче рішення — знижує ризики покупця та підвищує ліквідність NFT.
Чому Chainlink VRF — стандарт?
Лут-бокси, крит-удари, дроп — все потребує verifiable random. Chainlink VRF V2 Plus забезпечує перевірену випадковість: гравець може переконатися, що випадіння предмету чесне. Звернення до оракула коштує газу, але ми оптимізуємо через батчинг запитів.
contract LootSystem is VRFConsumerBaseV2Plus {
function openLootBox(uint256 boxTokenId) external {
require(lootBoxContract.ownerOf(boxTokenId) == msg.sender, "Not owner");
lootBoxContract.burn(boxTokenId);
uint256 requestId = s_vrfCoordinator.requestRandomWords(...);
requestToPlayer[requestId] = msg.sender;
}
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
address player = requestToPlayer[requestId];
uint256 rand = randomWords[0];
uint256 rarityRoll = rand % 10_000;
// 0.5% легендарний, 4.5% епік, 15% рідкісний, 80% звичайний
ItemRarity rarity;
if (rarityRoll < 50) rarity = ItemRarity.Legendary;
else if (rarityRoll < 500) rarity = ItemRarity.Epic;
else if (rarityRoll < 2000) rarity = ItemRarity.Rare;
else rarity = ItemRarity.Common;
uint256 itemId = _mintRandomItem(player, rarity, rand);
emit LootBoxOpened(player, itemId, rarity);
}
}
Процес інтеграції
- Аналіз вимог — діаграми потоків даних, вибір стандартів (ERC-721/1155, ERC-4906, ERC-4626 при необхідності).
- Розробка контрактів — повне покриття тестами Foundry/Hardhat, gas profiling.
- Інтеграція з фронтендом — wagmi, viem, RainbowKit для взаємодії з гаманцями.
- Тестування та аудит — обов'язковий етап перед mainnet, що включає Slither/Mythril/Echidna.
- Деплой та моніторинг — через Tenderly, налаштування алертів.
Наші інженери мають 7+ років досвіду в блокчейн-розробці та реалізували понад 50 проектів з NFT-інтеграцією. Замовте аудит смарт-контрактів перед запуском — оцінка проекту безкоштовно.
Що входить в роботу
В рамках інтеграції NFT-механік ми надаємо:
- Аудит існуючої архітектури та рекомендації з газ-оптимізації.
- Розробку смарт-контрактів на Solidity (ERC-721/1155, ERC-4906, ERC-4626 при необхідності).
- Інтеграцію з фронтендом (wagmi, viem, RainbowKit).
- Написання технічної документації та API-специфікацій.
- Навчання команди роботі з контрактами та процесами settlement.
- Підтримку після запуску та моніторинг через Tenderly.
Орієнтири за термінами
| Етап | Термін |
|---|---|
| Базова інтеграція (ERC-721 з рівнем, settlement, VRF) | 4–6 тижнів |
| Повна система (dynamic metadata, equipment, crafting, custom zone) | 8–12 тижнів |
| Аудит смарт-контрактів (обов'язковий перед mainnet) | 3–5 тижнів |
Зв'яжіться з нами, щоб обговорити ваш проект. Отримайте консультацію з архітектури — розрахуємо економію газу на ваших навантаженнях.







