Back to Blog

Platform / B07

MERX Güvenlik Mimarisi: Fonlarınız Nasıl Korunur

Bir platform finansal işlemleri yönettiğinde, güvenlik bir özellik değildir - her şeyin oturduğu temeldir. Tek bir zafiyet kullanıcı güvenini kalıcı olarak yok edebilir. MERX'te güvenlik hususları, ilk günden itibaren her mimari kararı şekillendirmiştir; sonradan eklenen bir düşünce değil.

Bu makale MERX'in güvenlik mimarisini detaylandırır: fonlar nasıl korunur, veri bütünlüğü nasıl sağlanır, sistem yaygın saldırı vektörlerine nasıl karşı koyar ve platformu esnek kılan tasarım ilkeleri.


İlke 1: Özel Anahtarların Saklanmaması

MERX hiçbir zaman TRON özel anahtarlarınızı tutmaz, depolamaz veya erişim sağlamaz. Bu, tüm bir saldırı sınıfını ortadan kaldıran temel bir tasarım kararıdır.

Nasıl Çalışır

MERX'i enerji satın almak için kullandığınızda, delegasyon sağlayıcının adresinden sizin adresinize gerçekleşir. MERX bu işlemi yönetir ancak hiçbir zaman özel anahtarınıza erişmesi gerekmez. Özel anahtarınız cihazınızda, donanım cüzdanınızda veya yönettiğiniz başka yerde kalır.

Akış şöyledir:

1. MERX'e şunu söylersiniz: "65.000 enerjiyi TMyAddress'e deleget et"
2. MERX sağlayıcıya şunu söyler: "65.000 enerjiyi TMyAddress'e deleget et"
3. Sağlayıcı TProviderAddress'ten TMyAddress'e delegasyon yapar
4. MERX delegasyonu zincirde doğrular
5. Özel anahtarınız hiçbir zaman işin içinde değildir

Neden Bu Önemli

MERX'in güvenliği ihlal edilse, saldırganlar TRX veya jetonlarınızı çalamazlar çünkü MERX'in anahtarlarınız yok. Bunu, tokenleri platform tarafından kontrol edilen bir adrese yatırmanız gereken platformlarla karşılaştırın - bu platformlar anahtarlarınızı (veya fonlarınıza giden anahtarları) tutar, bu da tek bir başarısızlık noktası oluşturur.

Hazine İstisnası

MERX depozito almak ve para çekme işlemlerini işlemek için kendi hazine adresini yönetir. Hazine özel anahtarı, Docker secret olarak saklanır ve yalnızca treasury-signer hizmeti tarafından erişilebilir. API hizmetine, web ön ucuna veya başka herhangi bir bileşene hiçbir zaman açıklanmaz. Bu izolasyon hakkında aşağıda daha fazla bilgi.


İlke 2: Çift Giriş Defteri

MERX'teki her finansal işlem, eşleştirilmiş bir defter girişi oluşturur. Bu, son 700 yılın her bankası ve finansal kurumu tarafından kullanılan aynı muhasebe ilkesidir. Çalışır.

Nasıl Çalışır

Her işlem iki giriş oluşturur: bir borç ve bir alacak. Tüm borçların toplamı her zaman tüm alacakların toplamına eşittir. Eğer yoksa, bir şey yanlış demektir ve sistem bunu hemen algılar.

-- Sipariş ödeme örneği
INSERT INTO ledger (account_id, type, amount_sun, direction)
VALUES
  ($user_id, 'ORDER_PAYMENT', 5525000, 'DEBIT'),
  ($provider_settlement, 'ORDER_PAYMENT', 5525000, 'CREDIT');

Değişmezlik

Defter kayıtları hiçbir zaman güncellenmez veya silinmez. Bir işlemin tersine çevrilmesi gerekirse (örn. geri ödeme), ters yönde yeni bir defter girişi oluşturulur:

-- Geri ödeme: yeni giriş, orijinal giriş kalır
INSERT INTO ledger (account_id, type, amount_sun, direction, reference_id)
VALUES
  ($user_id, 'REFUND', 5525000, 'CREDIT', $original_order_id),
  ($provider_settlement, 'REFUND', 5525000, 'DEBIT', $original_order_id);

Orijinal borç girişi hiçbir zaman değiştirilmez. Geri ödeme alacak girişi açıkça orijinal girişe referans verir, tam bir denetim izi oluşturur.

Neden Bu Önemli

Saldırganlar uygulama katmanının güvenliğini ihlal eder ve kullanıcının bakiyesini artırmaya çalışırsa, defter girişleri dengelenmiş olmayacaktır. Düzenli mutabakat kontrolleri bunu hemen algılar:

-- Mutabakat sorgusu: her zaman 0 döndürmelidir
SELECT SUM(CASE direction
  WHEN 'DEBIT' THEN amount_sun
  WHEN 'CREDIT' THEN -amount_sun
END) as imbalance
FROM ledger;

Sıfır olmayan herhangi bir sonuç anında bir uyarı ve araştırma tetikler.


İlke 3: Atomik Bakiye İşlemleri

Her bakiye değişikliği, yarış koşullarını önlemek için SELECT FOR UPDATE kullanır. Bu isteğe bağlı değildir - veritabanı düzeyinde uygulanır.

Yarış Koşulu Sorunu

Uygun kilitlemek olmadan, 10 TRX bakiyesi olan bir kullanıcı 8 TRX'lik iki eş zamanlı sipariş sunabilir:

Thread 1: SELECT balance WHERE user_id = 1    -> 10 TRX
Thread 2: SELECT balance WHERE user_id = 1    -> 10 TRX
Thread 1: balance (10) >= order (8)? EVET     -> devam et
Thread 2: balance (10) >= order (8)? EVET     -> devam et
Thread 1: UPDATE balance = 10 - 8 = 2 TRX
Thread 2: UPDATE balance = 10 - 8 = 2 TRX

Sonuç: Kullanıcı 10 TRX'le 16 TRX harcadı

Çözüm

BEGIN;

-- Satırı kilitle - ikinci işlem burada bekler
SELECT balance_sun FROM accounts
WHERE user_id = $1
FOR UPDATE;

-- Bakiyeyi kontrol et
-- Yetersiz: ROLLBACK yap
-- Yeterli: devam et

UPDATE accounts
SET balance_sun = balance_sun - $order_amount
WHERE user_id = $1
  AND balance_sun >= $order_amount;  -- UPDATE'de tekrar kontrol

COMMIT;

FOR UPDATE satır düzeyinde bir kilit alır. İkinci işlem, ilk işlem işlenene veya geri alınana kadar bekler. İlk işlem tamamlandıktan sonra (bakiye 2 TRX'ye düşer), ikinci işlem güncellenmiş bakiyeyi (2 TRX) okur ve yetersiz fon siparişini doğru şekilde reddeder.


İlke 4: Girdi Doğrulaması

Tüm girdiler işlenmeden önce Zod şemaları ile doğrulanır. Buna API istekleri, webhook yükleri, sağlayıcı yanıtları ve iç hizmet iletileri dahildir.

API Girdi Doğrulaması

const CreateOrderSchema = z.object({
  energy: z.number()
    .int('Enerji bir tamsayı olmalıdır')
    .min(10000, 'Minimum sipariş 10.000 enerjidir')
    .max(100000000, 'Maksimum sipariş 100.000.000 enerjidir'),

  targetAddress: z.string()
    .regex(/^T[1-9A-HJ-NP-Za-km-z]{33}$/, 'Geçersiz TRON adresi formatı')
    .refine(isValidTronAddress, 'Geçersiz TRON adresi sağlama toplamı'),

  duration: z.enum(['1h', '1d', '3d', '7d', '14d', '30d']),

  maxPrice: z.number()
    .positive()
    .optional(),

  idempotencyKey: z.string()
    .max(255)
    .optional()
});

Her alan türünü belirtilmiş, sınırlandırılmış ve doğrulanmıştır. Ham kullanıcı girdisi hiçbir zaman iş mantığına veya veritabanı sorgularına ulaşmaz.

SQL Enjeksiyonu Önleme

Tüm veritabanı sorguları parametreli ifadeleri kullanır. Dize birleştirme hiçbir zaman SQL oluşturmak için kullanılmaz:

// Hiçbir zaman bunu yapma:
const query = `SELECT * FROM users WHERE id = '${userId}'`;  // SQL enjeksiyonu

// Her zaman bunu yap:
const query = 'SELECT * FROM users WHERE id = $1';
const result = await db.query(query, [userId]);

Bu kod incelemesi ve linting kuralları tarafından uygulanır. Kodda ham SQL dize interpolasyonu için hiçbir mekanizma yoktur.

TRON Adresi Doğrulaması

TRON adresleri birden fazla seviyede doğrulanır:

  1. Format kontrolü: TRON adresi regex'i ile eşleşmelidir (T ile başlar, 34 karakter, base58).
  2. Sağlama toplamı doğrulaması: adres yazım hatalarını tespit eden bir sağlama toplamı içerir.
  3. Zincir üstü doğrulama (isteğe bağlı): adresi doğrulayın ve etkinleştirilip etkinleştirilmediğini onaylayın.

Enerjiyi geçersiz bir adrese göndermek kaynakları boşa harcatır ve zincirde tersine çevrilemez. Kesin doğrulama bunu önler.


İlke 5: Hizmet İzolasyonu

MERX, her biri minimal izinler ve gereksiz erişim olmadan izole edilmiş Docker kapsayıcıları seti olarak çalışır.

Kapsayıcı Mimarisi

Docker ağı:
  |
  |-- api           (port 3000, herkese açık)
  |-- price-monitor (harici port yok)
  |-- order-executor (harici port yok)
  |-- ledger        (harici port yok)
  |-- treasury-signer (harici port yok, Docker secret erişimi)
  |-- deposit-monitor (harici port yok)
  |-- withdrawal-executor (harici port yok)
  |
  |-- postgresql    (port 5432, sadece dahili)
  |-- redis         (port 6379, sadece dahili)

Temel İzolasyon Özellikleri

Neden Bu Önemli

Saldırganlar API hizmetinin (en açık bileşen) güvenliğini ihlal etseler de, şunları yapamaz:

Herhangi bir hizmet düzeyinde ihlal yapmanın hasar alanı tasarım gereği sınırlıdır.


İlke 6: Hız Sınırlandırması ve Suistimal Önleme

API Hız Sınırları

Her API uç noktasının amacına uygun hız sınırları vardır:

Genel uç noktalar (fiyatlar, sağlık):     100 istek/dakika
Doğrulanmış okumalar (siparişler, bakiye): 60 istek/dakika
Doğrulanmış yazımlar (sipariş oluştur):   30 istek/dakika
Para çekme:                                5 istek/dakika

Hız sınırları API anahtarı başına uygulanır, Redis'te kayan pencereler ile izlenir.

Para Çekme Güvenlik Önlemleri

Para çekme en yüksek riskli işlemdir (gerçek varlıkları platformdan çıkarmak). Ek güvenlik önlemleri şunları içerir:


İlke 7: Webhook Güvenliği

MERX sipariş durumu güncellemeleri, depozitolar ve diğer olaylar için webhook bildirimleri gönderir. Webhook'lar sahteciliği önlemek için HMAC-SHA256 ile imzalanır.

HMAC Webhook'ları Nasıl Çalışır

1. MERX hesaplar: HMAC-SHA256(webhook_body, your_webhook_secret)
2. MERX imzayı X-Merx-Signature başlığına ekler
3. Sunucunuz HMAC'ı aynı secret ile yeniden hesaplar
4. İmzalar eşleşirse: orijinal webhook. Yoksa: sahte, atla.

Kod'da Doğrulama

import crypto from 'crypto';

function verifyWebhook(body: string, signature: string, secret: string): boolean {
  const computed = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(computed)
  );
}

Zamanlama saldırılarını önlemek için timingSafeEqual kullanımına dikkat edin. Saf bir dize karşılaştırması (===) yanıt süresi varyasyonları aracılığıyla doğru imza hakkında bilgi sızıtacaktır.


İlke 8: Gizli Bilgiler Yönetimi

Hiçbir secret hiçbir zaman kaynak kodunda sabit kodlanmaz. Tüm hassas değerler ortam değişkenleri ve Docker secret'ları aracılığıyla yönetilir.

Ortam Değişkenleri

# .env (hiçbir zaman git'e işlenmez)
DATABASE_URL=postgresql://...
REDIS_URL=redis://...
API_JWT_SECRET=...
WEBHOOK_SIGNING_SECRET=...
TRON_API_KEY=...

Docker Secret'ları (Yüksek Hassasiyetli Değerler İçin)

Hazine özel anahtarı ortam değişkenleri için çok hassastır (günlük alınabilir veya işlem incelemesi aracılığıyla sızabilir). Docker secret olarak saklanır:

# docker-compose.yml
services:
  treasury-signer:
    secrets:
      - treasury_private_key

secrets:
  treasury_private_key:
    file: /run/secrets/treasury_key

Docker secret'ları kapsayıcı içinde dosya olarak monte edilir, yalnızca hizmet süreci tarafından okunabilir. Ortam değişkeni listelerinde, kapsayıcı inceleme çıktısında veya günlüklerde görünmez.

Git Koruması

.gitignore dosyası tüm hassas dosyaları hariç tutar:

.env
*.key
*.pem
secrets/

Bu ilk commit'ten önce kurulur, değil sonra.


İzleme ve Olaylara Yanıt

Otomatik Uyarılar

Aşağıdaki koşullar anında uyarı tetikler:

Denetim Günlüğü

Her güvenlikle ilgili işlem yapılandırılmış veriler ile günlüğe kaydedilir:

{
  "event": "withdrawal_requested",
  "user_id": "usr_abc123",
  "amount_sun": 10000000,
  "destination": "TAddress...",
  "ip": "203.0.113.45",
  "timestamp": "2026-03-30T12:00:00Z"
}

Günlükler adli analiz ve uyum için saklanır. Bunlar yalnızca ekleme ve uygulama verilerinden ayrı olarak saklanır.


Sonuç

MERX'teki güvenlik, tek bir özellik değildir, ancak birbirine bağlı ilkeler kümesidir: anahtar saklama değil, çift giriş muhasebesi, atomik bakiye işlemleri, katı girdi doğrulaması, hizmet izolasyonu, hız sınırlandırması, imzalı webhook'lar ve uygun secret yönetimi. Her ilke belirli bir tehdit vektörünü ele alır ve birlikte, herhangi bir bileşenin güvenliğini ihlal etmenin sistemi tehlikeye atmadığı derinlemesine savunma mimarisi yaratırlar.

Hiçbir sistem, tam korunaklı değildir. Fakat güvenliği mimari içine entegre ederek tasarlararak - daha sonra düzeltmek yerine - MERX saldırı yüzeyini en aza indirir ve saldırganın zarar vermesi için ödeyeceği maliyeti arttırır.

Açık kaynak bileşenleri inceleyin: https://github.com/Hovsteder/merx-sdk-js, https://github.com/Hovsteder/merx-sdk-python, https://github.com/Hovsteder/merx-mcp.

MERX'i https://merx.exchange'de kullanmaya başlayın.


Bu makale MERX teknik serisinin bir parçasıdır. MERX, güvenliği temel bir gereksinim olarak tasarlanan ilk blokzincir kaynakları değişimidir, yan düşünce değil.

Şimdi AI ile Deneyin

MERX'i Claude Desktop'a veya herhangi bir MCP uyumlu istemciye ekleyin -- sıfır kurulum, salt-okunur araçlar için API anahtarı gerekmez:

{
  "mcpServers": {
    "merx": {
      "url": "https://merx.exchange/mcp/sse"
    }
  }
}

AI aracınızdan şunu sorun: "TRON enerjisinin en ucuz fiyatı şu anda nedir?" ve bağlantılı tüm sağlayıcılardan canlı fiyatlar alın.

Tam MCP belgeleri: merx.exchange/docs/tools/mcp-server


All Articles