Разработка кастомного оракула

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка кастомного оракула
Сложная
~1-2 недели
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1258
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1170
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    873
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1092
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    830

Разработка кастомного оракула

Chainlink и Pyth закрывают 95% потребностей в ценовых данных. Но есть случаи где готовое решение не подходит: специфический актив без coverage, нестандартный тип данных, требование минимального доверия к третьим сторонам, или необходимость специфической агрегации. Тогда разрабатывают кастомный оракул.

Когда нужен кастомный оракул

  • Неликвидный или нишевый актив: Chainlink не добавляет feed для токена с $1M TVL
  • Off-chain данные: спортивные результаты, погода, страховые индексы — специфичны
  • Частные данные: корпоративные метрики, TradFi данные с лицензионными ограничениями
  • Агрегация по-особому: медиана по конкретному набору источников, VWAP за кастомный период
  • On-chain данные с верификацией: данные из другой сети через ZK proofs

Архитектура кастомного оракула

Компоненты

External Data Sources
    ↓ (HTTP/WebSocket)
Oracle Node Network
    ├── Node 1 (fetches, signs, submits)
    ├── Node 2 (fetches, signs, submits)
    └── Node N (fetches, signs, submits)
         ↓ (signed reports)
On-chain Aggregator Contract
    ├── Collect reports
    ├── Verify signatures  
    ├── Aggregate (median/TWAP)
    └── Publish result
         ↓
Consumer Contracts

On-chain Aggregator

contract CustomOracle {
    struct Report {
        uint256 value;
        uint256 timestamp;
        bytes signature;
    }
    
    mapping(address => bool) public trustedNodes;
    uint256 public requiredReports;  // минимум M из N нод
    
    uint256 public latestValue;
    uint256 public latestTimestamp;
    
    function submitReport(uint256 value, uint256 timestamp, bytes calldata sig) external {
        require(trustedNodes[msg.sender], "Not trusted node");
        require(timestamp > block.timestamp - 300, "Report too old");
        
        // Верификация подписи
        bytes32 messageHash = keccak256(abi.encodePacked(value, timestamp));
        address signer = recoverSigner(messageHash, sig);
        require(signer == msg.sender, "Invalid signature");
        
        _pendingReports[roundId][msg.sender] = Report(value, timestamp, sig);
        
        if (_pendingReportCount[roundId] >= requiredReports) {
            _finalizeRound(roundId);
        }
    }
    
    function _finalizeRound(uint256 roundId) internal {
        uint256[] memory values = _collectValues(roundId);
        latestValue = _median(values);
        latestTimestamp = block.timestamp;
        emit NewRound(roundId, latestValue);
    }
}

Oracle Node

Off-chain нода которая периодически:

  1. Запрашивает данные с источников
  2. Агрегирует (median, weighted average)
  3. Подписывает ECDSA
  4. Отправляет транзакцию в агрегатор
import asyncio
import aiohttp
from eth_account import Account
from web3 import Web3

class OracleNode:
    async def fetch_price(self, source_url: str) -> float:
        async with aiohttp.ClientSession() as session:
            async with session.get(source_url) as response:
                data = await response.json()
                return float(data['price'])
    
    async def run_round(self):
        # Получить цены из нескольких источников
        prices = await asyncio.gather(*[
            self.fetch_price(url) for url in self.sources
        ])
        
        # Медиана
        median_price = sorted(prices)[len(prices) // 2]
        
        # Подписать и отправить
        timestamp = int(time.time())
        message = Web3.solidity_keccak(['uint256', 'uint256'], 
                                        [int(median_price * 1e8), timestamp])
        signed = self.account.sign_message(message)
        
        await self.oracle_contract.functions.submitReport(
            int(median_price * 1e8), timestamp, signed.signature
        ).transact()

Verifiable Oracle с ZK Proofs

Для высоких требований к trustlessness — ZK-based oracle. Нода предоставляет ZK proof того что данные корректно получены и агрегированы.

DECO (Chainlink Labs research): TLS-based ZK proofs. Нода доказывает что получила данные с конкретного HTTPS endpoint без раскрытия TLS session.

zkOracle концепция: вычисление агрегации доказывается через zkSNARK. Верификатор on-chain дешево проверяет proof вместо доверия подписи.

На практике это экспериментально и дорого по вычислениям — но развивающееся направление.

Манипуляция оракулами: защита

Flash loan + oracle manipulation: злоумышленник берёт flash loan, двигает цену на DEX (если оракул использует spot price), эксплуатирует протокол по манипулированной цене.

Защиты:

  • TWAP вместо spot: Time-Weighted Average Price за N минут сложнее манипулировать
  • Multiple sources: медиана по нескольким биржам, не только Uniswap
  • Circuit breakers: отказ при отклонении от предыдущей цены > X%
  • Volume-weighted: игнорировать источники с аномально малым объёмом

Update frequency и front-running: если оракул обновляется раз в час — арбитражники видят запланированное обновление в mempool и front-runят. Частые обновления или private mempool снижают этот риск.

Разработка кастомного оракула: 4-12 недель в зависимости от числа источников, сетей и требований к trustlessness.