Розробка системи синхронізації стану між мережами

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка системи синхронізації стану між мережами
Складний
від 1 тижня до 3 місяців
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1306
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1218
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    920
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1147
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    610
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    885

Система синхронізації стану між чейнами

Синхронізація стану — ширша задача, ніж bridge токенів. Смарт-контракт на чейні B повинен "знати" про стан смарт-контракту на чейні A та реагувати на зміни. Приклади: governance vote на Ethereum застосовується до протоколу на Arbitrum; NFT куплений на Polygon розблокує контент на Solana; позиція в lending на Optimism використовується як collateral на Base.

Вимагає генерального мессенджингу не тільки токенів. І вирішення проблеми finality: коли чейн B може довіряти стану з чейна A?

Проблема Finality

Chain Тип Finality Час
Ethereum Absolute (Casper) ~12 хв
Arbitrum Soft sequencer ~250ms; hard ~10 хв
Polygon PoS Checkpoint на L1 ~30 хв повна finality
Solana ~1.5 сек (400ms slots) ~1.5 сек
Bitcoin Probabilistic 6 блоків ~60 хв

Optimistic: прийняти після soft finality, challenge window для rollback. Для non-financial стану.

Conservative: чекати hard finality (L1-anchored). 10-30 хв для L2. Для фінансових даних.

ZK-Верифікація: Trustless Рішення

Цільовий чейн верифікує ZK proof про стан вихідного чейна. Storage Proof через Herodotus: доказати значення конкретного storage slot на іншому чейні. Верифікується on-chain через Merkle-Patricia proof.

Практична Архітектура: General Message Passing

Для більшості проектів ZK light client надто складний/дорогий. Використовуємо GMP через Axelar/LayerZero/Wormhole з розумними параметрами безпеки.

// Source: відправляємо стан
contract StateSender {
    struct GameState {
        address player;
        uint256 score;
        uint256 level;
        uint256 timestamp;
    }
    
    function syncPlayerState(
        string calldata destChain,
        string calldata destAddress,
        address player
    ) external payable {
        GameState memory state = GameState({
            player: player,
            score: playerScores[player],
            level: playerLevels[player],
            timestamp: block.timestamp
        });
        
        bytes memory payload = abi.encode(state);
        gasService.payNativeGasForContractCall{value: msg.value}(
            address(this), destChain, destAddress, payload, msg.sender
        );
        gateway.callContract(destChain, destAddress, payload);
    }
}

// Destination: отримуємо та застосовуємо
contract StateReceiver is AxelarExecutable {
    function _execute(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) internal override {
        require(authorized[sourceChain][sourceAddress], "Unauthorized");
        
        GameState memory state = abi.decode(payload, (GameState));
        require(state.timestamp > syncedState[state.player].timestamp, "Stale");
        
        syncedState[state.player] = state;
        emit StateSynced(sourceChain, state.player, state.score);
    }
}

Ідемпотентність та упорядкування

Повідомлення можуть прийти не в порядку або дубльовано.

mapping(string => mapping(address => uint256)) public lastSeq;
mapping(bytes32 => bool) public processed;

function _execute(string calldata source, string calldata addr, bytes calldata payload) internal override {
    bytes32 msgId = keccak256(abi.encode(source, addr, payload));
    require(!processed[msgId], "Already processed");
    processed[msgId] = true;
    
    (GameState state, uint256 seq) = abi.decode(payload, (GameState, uint256));
    require(seq == lastSeq[source][state.player] + 1, "Out of order");
    lastSeq[source][state.player] = seq;
    
    _applyState(state);
}

Батчинг для високочастотних оновлень

Для ігор/trading синхронізувати кожну зміну on-chain неефективно. Батчуємо оновлення off-chain, відправляємо Merkle root.

class StateSyncWorker {
  private pending = new Map();
  private syncInterval = 30_000; // 30 сек
  
  queueUpdate(playerId: string, state: PlayerState) {
    this.pending.set(playerId, state);
  }
  
  async flushBatch() {
    if (this.pending.size === 0) return;
    
    const batch = Array.from(this.pending.entries());
    this.pending.clear();
    
    const leaves = batch.map(([id, state]) =>
      keccak256(abi.encode(id, state))
    );
    const merkleRoot = new MerkleTree(leaves).getRoot();
    
    await stateSyncContract.submitBatch(merkleRoot, batch.length);
    await batchStore.save(merkleRoot, batch);
  }
}

Таймлайн

Базова синхронізація (2 чейни, Axelar, упорядкована): 3-4 тижні. Merkle-batched з off-chain worker + ZK proof: 8-12 тижнів. ZK light client (Succinct/Herodotus): 12-20 тижнів.