Ana içeriğe atla
Change page

Ethash

Ethash, Ethereum'un İş Kanıtı (PoW) madencilik algoritmasıydı. İş Kanıtı (PoW) artık tamamen kapatıldı ve Ethereum artık bunun yerine Hisse Kanıtı (PoS) kullanılarak güvence altına alınıyor. Birleşme, Hisse Kanıtı (PoS) ve staking hakkında daha fazla bilgi edinin. Bu sayfa tarihi ilgi amaçlıdır!

Ethash, Dagger-Hashimoto algoritmasının değiştirilmiş bir versiyonudur. Ethash İş Kanıtı (PoW) bellek zorludur (memory hard) (opens in a new tab), bu da algoritmayı ASIC'e dirençli hale getirdiği düşünülen bir özellikti. Ethash ASIC'leri sonunda geliştirildi ancak GPU madenciliği, İş Kanıtı (PoW) kapatılana kadar hala geçerli bir seçenekti. Ethash, Ethereum dışındaki diğer İş Kanıtı (PoW) ağlarında diğer coin'lerin madenciliğini yapmak için hala kullanılmaktadır.

Ethash nasıl çalışır?

Bellek zorluğu, nonce ve blok başlığına bağlı sabit bir kaynağın alt kümelerinin seçilmesini gerektiren bir İş Kanıtı (PoW) algoritması ile elde edilir. Bu kaynağa (birkaç gigabayt boyutunda) DAG denir. DAG her 30000 blokta bir değiştirilir, bu ~125 saatlik pencereye bir dönem (yaklaşık 5,2 gün) denir ve oluşturulması biraz zaman alır. DAG yalnızca blok yüksekliğine bağlı olduğundan önceden oluşturulabilir, ancak oluşturulmamışsa istemcinin bir blok üretmek için bu sürecin sonuna kadar beklemesi gerekir. İstemciler DAG'leri önceden oluşturup önbelleğe almazlarsa, ağ her dönem geçişinde büyük bir blok gecikmesi yaşayabilir. İş Kanıtı'nı (PoW) doğrulamak için DAG'nin oluşturulmasına gerek olmadığını, bunun da esasen hem düşük CPU hem de küçük bellek ile doğrulamaya izin verdiğini unutmayın.

Algoritmanın izlediği genel yol aşağıdaki gibidir:

  1. O noktaya kadar olan blok başlıkları taranarak her blok için hesaplanabilen bir tohum (seed) vardır.
  2. Tohumdan, 16 MB'lık sözde rastgele bir önbellek hesaplanabilir. Hafif istemciler önbelleği depolar.
  3. Önbellekten, veri kümesindeki her bir öğenin önbellekteki yalnızca az sayıda öğeye bağlı olması özelliğiyle 1 GB'lık bir veri kümesi oluşturabiliriz. Tam istemciler ve madenciler veri kümesini depolar. Veri kümesi zamanla doğrusal olarak büyür.
  4. Madencilik, veri kümesinden rastgele dilimler almayı ve bunları birlikte hashlemeyi içerir. Doğrulama, ihtiyacınız olan veri kümesinin belirli parçalarını yeniden oluşturmak için önbelleği kullanarak düşük bellekle yapılabilir, bu nedenle yalnızca önbelleği depolamanız gerekir.

Büyük veri kümesi her 30000 blokta bir güncellenir, bu nedenle bir madencinin çabasının büyük çoğunluğu veri kümesinde değişiklik yapmak değil, onu okumak olacaktır.

Tanımlar

Aşağıdaki tanımları kullanıyoruz:

'SHA3' kullanımı

Ethereum'un gelişimi SHA3 standardının gelişimiyle aynı zamana denk geldi ve standartlar süreci, kesinleşmiş hash algoritmasının dolgusunda (padding) geç bir değişiklik yaptı, bu nedenle Ethereum'un "sha3_256" ve "sha3_512" hash'leri standart sha3 hash'leri değil, diğer bağlamlarda genellikle "Keccak-256" ve "Keccak-512" olarak adlandırılan bir varyanttır. Tartışmalara bakın, örn. burada (opens in a new tab), burada (opens in a new tab) veya burada (opens in a new tab).

Aşağıdaki algoritmanın açıklamasında "sha3" hash'lerine atıfta bulunulduğundan lütfen bunu aklınızda bulundurun.

Parametreler

Ethash'in önbelleği ve veri kümesi için parametreler blok numarasına bağlıdır. Önbellek boyutu ve veri kümesi boyutu doğrusal olarak büyür; ancak, döngüsel davranışa yol açan tesadüfi düzenlilik riskini azaltmak için her zaman doğrusal olarak büyüyen eşiğin altındaki en yüksek asal sayıyı alırız.

Veri kümesi ve önbellek boyutu değerlerinin tabloları ekte verilmiştir.

Önbellek oluşturma

Şimdi, bir önbellek üretmek için işlevi belirtiyoruz:

Önbellek üretim süreci, önce 32 MB belleğin sırayla doldurulmasını, ardından Sergio Demian Lerner'ın Strict Memory Hard Hashing Functions (2014) (opens in a new tab) adlı eserindeki RandMemoHash algoritmasının iki geçişinin gerçekleştirilmesini içerir. Çıktı, 524288 adet 64 baytlık değerden oluşan bir kümedir.

Veri toplama işlevi

Bazı durumlarda XOR'un birleşmeli olmayan (non-associative) bir alternatifi olarak FNV hash (opens in a new tab)'ten esinlenen bir algoritma kullanıyoruz. Asal sayıyı sırayla bir bayt (sekizli) ile çarpan FNV-1 spesifikasyonunun aksine, asal sayıyı tam 32 bitlik girdiyle çarptığımıza dikkat edin.

FNV_PRIME = 0x01000193

def fnv(v1, v2):
    return ((v1 * FNV_PRIME) ^ v2) % 2**32

Lütfen unutmayın, Sarı Bülten bile fnv'yi v1*(FNV_PRIME ^ v2) olarak belirtse de, mevcut tüm uygulamalar tutarlı bir şekilde yukarıdaki tanımı kullanır.

Tam veri kümesi hesaplaması

Tam 1 GB'lık veri kümesindeki her 64 baytlık öğe aşağıdaki gibi hesaplanır:

Esasen, sözde rastgele seçilmiş 256 önbellek düğümünden gelen verileri birleştiriyoruz ve veri kümesi düğümünü hesaplamak için bunu hashliyoruz. Tüm veri kümesi daha sonra şu şekilde oluşturulur:

def calc_dataset(full_size, cache):
    return [calc_dataset_item(cache, i) for i in range(full_size // HASH_BYTES)]

Ana döngü

Şimdi, belirli bir başlık ve nonce için nihai değerimizi üretmek amacıyla tam veri kümesinden verileri topladığımız ana "hashimoto" benzeri döngüyü belirtiyoruz. Aşağıdaki kodda, header, kesilmiş bir blok başlığının, yani mixHash ve nonce alanları hariç tutulmuş bir başlığın RLP temsilinin SHA3-256 hash'ini temsil eder. nonce, büyük uçlu (big-endian) sırasındaki 64 bitlik işaretsiz bir tamsayının sekiz baytıdır. Yani nonce[::-1], bu değerin sekiz baytlık küçük uçlu (little-endian) temsilidir:

Esasen, 128 bayt genişliğinde bir "karışım" (mix) tutuyoruz ve tam veri kümesinden art arda sırayla 128 bayt alıp bunu karışımla birleştirmek için fnv işlevini kullanıyoruz. Algoritmanın her turunun her zaman RAM'den tam bir sayfa getirmesi ve böylece ASIC'lerin teorik olarak kaçınabileceği çeviri arabelleği (TLB) isabet kayıplarını en aza indirmesi için 128 baytlık sıralı erişim kullanılır.

Bu algoritmanın çıktısı istenen hedefin altındaysa, nonce geçerlidir. Sonundaki ekstra sha3_256 uygulamasının, en azından küçük bir miktar iş yapıldığını kanıtlamak için sağlanabilecek bir ara nonce olmasını sağladığına dikkat edin; bu hızlı dış İş Kanıtı (PoW) doğrulaması, anti-DDoS amaçları için kullanılabilir. Ayrıca sonucun tarafsız, 256 bitlik bir sayı olduğuna dair istatistiksel güvence sağlamaya da hizmet eder.

Madencilik

Madencilik algoritması aşağıdaki gibi tanımlanır:

def mine(full_size, dataset, header, difficulty):
    # aynı basamaktaki hash ile karşılaştırmak için hedefi sıfırla doldur
    target = zpad(encode_int(2**256 // difficulty), 64)[::-1]
    from random import randint
    nonce = randint(0, 2**64)
    while hashimoto_full(full_size, dataset, header, nonce) > target:
        nonce = (nonce + 1) % 2**64
    return nonce

Tohum hash'ini tanımlama

Belirli bir bloğun üzerinde madencilik yapmak için kullanılacak tohum hash'ini hesaplamak amacıyla aşağıdaki algoritmayı kullanıyoruz:

 def get_seedhash(block):
     s = '\x00' * 32
     for i in range(block.number // EPOCH_LENGTH):
         s = serialize_hash(sha3_256(s))
     return s

Sorunsuz madencilik ve doğrulama için, gelecekteki tohum hash'lerini ve veri kümelerini ayrı bir iş parçacığında (thread) önceden hesaplamanızı önerdiğimizi unutmayın.

Daha fazla okuma

Size yardımcı olan bir topluluk kaynağı mı biliyorsunuz? Bu sayfayı düzenleyin ve ekleyin!

Ek

Yukarıdaki Python spesifikasyonunu kod olarak çalıştırmakla ilgileniyorsanız, aşağıdaki kod başa eklenmelidir.

Veri Boyutları

Aşağıdaki arama tabloları, veri boyutları ve önbellek boyutlarının yaklaşık 2048 tablo haline getirilmiş dönemini sağlar.