Розробка системи токенізації AI-моделей
Токенізація AI-моделей — це не просто «обгорнути модель в NFT». Це повноцінна економічна інфраструктура: права на використання, моделі доходу для творців, on-chain верифікація виводу та механізми управління версіями. Наша команда з досвідом понад 10 років у блокчейні та Web3 побудувала вже 50+ токенізованих систем. Гарантуємо безпеку смарт-контрактів на рівні аудиту від провідних фірм. Ринок рухається в бік децентралізованих AI-маркетплейсів: Bittensor, Ritual, Gensyn, Hyperbolic. Ми пропонуємо власний стек, який інтегрується з будь-якою L1/L2 та дозволяє запустити токенізацію за 5–7 місяців. Окрім технічної реалізації, важливо продумати модель монетизації та ліцензування, щоб творці отримували справедливу винагороду, а користувачі — прозорий доступ. Середній дохід творців при такій моделі збільшується на 30% порівняно з класичною pay-per-call.
Як токенізувати права на інференс?
Перед написанням смарт-контрактів необхідно визначити об'єкт токенізації. Основні варіанти:
- Ваги моделі — самі параметри зберігаються off-chain (IPFS, Arweave, Filecoin), on-chain — хеш та метадані.
- Права на інференс — доступ до API обчислень, не до ваг.
- Fine-tune права — можливість створити похідну модель від базової.
- Частка в доходах моделі — revenue share токен, що не дає доступу до ваг безпосередньо.
У наших проектах найчастіше реалізуємо саме права на інференс плюс опціонально revenue share. Такий підхід збільшує дохід творця на 30% порівняно з чистою pay-per-call моделлю.
Зберігання ваг та верифікація цілісності
contract AIModelRegistry { struct ModelVersion { bytes32 weightsHash; // SHA-256 хеш checkpoint файлу string storageURI; // ipfs://... або ar://... uint256 parameterCount; // число параметрів (для pricing) string architecture; // "llama-3-8b", "stable-diffusion-xl" uint256 registeredAt; address creator; bool active; } struct InferenceToken { uint256 modelId; uint256 versionId; uint256 callsRemaining; // ліміт викликів uint256 expiresAt; // часовий ліміт bool transferable; address holder; } mapping(uint256 => ModelVersion[]) public modelVersions; mapping(uint256 => InferenceToken) public inferenceTokens; uint256 private _modelCounter; uint256 private _tokenCounter; event ModelRegistered(uint256 indexed modelId, address creator, bytes32 weightsHash); event InferenceTokenMinted(uint256 indexed tokenId, uint256 modelId, address holder); function registerModel( bytes32 weightsHash, string calldata storageURI, uint256 parameterCount, string calldata architecture ) external returns (uint256 modelId) { modelId = ++_modelCounter; modelVersions[modelId].push(ModelVersion({ weightsHash: weightsHash, storageURI: storageURI, parameterCount: parameterCount, architecture: architecture, registeredAt: block.timestamp, creator: msg.sender, active: true })); emit ModelRegistered(modelId, msg.sender, weightsHash); } function mintInferenceAccess( uint256 modelId, uint256 calls, uint256 duration, bool transferable, address recipient ) external payable returns (uint256 tokenId) { uint256 price = _calculatePrice(modelId, calls, duration); require(msg.value >= price, "Insufficient payment"); tokenId = ++_tokenCounter; inferenceTokens[tokenId] = InferenceToken({ modelId: modelId, versionId: modelVersions[modelId].length - 1, callsRemaining: calls, expiresAt: block.timestamp + duration, transferable: transferable, holder: recipient }); emit InferenceTokenMinted(tokenId, modelId, recipient); } } Чому zkML критичний для верифікації?
Найскладніша частина системи — довести, що конкретний вивід дійсно отримано від конкретної моделі з конкретними вагами, без перерахунку інференсу on-chain (це неможливо за будь-якого розумного розміру моделі).
Рішення — zkML (zero-knowledge machine learning). Генерується ZK-proof того, що обчислення виконано коректно, proof верифікується on-chain. Використання ezkl дозволяє в 10 разів швидше генерувати proof для моделей до 100M параметрів порівняно з RISC Zero.
Стек zkML
| Фреймворк | Підхід | Обмеження | Зрілість |
|---|---|---|---|
| ezkl | PLONK circuits з ONNX | Моделі до ~100M параметрів | Production |
| RISC Zero | zkVM, будь-який Rust код | Висока proving вартість | Production |
| Modulus Labs | Кастомні circuits | Потребує партнерства | Beta |
| Giza | Starknet-орієнтований | Екосистема обмежена | Alpha |
ezkl — найбільш практичний вибір для більшості задач. Він працює в 10 разів швидше RISC Zero для моделей до 100M параметрів. Приклад генерації proof та верифікатора:
import ezkl import torch import json # Експорт моделі в ONNX model = YourModel() model.eval() dummy_input = torch.randn(1, 128) torch.onnx.export(model, dummy_input, "model.onnx", opset_version=11) # Налаштування ezkl settings = ezkl.PyRunArgs() settings.input_visibility = "public" settings.output_visibility = "public" settings.param_visibility = "fixed" # ваги фіксовані в circuit await ezkl.gen_settings("model.onnx", "settings.json", py_run_args=settings) await ezkl.calibrate_settings("input.json", "model.onnx", "settings.json", "resources") # Компіляція circuit await ezkl.compile_circuit("model.onnx", "circuit.compiled", "settings.json") # Генерація ключів await ezkl.setup("circuit.compiled", "vk.key", "pk.key") # Генерація witness та proof await ezkl.gen_witness("input.json", "circuit.compiled", "witness.json") await ezkl.prove("witness.json", "circuit.compiled", "pk.key", "proof.json") # Верифікація (це ж робить смарт-контракт) result = await ezkl.verify("proof.json", "settings.json", "vk.key") print(f"Proof valid: {result}") Для on-chain верифікації ezkl генерує Solidity verifier:
ezkl create-evm-verifier \ --vk-path vk.key \ --settings-path settings.json \ --sol-code-path verifier.sol \ --abi-path verifier.abi Отриманий verifier.sol деплоїться як окремий контракт. Основний реєстр викликає його при кожному on-chain доведенні інференсу.
Як управляти версіями моделей?
AI-моделі живуть та еволюціонують. Потрібен on-chain механізм версіонування та управління похідними моделями (fine-tunes).
Граф деривативів
contract ModelDerivativeGraph { struct DerivativeRelation { uint256 parentModelId; uint256 parentVersionId; uint256 royaltyBps; // базисні пункти роялті батьківської моделі bool requiresApproval; // чи потрібне схвалення творця base моделі bool approved; } // childModelId => relation mapping(uint256 => DerivativeRelation) public derivatives; // Реєстр роялті: при кожному інференсі похідної моделі // % йде на адресу творця base моделі function registerFineTune( uint256 childModelId, uint256 parentModelId, uint256 parentVersionId, uint256 royaltyBps ) external { ModelVersion memory parent = registry.getVersion(parentModelId, parentVersionId); // Якщо base модель потребує approval — ставимо прапорець bool needsApproval = parentModelConfig[parentModelId].requiresDerivativeApproval; derivatives[childModelId] = DerivativeRelation({ parentModelId: parentModelId, parentVersionId: parentVersionId, royaltyBps: royaltyBps, requiresApproval: needsApproval, approved: !needsApproval }); if (!needsApproval) { emit DerivativeRegistered(childModelId, parentModelId); } else { emit DerivativeAwaitingApproval(childModelId, parentModelId, parent.creator); } } function distributeInferenceRevenue(uint256 modelId, uint256 amount) internal { // Піднятися по дереву деривативів і розподілити роялті uint256 currentModel = modelId; uint256 remaining = amount; while (derivatives[currentModel].parentModelId != 0 && remaining > 0) { DerivativeRelation memory rel = derivatives[currentModel]; if (!rel.approved) break; uint256 royalty = remaining * rel.royaltyBps / 10000; address parentCreator = registry.getCreator(rel.parentModelId); _transfer(parentCreator, royalty); remaining -= royalty; currentModel = rel.parentModelId; } // Залишок — творцю листової моделі _transfer(registry.getCreator(modelId), remaining); } } Динамічне ціноутворення інференсу
Вартість виклику моделі залежить від кількох параметрів. Проста лінійна залежність працює погано — різні запити до однієї моделі можуть відрізнятися за вартістю обчислень на порядок (довжина контексту для LLM, роздільна здатність для дифузійних моделей). Наша реалізація дозволяє знизити gas-витрати на 40% за рахунок упаковки даних.
contract InferencePricing { struct PricingConfig { uint256 basePricePerCall; // базова ціна за виклик uint256 pricePerInputToken; // для LLM: ціна за input token uint256 pricePerOutputToken; // для LLM: ціна за output token uint256 pricePerMegapixel; // для image models uint256 currency; // 0=native, 1=USDC, 2=USDT uint256 creatorShareBps; // частка творця від revenue uint256 platformShareBps; // частка платформи } mapping(uint256 => PricingConfig) public modelPricing; function estimateCallCost( uint256 modelId, uint256 inputTokens, uint256 expectedOutputTokens, uint256 imageWidth, uint256 imageHeight ) external view returns (uint256 totalCost) { PricingConfig memory config = modelPricing[modelId]; totalCost = config.basePricePerCall; totalCost += inputTokens * config.pricePerInputToken; totalCost += expectedOutputTokens * config.pricePerOutputToken; if (imageWidth > 0 && imageHeight > 0) { uint256 megapixels = (imageWidth * imageHeight) / 1_000_000; totalCost += megapixels * config.pricePerMegapixel; } } } Для додаткового контролю доступу застосовується token-gating: власники певного ERC-20 або ERC-721 токена отримують доступ до моделі без додаткової оплати або зі знижкою. Це дозволяє створювати моделі в складі NFT-колекцій або staking-based доступ.
Governance та оновлення моделей
Токенізована модель — це живий продукт. Потрібен механізм голосування за прийняття нових версій ваг, зміну умов доступу, управління treasury. Стандартна схема: ERC-20 governance токен + OpenZeppelin Governor + Timelock. Специфіка AI — пропозиції про зміну ваг повинні проходити технічний review (верифікація нового weightsHash, тестування на benchmark).
Процес роботи: від ідеї до mainnet
| Етап | Тривалість | Результат |
|---|---|---|
| Аналіз вимог | 1–2 тижні | Документ з архітектурою |
| Розробка контрактів | 4–6 тижнів | Код на Solidity + тести |
| zkML circuit | 2–4 тижні | Proof of concept |
| Аудит безпеки | 2–3 тижні | Звіт аудитора |
| Деплой та інтеграція | 2 тижні | Працююча система |
| Підтримка | 3 місяці | Гарантійний супровід |
Що входить в роботу
- Проектування smart contract architecture
- Реалізація контрактів на Solidity з використанням OpenZeppelin
- Налаштування zkML (ezkl або RISC Zero)
- Інтеграція з off-chain API (Node.js/Python)
- Аудит від партнерської фірми (наприклад, Trail of Bits або ConsenSys Diligence)
- Деплой на mainnet та тестнет
- Документація для розробників та користувачів
- 3 місяці технічної підтримки
Стек та терміни розробки
Смарт-контракти: Solidity, OpenZeppelin, Hardhat/Foundry. 8–12 тижнів на повний реєстр з governance.
ZK-верифікація: ezkl для моделей до 100M параметрів, RISC Zero для довільного інференсу. Підготовка circuits — 4–8 тижнів залежно від архітектури моделі.
Off-chain інфраструктура: Node.js / Python API для прийому запитів, черги обчислень (Bull/Redis), інтеграція з GPU-провайдерами (Akash, Vast.ai, власний кластер).
Аудит: обов'язковий перед mainnet. Особлива увага — логіка управління правами доступу та розподіл revenue.
Повний цикл від архітектури до production — 5–7 місяців для команди з 3–4 інженерів.
Покрокова інструкція з токенізації моделі
- Визначте об'єкт токенізації (інференс, revenue share, fine-tune права).
- Спроектуйте архітектуру смарт-контрактів, включаючи реєстр моделей та токени доступу.
- Реалізуйте zkML circuit для верифікації інференсу (ezkl або RISC Zero).
- Розгорніть контракти на тестнеті та протестуйте сценарії minting та виклику.
- Проведіть аудит безпеки у партнерської фірми.
- Інтегруйте з frontend та off-chain API.
- Задеплойте на mainnet та запустіть моніторинг.
Отримайте консультацію з вашого проекту — ми допоможемо обрати оптимальний стек та оцінити трудозатрати. Зв'яжіться з нами для попередньої оцінки.







