iToverDose/Yazılım· 30 MAYIS 2026 · 16:01

Etkinlik kaynağında verileri nasıl kalıcı olarak koruyabilirsiniz?

Etkinlik kaynağı (event sourcing), verilerinizi değiştirilemez hale getirme vaadiyle geliyor ancak gerçekte bu garantiyi sağlamak için ek adımlar gerekiyor. İşte verilerinizin gerçekten kalıcı olmasını sağlayacak yöntemler.

DEV Community4 dk okuma0 Yorumlar

Etkinlik kaynağı (event sourcing) yaklaşımının en büyük satış noktası, verilerin değiştirilemez olmasıdır: güncelleme yapılmaz, silme yapılmaz, yalnızca yeni kayıtlar eklenir ve böylece geçmiş tamamen korunur. Ancak pratikte durum her zaman bu kadar basit değildir.

Veriler aslında sizin kodunuzun onayına bağlıdır — veritabanından sorumlu bir kişinin, bir gece yarısı çalıştırılan yanlış bir sorguya veya farklı baytlarla geri yüklenen bir yedeğe karşı koruma sağlamaz. Bu tür bir müdahaleyi tespit etmek genellikle müşterilerinizden biri şikayette bulunana kadar mümkün olmaz ve o noktada artık izi sürmek neredeyse imkansızdır.

Olay zincirini birbirine bağlamak

Buradaki çözüm oldukça basit: her satıra iki ek sütun ekleyin — içeriğinin bir özeti ve önceki satırın özetini taşıyan bir sütun.

Örnek zincir aşağıdaki gibi görünebilir:

#1 AccountOpened   prev=00000… hash=70be4f…
#2 AmountDeposited  prev=70be4f… hash=796018…
#3 AmountWithdrawn  prev=796018… hash=6a0260…

Bu özetler, SHA-256(öncekiÖzet || json(yük)) formülüyle hesaplanır. Karmaşık bir algoritma değil, ancak her özet bir önceki özetten doğrudan etkileniyor. Bir kayıtta değişiklik yaparsanız, ilgili özet artık uyuşmaz. Özeti düzeltmek için bir sonraki satırın bağlantısını bozmadan değiştirirseniz, zincir kırılır. Bu şekilde, tek bir kaydı değiştirmek tüm zinciri bozuyor.

Kırk satırlık basit bir uygulama

Yeni bir olay eklerken zinciri devam ettirmek için aşağıdaki gibi bir yöntem kullanabilirsiniz:

public HashChainedEntry Append(object payload)
{
    var previousHash = _entries.Count == 0 ? GenesisHash : _entries[^1].Hash;
    var hash = ComputeHash(previousHash, payload);
    var entry = new HashChainedEntry(
        _entries.Count + 1,
        payload,
        previousHash,
        hash
    );
    _entries.Add(entry);
    return entry;
}

internal static byte[] ComputeHash(byte[] previousHash, object payload)
{
    var payloadJson = JsonSerializer.SerializeToUtf8Bytes(payload, payload.GetType());
    var combined = new byte[previousHash.Length + payloadJson.Length];
    Buffer.BlockCopy(previousHash, 0, combined, 0, previousHash.Length);
    Buffer.BlockCopy(payloadJson, 0, combined, previousHash.Length, payloadJson.Length);
    return SHA256.HashData(combined);
}

Doğrulama işlemi de tersine çalışır. Satırları gezerek yeniden hesaplama yapılır ve her bir kayıtta iki şey kontrol edilir: bağlantı ve özet.

byte[] previousHash = new byte[32]; // genesis
foreach (var entry in store.Entries)
{
    if (!ByteArraysEqual(previousHash, entry.PreviousHash))
        throw new EventStreamCorruptedException(
            entry.Sequence,
            "önceki özet bağlantısı geçerli değil"
        );

    var recomputed = ComputeHash(previousHash, entry.Payload);
    if (!ByteArraysEqual(recomputed, entry.Hash))
        throw new EventStreamCorruptedException(
            entry.Sequence,
            "kayıtlı özet, yüke ait yeniden hesaplanan özetle uyuşmuyor"
        );

    previousHash = entry.Hash;
}

Örneğin, Alice’in hesabına yapılan 50 dolarlık depoziti veritabanında 5.000 dolara yükseltmeye çalışırsanız, doğrulama işlemi zinciri tam olarak #2 numaralı olayda durdurur ve hata mesajı verir:

Etkinlik zinciriyle oynanmış: kayıtlı özet, yüke ait yeniden hesaplanan özetle uyuşmuyor

Bu yaklaşımın sunduğu koruma

  • Bir kayıdın içeriğini değiştirmek: Yeniden hesaplanan özet artık kayıtlı özetle uyuşmaz.
  • Kaydı yeniden özetlemek: Bir sonraki kaydın bağlantısı artık geçerli değildir.
  • Ortadan bir kaydı silmek: Takip eden kayıtların bağlantıları bozulur.
  • Sahte bir kayıt eklemek: Aynı şekilde zincirdeki bağlantı kırılır.

Gerçek sınırlar: kimlik doğrulama değil, kontrol

Burada dikkat edilmesi gereken önemli bir nokta var. Bu yöntem, saldırganın tembel olduğunu varsayar: bir kaydı değiştirip yoluna devam eder ve eski özeti olduğu gibi bırakır. Ancak veritabanına tam erişimi olan biri tembel olmak zorunda değildir. Tüm kaydı ve sonrasındaki tüm özetleri yeniden hesaplayabilir ve zinciri tutarlı hale getirebilir. Bu durumda doğrulama aracı hiçbir uyarı vermez.

Hash zinciri bir imza değil, yalnızca bir kontrol mekanizmasıdır. Eğer zincirin her iki ucuna da siz sahipseniz, veritabanınıza erişimi olan herkes de sahibidir. Bu, kendi sınırlarınız içinde uyguladığınızda ulaşabileceğiniz en yüksek güvenlik seviyesidir ve bunu açıkça belirtmek önemlidir.

Sınırların ötesine geçmek: dışarıya kökleme

Bu noktada devreye "kökleme" (anchoring) kavramı giriyor. Stratara projesi, olay zincirlerinin yanı sıra ikinci bir tabloyla çalışır: her birkaç olayda zincirin başını kaydeden bir tablo. Her bir kök kaydı, BlockchainTxHash adlı bir sütun içerir ve bu sütun dışarıya kökleme yapmak için kullanılır.

Bu kökleme işlemi için kullanılabilecek çeşitli seçenekler vardır:

  • Bir kamu blokzinciri
  • RFC 3161 zaman damgası yetkilisi
  • OpenTimestamps takvimi
  • Bir noter hizmeti

Temel fikir şudur: kaydı sizin kontrolünüzün dışında bir yere kaydedin. Bu şekilde, veritabanınızdaki tüm özetleri yeniden hesaplasalar bile, dışarıya kaydedilmiş olan kökleme değeri değiştirilemez.

Stratara’nın sunduğu şey, kökleme tablosu, kökleme işini yapan arka plan çalışanı ve BlockchainTxHash sütunudur. Asıl köklendirmeyi yapmak ve sonrasında kontrol etmek ise sizin uygulamanız gereken kısımdır. Proje, örnek bir uygulamada tüm süreci bellekte çalıştırarak size fikir verir.

Ancak unutulmaması gereken bir uyarı var: eğer bir saldırgan hem veritabanınıza hem de kökleme hattınıza erişim sahipse, tüm zinciri ve köklemeleri yeniden oluşturabilir ve sisteminizde hiçbir anormallik görünmeyebilir. Bu nedenle, kökleme değerini gerçekten kontrolünüzün dışında olan bir yere kaydetmeniz kritik önem taşır.

Hash oluşturma ve doğrulama nerede gerçekleşmeli?

Hash oluşturma işlemi, her yeni olay eklendiğinde değil, arka planda çalışan bir işçi tarafından gerçekleştirilir. Bu şekilde, yazma işlemleri ucuz ve hızlı kalır. Zincir, kaydetme işleminden kısa bir süre sonra doldurulur. Doğrulama ise ayrı bir süreç olarak planlı bir şekilde çalıştırılır — örneğin, dışarıdaki kökleme değeriyle karşılaştırmak için. Okuma yolunda doğrulama yapmak istemezsiniz, çünkü bu SELECT … ORDER BY Sequence sorgusunu yavaşlatır.

Yapay zeka özeti

Etkinlik kaynağı (event sourcing) ile verilerinizi değiştirilemez hale getirmek mümkün mü? Hash zinciri ve dış köklendirme yöntemleriyle verilerinizin güvenliğini nasıl artırabilirsiniz.

Yorumlar

00
YORUM BIRAK
ID #DXOWQY

0 / 1200 KARAKTER

İnsan doğrulaması

4 + 6 = ?

Editör onayı sonrası yayına girer

Moderasyon · Spam koruması aktif

Henüz onaylı yorum yok. İlk yorumu sen bırak.