Розробка блокчейн-рішення для логістики

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

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

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

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

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

Розробка блокчейн-рішення для логістики

Логістика — один із небагатьох секторів, де блокчейн дає реальне преимущество над традиційними базами даних. Причина: у ланцюгу поставок беруть участь множество незалежних сторін (виробник, експедитор, таможня, порт, перевозник, одержувач), кожна ведеться власний облік, і рекончиляція між ними займає дні та вимагає дорогих посередників. TradeLens (Maersk + IBM), Morpheus.Network, CargoX — реальні приклади. Блокчейн тут не «технологія заради технології», а shared ledger для мультисторонної системи без єдиного доверенного центру.

Що конкретно вирішує блокчейн у логістиці

Три проблеми, які коштують реальних грошей:

Підлінність документів: Bill of Lading — ключовий документ у морській логістиці. Традиційно — паперовий, передається курʼєром. Електронний B/L (eBL) давно існує, але централізовані платформи (essDOCS, Bolero) вимагають довіри до оператора. CargoX реалізує B/L як NFT (ERC-721) на Ethereum — ownership трансферабелен on-chain без посередника.

Прозорість умов угоди: смарт-контракт-escrow: оплата висвобджується автоматично при підтвердженні доставки. Не потрібні банківські гарантії або аккредитиви для невеликих угод.

Трекинг та provenance: для фармацевтики, люкса, продовольства — критична верифікація origin та ланцюга зберігання (температура, вологість). IoT-сенсори + блокчейн = неізмінний audit trail.

Архітектура документообороту

Bill of Lading як NFT

contract ElectronicBillOfLading is ERC721, AccessControl {
    bytes32 public constant CARRIER_ROLE = keccak256("CARRIER_ROLE");
    bytes32 public constant CUSTOMS_ROLE = keccak256("CUSTOMS_ROLE");
    
    struct ShipmentData {
        string shipmentId;          // зовнішній ID з TMS
        address shipper;
        address consignee;
        string portOfLoading;
        string portOfDischarge;
        string cargoDescription;
        uint256 quantity;
        string unit;                // TEU, tonnes, pallets
        uint256 issuedAt;
        ShipmentStatus status;
        bytes32 dataHash;          // хеш повного документу в IPFS
    }
    
    enum ShipmentStatus {
        Issued,
        InTransit,
        ArrivedAtPort,
        CustomsCleared,
        Delivered,
        Surrendered
    }
    
    mapping(uint256 => ShipmentData) public shipments;
    mapping(uint256 => string[]) public statusHistory; // лог змін статусу
    
    uint256 private _tokenIdCounter;
    
    function issueBL(
        address consignee,
        string calldata shipmentId,
        string calldata portOfLoading,
        string calldata portOfDischarge,
        string calldata cargoDescription,
        uint256 quantity,
        string calldata unit,
        bytes32 dataHash
    ) external onlyRole(CARRIER_ROLE) returns (uint256) {
        uint256 tokenId = ++_tokenIdCounter;
        
        _mint(consignee, tokenId);
        
        shipments[tokenId] = ShipmentData({
            shipmentId: shipmentId,
            shipper: msg.sender,
            consignee: consignee,
            portOfLoading: portOfLoading,
            portOfDischarge: portOfDischarge,
            cargoDescription: cargoDescription,
            quantity: quantity,
            unit: unit,
            issuedAt: block.timestamp,
            status: ShipmentStatus.Issued,
            dataHash: dataHash
        });
        
        emit BLIssued(tokenId, consignee, shipmentId);
        return tokenId;
    }
    
    function updateStatus(
        uint256 tokenId,
        ShipmentStatus newStatus,
        string calldata note
    ) external {
        ShipmentData storage shipment = shipments[tokenId];
        
        // Перевірка ролей для кожного переходу
        if (newStatus == ShipmentStatus.CustomsCleared) {
            require(hasRole(CUSTOMS_ROLE, msg.sender), "Only customs");
        } else if (newStatus == ShipmentStatus.Delivered) {
            require(ownerOf(tokenId) == msg.sender, "Only consignee");
        } else {
            require(hasRole(CARRIER_ROLE, msg.sender), "Only carrier");
        }
        
        ShipmentStatus prevStatus = shipment.status;
        shipment.status = newStatus;
        statusHistory[tokenId].push(string(abi.encodePacked(
            Strings.toString(block.timestamp), ":", note
        )));
        
        emit StatusUpdated(tokenId, prevStatus, newStatus, msg.sender);
    }
    
    // Override transfer — B/L може передаватися тільки при певних статусах
    function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) 
        internal override 
    {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
        
        if (from != address(0)) { // не mint
            ShipmentStatus status = shipments[tokenId].status;
            require(
                status == ShipmentStatus.Issued || status == ShipmentStatus.InTransit,
                "BL not transferable in current status"
            );
        }
    }
}

Escrow для платежів

Оплата заморожена в смарт-контракті до підтвердження доставки:

contract ShipmentEscrow {
    enum EscrowState { Created, Funded, Released, Disputed, Refunded }
    
    struct Escrow {
        address buyer;
        address seller;
        address carrier;
        uint256 amount;
        address token;              // USDC або інший stablecoin
        uint256 blTokenId;          // ID B/L NFT
        address blContract;
        EscrowState state;
        uint256 releaseDeadline;   // якщо немає dispute до deadline — авто-release
    }
    
    mapping(bytes32 => Escrow) public escrows;
    
    function createEscrow(
        address seller,
        address carrier,
        uint256 amount,
        address token,
        uint256 blTokenId,
        address blContract,
        uint256 deliveryDeadline
    ) external returns (bytes32 escrowId) {
        escrowId = keccak256(abi.encodePacked(msg.sender, seller, blTokenId, block.timestamp));
        
        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
        
        escrows[escrowId] = Escrow({
            buyer: msg.sender,
            seller: seller,
            carrier: carrier,
            amount: amount,
            token: token,
            blTokenId: blTokenId,
            blContract: blContract,
            state: EscrowState.Funded,
            releaseDeadline: deliveryDeadline + 7 days // буфер для dispute
        });
    }
    
    function confirmDelivery(bytes32 escrowId) external {
        Escrow storage escrow = escrows[escrowId];
        require(msg.sender == escrow.buyer, "Only buyer");
        require(escrow.state == EscrowState.Funded, "Wrong state");
        
        // Перевіряємо що B/L має статус Delivered
        ElectronicBillOfLading bl = ElectronicBillOfLading(escrow.blContract);
        require(
            bl.shipments(escrow.blTokenId).status == ElectronicBillOfLading.ShipmentStatus.Delivered,
            "Not delivered on-chain"
        );
        
        escrow.state = EscrowState.Released;
        IERC20(escrow.token).safeTransfer(escrow.seller, escrow.amount);
    }
}

IoT-інтеграція: дані з датчиків в блокчейн

Для cold chain (фармацевтика, продукти) важлива верифікація умов зберігання. IoT → блокчейн вимагає вирішення проблеми oracle: смарт-контракт не може отримати дані з фізичних датчиків напрямки.

Архітектура IoT oracle

IoT датчики (температура, вологість, GPS)
    ↓ MQTT / LoRaWAN
IoT шлюз (Raspberry Pi / промисловий гейт)
    ↓ підписані пакети даних
Oracle сервіс (Chainlink Functions або власний)
    ↓ on-chain транзакція
Смарт-контракт (запис телеметрії)
contract ShipmentTelemetry {
    struct TelemetryRecord {
        uint256 timestamp;
        int16 temperature;      // у десятих долях градуса (156 = 15.6°C)
        uint16 humidity;        // у десятих процента
        int32 latitude;         // у мікрастепенях
        int32 longitude;
        address oracle;         // хто підписав дані
    }
    
    mapping(uint256 => TelemetryRecord[]) public telemetry; // tokenId => records
    mapping(uint256 => bool) public conditionViolated;     // були ли нарушення
    
    // Допустимі діапазони для вантажу
    struct ConditionRequirements {
        int16 minTemp;
        int16 maxTemp;
        uint16 maxHumidity;
    }
    mapping(uint256 => ConditionRequirements) public requirements;
    
    function submitTelemetry(
        uint256 shipmentTokenId,
        int16 temperature,
        uint16 humidity,
        int32 lat,
        int32 lon,
        bytes calldata oracleSignature
    ) external {
        // Верифікуємо підпис oracle
        bytes32 dataHash = keccak256(abi.encodePacked(
            shipmentTokenId, temperature, humidity, lat, lon, block.timestamp / 300 // 5-мін окно
        ));
        address signer = ECDSA.recover(dataHash.toEthSignedMessageHash(), oracleSignature);
        require(isApprovedOracle(signer), "Unauthorized oracle");
        
        telemetry[shipmentTokenId].push(TelemetryRecord({
            timestamp: block.timestamp,
            temperature: temperature,
            humidity: humidity,
            latitude: lat,
            longitude: lon,
            oracle: signer
        }));
        
        // Перевіряємо нарушення умов
        ConditionRequirements memory req = requirements[shipmentTokenId];
        if (temperature < req.minTemp || temperature > req.maxTemp || humidity > req.maxHumidity) {
            conditionViolated[shipmentTokenId] = true;
            emit ConditionViolation(shipmentTokenId, temperature, humidity, block.timestamp);
        }
    }
}

Вибір блокчейну для логістики

Публічний блокчейн (Polygon, Arbitrum): максимальна откритість, permissionless учасники, токенізація B/L з DeFi інтеграцією. Мінуси: gas, публічність транзакцій (конкуренти бачать обсяги).

Enterprise blockchain (Hyperledger Fabric, R3 Corda): приватні дані, permissioned учасники, немає газу. Мінуси: немає токенізації, немає DeFi composability, висока вартість нод.

Hybrid: приватні дані в Fabric, хеші в публічний блокчейн для notarization. Складніше в розробці, але поєднує переваги обох.

Для B2B логістичного проекту з відомими учасниками — Hyperledger Fabric або Polygon з приватними транзакціями (zk-based). Для відкритого протоколу з токенізацією — Polygon або Arbitrum.

Інтеграція з існуючими системами

Логістичні TMS (Transportation Management Systems), ERP (SAP, Oracle TMS) мають REST/SOAP API. Інтеграційний шар:

class LogisticsIntegration {
  private web3Provider: Provider;
  private blContract: ElectronicBillOfLading;
  
  // Webhook від TMS при зміні статусу вантажу
  async handleTMSStatusUpdate(event: TMSEvent) {
    const { shipmentId, newStatus, timestamp, operator } = event;
    
    const tokenId = await this.getTokenIdByShipmentId(shipmentId);
    const onChainStatus = this.mapTMSStatusToOnChain(newStatus);
    
    // Відправляємо транзакцію
    const tx = await this.blContract.updateStatus(
      tokenId,
      onChainStatus,
      `TMS update: ${newStatus} at ${timestamp}`
    );
    
    await tx.wait();
    
    // Оновлюємо локальну БД
    await this.db.shipments.update({
      where: { shipmentId },
      data: { lastTxHash: tx.hash, onChainStatus },
    });
  }
}

Стек розробки

Компонент Технологія
B/L контракти Solidity + ERC-721 + Foundry
Escrow Solidity + OpenZeppelin
IoT oracle Chainlink Functions або власний oracle з HSM підпис
Backend API Node.js/TypeScript + Fastify
Документи IPFS + AES encryption для приватних документів
TMS інтеграція REST webhooks + message queue (RabbitMQ)
Frontend Next.js + wagmi + shadcn

Графік

MVP (B/L NFT + базовий трекинг статусів + простий escrow): 6–8 тижнів.

Production з IoT-інтеграцією, мультистороним workflow, TMS інтеграцією та audit reporting: 4–6 місяців.

Ключова складність не технічна, а організаційна: всі сторони ланцюга поставок повинні прийняти систему. Технічна інтеграція з кожним учасником додає 2–4 тижні роботи.