Uruchomienie koparki kryptowalut o mocy 50 kW to scenariusz graniczny pomiędzy domowym „gniazdkiem” a komercyjnym centrum danych. Z jednej strony, 50 kW aktywnego obciążenia można jeszcze podpiąć do małego lokalu komercyjnego lub obiektu prywatnego z własną stacją transformatorową. Z drugiej strony to już około 14–15 nowoczesnych koparek ASIC, z których każda generuje do 3.5 kW ciepła, pobiera od 15 do 16 amperów na jednej fazie i wymaga przetłoczenia od 600 do 800 metrów sześciennych powietrza na godzinę.
Ten materiał to konkretny poradnik dotyczący projektowania, zakupu sprzętu, instalacji elektrycznej, chłodzenia i automatyzacji farmy górniczej o mocy 50 kW. Bez lania wody, abstrakcyjnych rozważań i akademickiego gadania - same suche liczby, hardware, kable, profile gruntowe i sprawdzone skrypty monitorujące.
1. Parametry wejściowe i infrastruktura elektryczna
Fundamentem każdego biznesu kryptowalutowego jest stawka za kilowatogodzinę oraz niezawodność stacji transformatorowej. Przy stałym obciążeniu 50 kW przez całą dobę, znamionowy prąd Twojego zabezpieczenia głównego musi być obliczony z 20-procentowym zapasem (zgodnie ze standardami NFPA/IEC dla obciążeń ciągłych).
I_total = P / (√3 · U · cosφ) = 50000 / (√3 · 380 · 0.95) ≈ 79.8 A
Uwzględniając współczynnik zapasu 1.25, wyłącznik główny musi być dobrany na minimum 100A (trójfazowy).
Specyfikacja rozdzielnicy głównej (RG 50 kW)
- Wyłącznik główny: 3P 100A (charakterystyka C, zdolność wyłączalności min. 10 kA, np. Schneider Electric Acti9 lub ABB S200).
- Symetryzacja faz: 3 fazy L1, L2, L3 rozłożone ściśle równomiernie po 5 urządzeń na fazę (przy 15 urządzeniach), aby wyeliminować niezbalansowanie faz i prąd w przewodzie neutralnym.
- Linia kablowa od stacji do RG: Kabel miedziany YDY / YnDY 4x25 mm² lub aluminiowy AALSt / YAKY 4x50 mm² przy układać w wykopie (z uwzględnieniem spadku napięcia poniżej 2% na dystansie 50 metrów).
- Zabezpieczenie linii grupowych: Dla każdej koparki ASIC osobny wyłącznik nadprądowy 2P 20A (charakterystyka C) + kabel YDYp 3x2.5 mm² (miedziany, o zwiększonej odporności ogniowej, z podwójną izolacją).
- Uziemienie: Układ uziemienia TN-S lub TN-C-S o rezystancji nie większej niż 4 omy (składający się z 3 miedzianych szpil/kątowników o długości 2.5 m, wbijanych w układzie trójkąta i spawanych płaskownikiem 40x4 mm).
2. Dobór sprzętu i CAPEX (Nakłady inwestycyjne)
Do kalkulacji bierzemy rynkowy standard branżowy – serie Bitmain Antminer S19k Pro / S21 lub MicroBT Whatsminer M50/M60. Aby idealnie zagospodarować 50 kW, optymalnie jest wziąć 14 sztuk Antminerów S21 (200 TH/s) o standardowym poborze około 3500 W na urządzenie.
- Łączny hashrate: 14 · 200 TH/s = 2800 TH/s = 2.8 PH/s
- Łączny pobór mocy: 14 · 3500 W = 49 kW (mieści się w limicie 50 kW z uwzględnieniem zapasu na wentylację).
Tabela nakładów inwestycyjnych (CAPEX)
| Nazwa wydatku | Specyfikacja / Szczegóły | Ilość | Cena jedn. ($) | Razem ($) |
|---|---|---|---|---|
| Koparki ASIC | Antminer S21 200 TH/s (3500W) | 14 szt. | 3,800 | 53,200 |
| Główna rozdzielnica (RG) | Wyłączniki ABB/SE, styczniki, woltomierze, OSP | 1 kpl. | 1,200 | 1,200 |
| Okablowanie | 3x2.5, korytka kablowe, listwy PDU PDU-C19 (16A) | 14 linii | 70 | 980 |
| Chłodzenie / Wentylacja | Przemysłowy wentylator osiowy (12 000 m³/h) + falownik | 2 szt. | 850 | 1,700 |
| Filtracja nawiewna | Rama, filtry G4/F7 (pyłochłonne), żaluzje | 1 kpl. | 600 | 600 |
| Infrastruktura sieciowa | Switch zarządzalny Mikrotik 24-portowy, router 4G/WAN, UPS | 1 kpl. | 550 | 550 |
| Układ uziemienia | Zestaw uziemiający, montaż, pomiary | 1 kpl. | 350 | 350 |
| Prace montażowe | Montaż regałów, rozкладka elektryki, uruchomienie | - | - | 1,500 |
| RAZEM CAPEX | $60,080 |
3. Chłodzenie i wentylacja: Obliczenia termodynamiczne
Główny błąd początkujących to montaż klimatyzatora domowego. Klimatyzator usuwa wilgoć i obniża temperaturę za pomocą cyklu freonowego, ale przy 50 kW ciepła potrzebowałbyś urządzenia o mocy 150 000 BTU, które samo pożre dodatkowe 15–18 kW energii elektrycznej.
Koparki kryptowalut chłodzi się wyłącznie za pomocą przepływowej wentylacji nawiewno-wywiewnej (przedmuchu powietrzem).
Obliczenie wydatku powietrza
Wzór na wymagany przepływ powietrza:
Q = P_dissip / (ρ · c_p · ΔT)
Gdzie:
- P_dissip = 49000 W (moc wydzielanego ciepła)
- ρ = 1.2 kg/m³ (gęstość powietrza w 20°C)
- c_p = 1005 J/(кг·K) (ciepło właściwe powietrza)
- ΔT = 15°C (dopuszczalny przyrost temperatury pomiędzy nawiewem a wywiewem)
Q = 49000 / (1.2 · 1005 · 15) ≈ 2.708 m³/s = 9750 m³/h
Biorąc pod uwagę opory filtrów wstępnych (G4), należy zaplanować wentylatory o łącznej wydajności nie mniejszej niż 12 000 – 14 000 m³/h.
Podział stref (Hot/Cold Aisle)
- Korytarz zimny: Nawiew świeżego powietrza z zewnątrz przez ściany filtracyjne. Ciśnienie atmosferyczne w tej strefie jest lekko podwyższone.
4. OPEX i koszty operacyjne (Rozliczenie miesięczne)
Koszty operacyjne składają się z trzech kluczowych elementów: energii elektrycznej, najmu lokalu, internetu oraz serwisu technicznego.
Przyjmijmy średnią stawkę za prąd komercyjny na poziomie $0.07 za kWh.
Miesięczne zużycie energii elektrycznej
- Pobór godzinowy: 49 kW (koparki) + 1.5 kW (wentylacja i sieć) = 50.5 kW
- Pobór dobowy: 50.5 · 24 = 1212 kWh
- Pobór miesięczny (30.5 dnia): 1212 · 30.5 = 36 966 kWh
- Miesięczny koszt prądu: 36 966 · $0.07 = $2,587.62
Stałe wydatki miesięczne (OPEX)
| Pozycja kosztowa | Opis | Kwota ($) |
|---|---|---|
| Energia elektryczna | 36 966 kWh po $0.07/kWh | 2,587.62 |
| Najem lokalu | Pomieszczenie przemysłowe/magazynowe 20-30 m² | 300.00 |
| Łącze i internet | Główne łącze światłowodowe + zapasowe (4G) | 40.00 |
| Fundusz serwisowy / Części zamienne | Wymiana wentylatorów ASIC, czyszczenie filtrów, materiały eksploatacyjne | 150.00 |
| RAZEM OPEX / mies. | $3,077.62 |
5. Rentowność, zwrot z inwestycji (ROI) oraz model finansowy
Do obliczenia przychodów wykorzystujemy wskaźniki trudności sieci Bitcoin oraz nagrody za blok z 2026 roku. Załóżmy, że 1 TH/s przynosi dziennie około $0.042 (bez odliczonego kosztu prądu, przy kursie BTC ~$65,000).
Kalkulacja przychodów (Revenue)
- Łączny hashrate: 2800 TH/s
- Przychód dzienny: 2800 · $0.042 = $117.60
- Przychód miesięczny (30.5 dnia): $117.60 · 30.5 = $3,586.80
Zysk netto (EBITDA / Net Profit)
- Net Profit/mo = Przychód ($3,586.80) - OPEX ($3,077.62) = $509.18 (przy wyższym zysku na TH/s kwota rośnie; przy kursie $90,000/BTC zysk skaluje się proporcjonalnie).
Ważna uwaga dotycząca wrażliwości ROI na kurs i stawkę za prąd:
Przy cenie energii $0.05 / kWh koszt stały OPEX za prąd spadnie do $1,848.30, a zysk netto wzrośnie do $1,248.50 miesięcznie. To skraca okres zwrotu z inwestycji z dramatycznych wartości do rozsądnych 35-40 miesięcy. Kopanie na taryfie komercyjnej powyżej $0.065–0.07/kWh bez hossy na rynku lub wysokoefektywnego sprzętu wiąże się z ekstremalnie wysokim ryzykiem.
6. Automatyzacja i sterowanie: Skrypt monitorujący w Pythonie (CGMiner / CGMiner API)
Prawdziwy inżynier nie traci czasu na ręczne klikanie w interfejsach webowych 14 urządzeń. Wszystkie współczesne koparki ASIC (Antminer, Whatsminer) obsługują protokół CGMiner API (oparty na JSON przesyłanym przez gniazda TCP).
Poniżej znajduje się gotowy, wdrożeniowy skrypt w Pythonie do monitorowania puli farmy. Skrypt odpytuje wszystkie 14 urządzeń w sieci lokalnej, zbiera hashrate, temperaturę chipów, a w przypadku spadku wydajności lub przegrzania wysyła powiadomienie na Telegram.
#!/usr/bin/env python3
"""
Monitorowanie farmy koparek ASIC przez CGMiner API (port 4028).
Funkcje:
* odpytuje wszystkie urządzenia równolegle;
* Antminer (klucz "command") oraz Whatsminer (klucz "cmd") — typ definiowany w MINERS;
* alerty: brak połączenia, spadek hashrate'u, przegrzanie, brak pól temperatur;
* deduplikacja: to samo zdarzenie nie jest wysyłane częściej niż co REPEAT_MINUTES;
* powiadomienie o powrocie do normy po ustąpieniu problemu;
* potwierdzenie problemu przez CONFIRM_CYCLES kolejnych odpytań (ochrona przed fałszywymi alarmami);
* stan jest zapisywany w pliku, dzięki czemu działa poprawnie zarówno w pętli, jak i z crona (--once).
Konfiguracja przez zmienne środowiskowe:
TG_BOT_TOKEN, TG_CHAT_ID — wymagane
TEMP_THRESHOLD (domyślnie 85) — próg temperatury chipów, °C
HASHRATE_WARN_TH (domyślnie 170) — minimalny hashrate, TH/s
POLL_INTERVAL_SEC (domyślnie 60) — okres odpytywania w trybie pętli
REPEAT_MINUTES (domyślnie 60) — powtórzenie tego samego alertu
CONFIRM_CYCLES (domyślnie 2) — ile kolejnych odpytań musi wykazać problem
Uruchomienie:
python3 asic_monitor.py # pętla nieskończona
python3 asic_monitor.py --once # pojedyncze wykonanie (dla cron / systemd timer)
WAŻNE: Port 4028 musi być dostępny wyłącznie w sieci lokalnej.
Nigdy nie wystawiaj go na zewnątrz.
"""
import json
import logging
import os
import socket
import sys
import time
from concurrent.futures import ThreadPoolExecutor
import requests
# --------------------------------------------------------------------------
# Konfiguracja
# --------------------------------------------------------------------------
# (ip, typ): "antminer" lub "whatsminer"
MINERS = [(f"192.168.1.{i}", "antminer") for i in range(101, 115)] # .101 - .114
# Przykład farmy mieszanej:
# MINERS[0] = ("192.168.1.101", "whatsminer")
API_PORT = 4028
SOCKET_TIMEOUT = 3.0
TG_BOT_TOKEN = os.environ.get("TG_BOT_TOKEN", "")
TG_CHAT_ID = os.environ.get("TG_CHAT_ID", "")
TEMP_THRESHOLD = float(os.environ.get("TEMP_THRESHOLD", "85"))
HASHRATE_WARN_TH = float(os.environ.get("HASHRATE_WARN_TH", "170"))
POLL_INTERVAL_SEC = int(os.environ.get("POLL_INTERVAL_SEC", "60"))
REPEAT_MINUTES = int(os.environ.get("REPEAT_MINUTES", "60"))
CONFIRM_CYCLES = int(os.environ.get("CONFIRM_CYCLES", "2"))
STATE_FILE = os.environ.get("STATE_FILE", "asic_monitor_state.json")
# Prefiksy kluczy temperatury chipów w odpowiedzi `stats` dla Antminera.
# Sprawdź ze swoim firmware: wykonaj `stats` i zweryfikuj realne klucze.
ANTMINER_TEMP_PREFIXES = ("temp2_", "temp_chip")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
log = logging.getLogger("asic_monitor")
# --------------------------------------------------------------------------
# Telegram
# --------------------------------------------------------------------------
def send_telegram(text: str) -> bool:
"""Wysyła wiadomość bez parse_mode (dynamiczny tekst nie psuje formatowania).
Zwraca True tylko wtedy, gdy Telegram zaakceptował wiadomość."""
if not TG_BOT_TOKEN or not TG_CHAT_ID:
log.error("Brak TG_BOT_TOKEN / TG_CHAT_ID, alert nie został wysłany: %s", text)
return False
url = f"https://api.telegram.org/bot{TG_BOT_TOKEN}/sendMessage"
try:
r = requests.post(url, json={"chat_id": TG_CHAT_ID, "text": text}, timeout=10)
if not r.ok:
log.error("Telegram zwrócił %s: %s", r.status_code, r.text[:200])
return r.ok
except requests.RequestException as e:
log.error("Błąd wysyłania do Telegrama: %s", e)
return False
# --------------------------------------------------------------------------
# Obsługa CGMiner API
# --------------------------------------------------------------------------
def query_miner(ip: str, kind: str, command: str) -> dict:
"""Wysyła komendę do CGMiner API. W razie błędu zwraca {"error": "..."}."""
key = "cmd" if kind == "whatsminer" else "command"
try:
with socket.create_connection((ip, API_PORT), timeout=SOCKET_TIMEOUT) as s:
s.settimeout(SOCKET_TIMEOUT)
s.sendall(json.dumps({key: command}).encode("utf-8"))
chunks = []
while True:
chunk = s.recv(4096)
if not chunk:
break
chunks.append(chunk)
text = b"".join(chunks).decode("utf-8", errors="ignore").replace("\x00", "")
# Niektóre wersje firmware zwracają "}{" bez przecinka między obiektami
text = text.replace("}{", "},{")
return json.loads(text)
except Exception as e: # sieć, timeout, niepoprawny JSON
return {"error": f"{type(e).__name__}: {e}"}
def to_float(value):
"""Liczba lub ciąg znaków -> float, w przeciwnym razie None."""
try:
return float(value)
except (TypeError, ValueError):
return None
def get_hashrate_th(summary: dict, kind: str):
"""Hashrate w TH/s lub None, jeśli pole nie zostało znalezione."""
try:
s = summary["SUMMARY"][0]
except (KeyError, IndexError, TypeError):
return None
if kind == "whatsminer":
# MH/s -> TH/s. Średnia z 5 minut, jeśli jest dostępna, w przeciwnym razie ogólna średnia.
for key in ("MHS 5m", "MHS av"):
v = to_float(s.get(key))
if v is not None:
return v / 1_000_000.0
return None
# Antminer: GH/s -> TH/s. Unikamy "GHS 5s" (zbyt duża fluktuacja).
for key in ("rate_30m", "GHS av"):
v = to_float(s.get(key))
if v is not None:
return v / 1000.0
return None
def get_max_chip_temp(ip: str, kind: str, summary: dict):
"""Maksymalna temperatura chipów lub None, jeśli nie znaleziono pól."""
if kind == "whatsminer":
try:
s = summary["SUMMARY"][0]
except (KeyError, IndexError, TypeError):
return None
temps = [to_float(s.get(k)) for k in ("Chip Temp Max", "Temperature")]
temps = [t for t in temps if t]
return max(temps) if temps else None
stats = query_miner(ip, kind, "stats")
try:
info = stats["STATS"][1]
except (KeyError, IndexError, TypeError):
return None
temps = []
for k, v in info.items():
if k.startswith(ANTMINER_TEMP_PREFIXES):
t = to_float(v)
if t: # 0 = płyta nie zwraca wartości
temps.append(t)
return max(temps) if temps else None
# --------------------------------------------------------------------------
# Sprawdzanie pojedynczego urządzenia
# --------------------------------------------------------------------------
def check_miner(ip: str, kind: str) -> dict:
"""Zwraca {issue_key: tekst_alertu} dla aktywnych problemów."""
issues = {}
summary = query_miner(ip, kind, "summary")
if "error" in summary:
# Brak łączności: pozostałe sprawdzenia nie mają sensu
return {"offline": f"⚠️ {ip}: brak odpowiedzi z API ({summary['error']})"}
th = get_hashrate_th(summary, kind)
if th is None:
issues["parse"] = f"❌ {ip}: nie udało się pobrać hashrate'u z summary (sprawdź firmware/typ)"
elif th < HASHRATE_WARN_TH:
issues["hashrate"] = f"📉 {ip}: hashrate {th:.1f} TH/s (próg {HASHRATE_WARN_TH:.0f})"
temp = get_max_chip_temp(ip, kind, summary)
if temp is None:
issues["temp_keys"] = f"❓ {ip}: nie znaleziono pól temperatur, sprawdź klucze w stats"
elif temp > TEMP_THRESHOLD:
issues["temp"] = f"🔥 {ip}: przegrzanie, chipy {temp:.0f}°C (próg {TEMP_THRESHOLD:.0f})"
return issues
# --------------------------------------------------------------------------
# Stan i deduplikacja
# --------------------------------------------------------------------------
def load_state() -> dict:
try:
with open(STATE_FILE, encoding="utf-8") as f:
return json.load(f)
except (OSError, ValueError):
return {"sent": {}, "streak": {}}
def save_state(state: dict) -> None:
try:
tmp = STATE_FILE + ".tmp"
with open(tmp, "w", encoding="utf-8") as f:
json.dump(state, f)
os.replace(tmp, STATE_FILE)
except OSError as e:
log.error("Nie udało się zapisać stanu: %s", e)
def run_cycle(state: dict) -> None:
sent, streak = state["sent"], state["streak"]
now = time.time()
with ThreadPoolExecutor(max_workers=len(MINERS)) as pool:
results = list(pool.map(lambda m: (m[0], check_miner(*m)), MINERS))
for ip, issues in results:
# 1) aktywne problemy
for key, text in issues.items():
sid = f"{ip}|{key}"
streak[sid] = streak.get(sid, 0) + 1
if streak[sid] < CONFIRM_CYCLES:
continue
last = sent.get(sid)
if last is None or now - last >= REPEAT_MINUTES * 60:
if send_telegram(text):
sent[sid] = now
# 2) usunięte problemy
prefix = f"{ip}|"
for sid in [s for s in list(streak) if s.startswith(prefix)]:
key = sid[len(prefix):]
if key in issues:
continue
streak.pop(sid, None)
if sid in sent: # powiadamiamy o naprawie tylko wtedy, gdy wcześniej poszedł alert
if send_telegram(f"✅ {ip}: problem „{key}” został usunięty"):
sent.pop(sid, None)
ok = sum(1 for _, i in results if not i)
log.info("Odpytywanie zakończone: %d/%d bez problemów", ok, len(results))
save_state(state)
# --------------------------------------------------------------------------
def main() -> None:
state = load_state()
state.setdefault("sent", {})
state.setdefault("streak", {})
if "--once" in sys.argv:
run_cycle(state)
return
log.info("Start monitoringu: %d urządzeń, okres %d s", len(MINERS), POLL_INTERVAL_SEC)
while True:
try:
run_cycle(state)
except Exception:
log.exception("Nieobsłużony błąd w pętli odpytywania")
time.sleep(POLL_INTERVAL_SEC)
if __name__ == "__main__":
main()7. Checklista przed uruchomieniem (Odbiór inżynieryjny)
- 1. Test obciążeniowy sieci: Uruchomić nagrzewnicę przemysłową 50 kW na 4 godziny przed montażem koparek. Sprawdzić pirometrem nagrzewanie się punktów stkowych na wyłączniku głównym i szynoprądach. Temperatura styków nie powinna przekraczać 65°C.
- 2. Pomiar uziemienia: Wezwać laboratorium elektryczne, zmierzyć pętlę zwarcia faza-zerowanie oraz rezystancję rozproszenia prądu uziemienia (powinna wynosić < 4 Ω).
- 3. Kontrola nawiewu: Upewnić się, że opór filtru G4 nie generuje podciśnienia w pomieszczeniu (drzwi do korytarza zimnego powinny otwierać się bez większego wysiłku przy pracującej wyciągowi).
- 4. Konfiguracja Watchdoga: Włączyć wbudowane funkcje Hardware Auto-Reboot w firmware koparek (LUXOS, VNISH lub Stock) na wypadek utraty połączenia z pulą lub zgubienia IP.
Uruchomienie:
export TG_BOT_TOKEN="..." TG_CHAT_ID="..."
python3 asic_monitor.py8. Kwestie prawne, umowa PPA i międzynarodowa księgowość podatkowa
Uruchomienie instalacji o mocy 50 kW w jakiejkolwiek jurysdykcji wymaga oficjalnego statusu odbiorcy komercyjnego. Kopanie „na lewo” zasilane ze zwykłego gniazdka nieuchronnie skończy się pismami od zakładu energetycznego, karami za przekroczenie limitów mocy i nielegalnym poborem energii.
Struktura prawna i formy działalności
- Rejestracja spółki operacyjnej (Sp. z o.o. / LLC / Inc.): Infrastrukturę rejestruje się na standardową spółkę z ograniczoną odpowiedzialnością. Jest to konieczne do legalnego podpisania umowy najmu powierzchni oraz umowy o przyłączenie do sieci elektrycznej.
- Umowa PPA (Power Purchase Agreement): Kluczowy dokument przedsięwzięcia to komercyjna umowa sprzedaży energii elektrycznej (PPA) zawarta ze sprzedawcą z urzędu lub właścicielem stacji transformatorowej (ST). Umowa precyzuje:
- Przydzieloną moc czynną: 50 kW w III kategorii niezasilania (z dopuszczalnym ciągłym obciążeniem całodobowym).
- Miejsce dostarczenia i granicę własności: 0.4 kV na szynach zbiorczych niskiego napięcia transformatora.
- Stawki taryfowe: ustalone koszty za kWh (cel < $0.065–0.07).
- Import sprzętu (Kod celny HS 8471): Zakup koparek ASIC odbywa się na podstawie bezpośredniego kontraktu handlowego. Międzynarodowy kod taryfy celnej (HS Code) dla tego sprzętu to 8471 50 000 0 (jednostki obliczeniowe). Przy pełnej odprawie celnej opłaca się podatek VAT oraz cło importowe. Na stanie firmy pozostają zgłoszenia celne ( SAD / GTD ) oraz faktury handlowe potwierdzające legalne pochodzenie aktywów trwałego majątku.
- Księgowość i wypłata środków (Off-ramping): Zyski z kopania generowane są w BTC bezpośrednio na pulsie. Do pokrycia bieżących kosztów (OPEX: prąd, najem) wykorzystuje się korporacyjne konto instytucjonalne (Corporate Account) na giełde kryptowalut lub w biurze OTC z ukończoną procedurą KYB (Know Your Business). Pozyskany fiat trafia na rachunek bankowy spółki przelewem, co pozwala na legalne i regularne opłacanie faktur za prąd.
9. Logistyka i odbiór sprzętu
Waga 14 sztuk Antminer S21 w fabrycznych opakowaniach wynosi około 230–250 kg.
Procedura kontroli jakości (QC przy odbiorze)
- 1. Oględziny zewnętrzne: sprawdzenie plomb gwarancyjnych i stanu kartonów.
- 2. Test potrząsania (Shake-test radiatorów): podczas transportu z Chin silne wibracje mogą zerwać śruby mocujące lub odspoić pojedyncze radiatory od chipów (zwłaszcza w sprzęcie używanym). Urządzenie należy delikatnie potrząsnąć – w środku nie może być słychać grzechoczących elementów.
- 3. Pomiar rezystancji (Cold Test): przed podaniem napięcia 220V sprawdza się multimetrem, czy na szynach zasilających płyty hash nie ma zwarcia (rezystancja linii VDD musi być zgodna ze specyfikacją producenta, rzędu kilkunastu omów).
- 4. Stanowisko testowe (15 minut): uruchomienie kolejno w izolowanym obwodzie. Kontrola osiągnięcia docelowego hashrate'u (200 TH/s), odpowiedzi wszystkich 3 płytek (3/3 Boards detected) oraz braku uszkodzonych chipów (HW Errors < 0.5%).
10. Bezpieczeństwo i izolacja sieciowa
Kopalnia o mocy 50 kW to łakomy kąsek zarówno dla złodziei sprzętu, jak i hakerów (przechwycenie ruchu stratum, wstrzykiwanie złośliwego oprogramowania).
Schemat architektury sieciowej:
[ Internet (WAN) ]
&│
[ Backup 4G/LTE ]
&│
┌───────┴────────┐
│ Router / WAF │ (MikroTik / OPNsense)
│ Firewall │ ── WireGuard VPN (Tylko zdalny dostęp)
└───────┬────────┘
│ (Izolowany VLAN 10.0.10.0/24)
┌────────┼─────────────────┬─────────────────┐
│ │ │ │
[ASIC 1] [ASIC 2] ... [ASIC 14] [Węzeł Skryptu]
10.0.10.101 10.0.10.102 10.0.10.114 10.0.10.250 (Python Watchdog)
Parametry segmentu sieciowego
- Pełna izolacja od WAN: Asiki znajdują się w zamkniętym segmencie VLAN bez publicznego adresu IP.
- Zamknięty port 4028 (CGMiner API): Dostęp do portu zbierania metryk jest dozwolony wyłącznie dla adresu IP wewnętrznego serwera monitoringowego.
- Szyfrowanie Stratum/TLS: Skierowanie ruchu do puli (Stratum V2 lub Stratum over TLS) uniemożliwia podmianę adresu portfela w wyniku ataku Man-in-the-Middle (MitM) na poziomie dostawcy internetu.
11. Podsumowanie inżynierskie (Checklista wdrożeniowa)
- 1. Instalacja elektryczna: Sprawdzić przekrój kabli VVGng-LS 3x2.5 mm² dla każdego gniazda C19, dokręcić kluczem dynamometrycznym wszystkie zaciski w rozdzielnicy głównej po 48 godzinach pracy pod obciążeniem.
- 2. Wentylacja: Zmierzyć różnicę temperatur między nawiewem a wywiewem. Przy ΔT > 18°C wentylatory wyciągowe należy przełączyć na wyższe obroty za pomocą falownika (VFD).
- 3. Monitoring: Uruchomić automatyczny skrypt nadzorujący koparki z powiadamianiem w przypadku spadku hashrate poniżej 170 TH/s.
- 4. Zarządzanie ryzykiem finansowym: Kalkulować próg rentowności, uwzględniając potencjalny wzrost trudności sieci o 15–20% rocznie.