#!/usr/bin/env python3 """ sovanaglobus.py — Uber для океана (Sovanaglobus Protocol) Книга Монтана, Глава 04: > "Бот делает убер между всеми участниками цепочки фрахтования морских. > (Грузовладельцев, Судовладельцев, Агентов и тд)" > "Uber убрал диспетчера такси. #Сованаглобус убирает посредника в фрахте." > "#Сованаглобус = протокол, не продукт. > Как Bitcoin Core — бесплатный софт." Sovanaglobus — это ПРОТОКОЛ, не платформа: - P2P фрахтование без брокера - Любые валюты (полная совместимость с фиатом) - Общий язык измерения — время """ from dataclasses import dataclass, field from datetime import datetime, timezone from decimal import Decimal from typing import Dict, List, Optional, Set from enum import Enum import hashlib class ParticipantType(Enum): """Типы участников рынка фрахта.""" CARGO_OWNER = "cargo_owner" # Грузовладелец SHIP_OWNER = "ship_owner" # Судовладелец AGENT = "agent" # Агент PORT = "port" # Порт BROKER = "broker" # Брокер (устраняется) class CargoType(Enum): """Типы грузов.""" BULK = "bulk" # Навалочный (зерно, уголь) CONTAINER = "container" # Контейнерный TANKER = "tanker" # Наливной (нефть, газ) GENERAL = "general" # Генеральный REEFER = "reefer" # Рефрижераторный @dataclass class Participant: """Участник протокола.""" node_id: str # Montana node ID participant_type: ParticipantType name: str montana_address: str # mt... адрес accepted_currencies: List[str] = field(default_factory=lambda: ["USD", "EUR", "Ɉ"]) def to_dict(self) -> dict: return { "node_id": self.node_id, "type": self.participant_type.value, "name": self.name, "address": self.montana_address, "currencies": self.accepted_currencies } @dataclass class FreightRequest: """Запрос на фрахт (от грузовладельца).""" request_id: str cargo_owner: str # node_id грузовладельца cargo_type: CargoType origin_port: str destination_port: str volume: str # "50,000 MT" / "500 TEU" laydays: str # Период погрузки currency: str # Предпочтительная валюта created_at: str def to_hash(self) -> str: data = f"{self.request_id}:{self.cargo_owner}:{self.origin_port}:{self.destination_port}" return hashlib.sha256(data.encode()).hexdigest() @dataclass class FreightOffer: """Предложение фрахта (от судовладельца).""" offer_id: str request_id: str # К какому запросу ship_owner: str # node_id судовладельца vessel_name: str vessel_imo: str rate: Decimal # Ставка currency: str # Валюта ставки eta: str # Ожидаемое прибытие created_at: str def to_hash(self) -> str: data = f"{self.offer_id}:{self.ship_owner}:{self.rate}:{self.currency}" return hashlib.sha256(data.encode()).hexdigest() @dataclass class FreightContract: """Контракт фрахтования (P2P, без брокера).""" contract_id: str request_id: str offer_id: str cargo_owner: str ship_owner: str rate: Decimal currency: str time_value_juno: Decimal # Эквивалент в Ɉ signed_at: str status: str = "active" def to_hash(self) -> str: data = f"{self.contract_id}:{self.cargo_owner}:{self.ship_owner}:{self.signed_at}" return hashlib.sha256(data.encode()).hexdigest() class SovanaglobusProtocol: """ Протокол P2P фрахтования. Книга Монтана: > "Все пользуются какой хотят валютой, также как и у Убера. > Полная привязка к фиатной системе через тех кто уже в Логистике." > "Даём ей общий язык измерения." """ VERSION = "0.1.0" # Рынок морского фрахта MARKET_SIZE = "$14-16 trillion/year" WORLD_TRADE_SHARE = "90% by volume" def __init__(self): self.participants: Dict[str, Participant] = {} self.requests: Dict[str, FreightRequest] = {} self.offers: Dict[str, FreightOffer] = {} self.contracts: Dict[str, FreightContract] = {} def register_participant( self, node_id: str, participant_type: ParticipantType, name: str, montana_address: str, currencies: List[str] = None ) -> Participant: """ Зарегистрировать участника в протоколе. Args: node_id: Montana node ID participant_type: Тип участника name: Название компании montana_address: mt... адрес currencies: Принимаемые валюты Returns: Participant """ participant = Participant( node_id=node_id, participant_type=participant_type, name=name, montana_address=montana_address, accepted_currencies=currencies or ["USD", "EUR", "Ɉ"] ) self.participants[node_id] = participant return participant def create_request( self, cargo_owner_id: str, cargo_type: CargoType, origin: str, destination: str, volume: str, laydays: str, currency: str = "USD" ) -> FreightRequest: """ Создать запрос на фрахт. Args: cargo_owner_id: node_id грузовладельца cargo_type: Тип груза origin: Порт погрузки destination: Порт выгрузки volume: Объём laydays: Период погрузки currency: Валюта Returns: FreightRequest """ if cargo_owner_id not in self.participants: raise ValueError(f"Participant not registered: {cargo_owner_id}") request_id = hashlib.sha256( f"{cargo_owner_id}:{datetime.now().isoformat()}".encode() ).hexdigest()[:16] request = FreightRequest( request_id=request_id, cargo_owner=cargo_owner_id, cargo_type=cargo_type, origin_port=origin, destination_port=destination, volume=volume, laydays=laydays, currency=currency, created_at=datetime.now(timezone.utc).isoformat() ) self.requests[request_id] = request return request def submit_offer( self, ship_owner_id: str, request_id: str, vessel_name: str, vessel_imo: str, rate: float, currency: str, eta: str ) -> FreightOffer: """ Подать предложение на запрос. Args: ship_owner_id: node_id судовладельца request_id: ID запроса vessel_name: Название судна vessel_imo: IMO номер rate: Ставка currency: Валюта eta: Ожидаемое прибытие Returns: FreightOffer """ if request_id not in self.requests: raise ValueError(f"Request not found: {request_id}") offer_id = hashlib.sha256( f"{ship_owner_id}:{request_id}:{datetime.now().isoformat()}".encode() ).hexdigest()[:16] offer = FreightOffer( offer_id=offer_id, request_id=request_id, ship_owner=ship_owner_id, vessel_name=vessel_name, vessel_imo=vessel_imo, rate=Decimal(str(rate)), currency=currency, eta=eta, created_at=datetime.now(timezone.utc).isoformat() ) self.offers[offer_id] = offer return offer def match_and_sign( self, request_id: str, offer_id: str ) -> FreightContract: """ Сопоставить и подписать контракт (P2P, без брокера). Args: request_id: ID запроса offer_id: ID предложения Returns: FreightContract """ request = self.requests.get(request_id) offer = self.offers.get(offer_id) if not request or not offer: raise ValueError("Request or offer not found") if offer.request_id != request_id: raise ValueError("Offer does not match request") contract_id = hashlib.sha256( f"{request_id}:{offer_id}:{datetime.now().isoformat()}".encode() ).hexdigest()[:16] # Конвертация в Ɉ (через Beeple benchmark) # $0.16/sec = базовая ставка # Примерная конверсия: rate / 0.16 * estimated_voyage_seconds estimated_days = 14 # Типичный рейс time_value = offer.rate / Decimal("0.16") * Decimal(estimated_days * 86400) contract = FreightContract( contract_id=contract_id, request_id=request_id, offer_id=offer_id, cargo_owner=request.cargo_owner, ship_owner=offer.ship_owner, rate=offer.rate, currency=offer.currency, time_value_juno=time_value, signed_at=datetime.now(timezone.utc).isoformat() ) self.contracts[contract_id] = contract return contract def get_protocol_stats(self) -> Dict: """Статистика протокола.""" return { "version": self.VERSION, "market_size": self.MARKET_SIZE, "world_trade_share": self.WORLD_TRADE_SHARE, "participants": len(self.participants), "active_requests": len(self.requests), "active_offers": len(self.offers), "signed_contracts": len(self.contracts), "broker_eliminated": True, "common_measure": "Time (Ɉ)" } # ═══════════════════════════════════════════════════════════════════════════════ # DEMO # ═══════════════════════════════════════════════════════════════════════════════ if __name__ == "__main__": protocol = SovanaglobusProtocol() print("=" * 60) print("SOVANAGLOBUS — Uber для океана") print("=" * 60) print("\n'Протокол, не продукт. Как Bitcoin Core.'") # Регистрация участников print("\n--- РЕГИСТРАЦИЯ УЧАСТНИКОВ ---") cargo_owner = protocol.register_participant( node_id="node_cargo_001", participant_type=ParticipantType.CARGO_OWNER, name="Grain Trading LLC", montana_address="mt1234567890abcdef1234567890abcdef12345678" ) print(f"Грузовладелец: {cargo_owner.name}") ship_owner = protocol.register_participant( node_id="node_ship_001", participant_type=ParticipantType.SHIP_OWNER, name="Baltic Shipping Co", montana_address="mtabcdef1234567890abcdef1234567890abcdef12" ) print(f"Судовладелец: {ship_owner.name}") # Запрос на фрахт print("\n--- ЗАПРОС НА ФРАХТ ---") request = protocol.create_request( cargo_owner_id="node_cargo_001", cargo_type=CargoType.BULK, origin="Novorossiysk", destination="Rotterdam", volume="50,000 MT", laydays="01-05 Feb 2026", currency="USD" ) print(f"ID: {request.request_id}") print(f"Маршрут: {request.origin_port} → {request.destination_port}") print(f"Груз: {request.cargo_type.value}, {request.volume}") # Предложение от судовладельца print("\n--- ПРЕДЛОЖЕНИЕ ---") offer = protocol.submit_offer( ship_owner_id="node_ship_001", request_id=request.request_id, vessel_name="MV BALTIC PRIDE", vessel_imo="9876543", rate=450000, currency="USD", eta="2026-02-01" ) print(f"Судно: {offer.vessel_name}") print(f"Ставка: ${offer.rate:,.0f}") # P2P контракт (без брокера!) print("\n--- P2P КОНТРАКТ (БЕЗ БРОКЕРА) ---") contract = protocol.match_and_sign(request.request_id, offer.offer_id) print(f"Contract ID: {contract.contract_id}") print(f"Ставка: ${contract.rate:,.0f} ({contract.currency})") print(f"Эквивалент в Ɉ: {contract.time_value_juno:,.0f}") print(f"Брокер: НЕТ (P2P)") # Статистика print("\n--- СТАТИСТИКА ПРОТОКОЛА ---") stats = protocol.get_protocol_stats() print(f"Рынок: {stats['market_size']}") print(f"Доля мировой торговли: {stats['world_trade_share']}") print(f"Участников: {stats['participants']}") print(f"Брокер устранён: {'ДА' if stats['broker_eliminated'] else 'НЕТ'}") print(f"Общая мера: {stats['common_measure']}") print("\n" + "=" * 60) print("'Uber убрал диспетчера. Sovanaglobus убирает брокера.'") print("=" * 60)