Sarı Bülten'in EVM Spesifikasyonlarını Anlamak
Sarı Bülten (yeni sekmede açılır), Ethereum için resmi spesifikasyondur. EIP süreci tarafından değiştirildiği yerler haricinde, her şeyin nasıl çalıştığının kesin açıklamasını içerir. Programcıların aşina olmayabileceği terminolojiyi içeren matematiksel bir makale olarak yazılmıştır. Bu makalede onu ve dolayısıyla diğer ilgili matematiksel makaleleri nasıl okuyacağınızı öğreneceksiniz.
Hangi Sarı Bülten?
Ethereum'daki hemen hemen her şey gibi, Sarı Bülten de zamanla gelişir. Belirli bir sürüme atıfta bulunabilmek için, yazının yazıldığı sıradaki mevcut sürümü (yeni sekmede açılır) yükledim. Kullandığım bölüm, sayfa ve denklem numaraları bu sürüme atıfta bulunacaktır. Bu belgeyi okurken onu farklı bir pencerede açık tutmak iyi bir fikirdir.
Neden EVM?
Orijinal sarı bülten, Ethereum'un gelişiminin tam başında yazılmıştır. Ağı güvence altına almak için başlangıçta kullanılan orijinal İş Kanıtı (PoW) tabanlı mutabakat mekanizmasını açıklar. Ancak Ethereum, Eylül 2022'de İş Kanıtı'nı (PoW) kapattı ve Hisse Kanıtı (PoS) tabanlı mutabakat kullanmaya başladı. Bu eğitim, sarı bültenin Ethereum Sanal Makinesi'ni tanımlayan kısımlarına odaklanacaktır. EVM, Hisse Kanıtı'na (PoS) geçişten etkilenmedi (DIFFICULTY işlem kodunun dönüş değeri hariç).
9 Yürütme modeli
Bu bölüm (s. 14-16), EVM tanımının çoğunu içerir.
Sistem durumu terimi, sistemi çalıştırmak için sistem hakkında bilmeniz gereken her şeyi içerir. Tipik bir bilgisayarda bu, bellek, yazmaçların içeriği vb. anlamına gelir.
Bir Turing makinesi (yeni sekmede açılır) hesaplamalı bir modeldir. Temel olarak, normal bir bilgisayarın yapabileceği hesaplamaları çalıştırma yeteneğine sahip olduğu kanıtlanmış, bilgisayarın basitleştirilmiş bir versiyonudur (bir bilgisayarın hesaplayabileceği her şeyi bir Turing makinesi hesaplayabilir ve bunun tersi de geçerlidir). Bu model, neyin hesaplanabilir olup neyin olmadığı hakkında çeşitli teoremleri kanıtlamayı kolaylaştırır.
Turing-tam (Turing-complete) (yeni sekmede açılır) terimi, bir Turing makinesiyle aynı hesaplamaları çalıştırabilen bir bilgisayar anlamına gelir. Turing makineleri sonsuz döngülere girebilir, ancak EVM giremez çünkü gazı biter, bu nedenle yalnızca yarı Turing-tamdır (quasi-Turing-complete).
9.1 Temeller
Bu bölüm, EVM'nin temellerini ve diğer hesaplama modelleriyle nasıl karşılaştırıldığını verir.
Bir yığın makinesi (yeni sekmede açılır), ara verileri yazmaçlarda değil, bir yığında (stack) (yeni sekmede açılır) depolayan bir bilgisayardır. Bu, sanal makineler için tercih edilen mimaridir çünkü uygulanması kolaydır, bu da hataların ve güvenlik açıklarının çok daha az olası olduğu anlamına gelir. Yığındaki bellek 256 bitlik kelimelere (words) bölünmüştür. Bu, Keccak-256 hashleme ve eliptik eğri hesaplamaları gibi Ethereum'un temel kriptografik işlemleri için uygun olduğundan seçilmiştir. Yığının maksimum boyutu 1024 öğedir (1024 x 256 bit). İşlem kodları yürütüldüğünde genellikle parametrelerini yığından alırlar. POP (öğeyi yığının en üstünden kaldırır), DUP_N (yığındaki N'inci öğeyi çoğaltır) vb. gibi yığındaki öğeleri yeniden düzenlemek için özel işlem kodları vardır.
EVM ayrıca yürütme sırasında verileri depolamak için kullanılan bellek (memory) adı verilen geçici bir alana sahiptir. Bu bellek 32 baytlık kelimeler halinde düzenlenmiştir. Tüm bellek konumları sıfır olarak başlatılır. Belleğe bir kelime eklemek için bu Yul (yeni sekmede açılır) kodunu yürütürseniz, kelimedeki boş alanı sıfırlarla doldurarak 32 baytlık belleği dolduracaktır, yani 0-29 konumlarında sıfırlar, 30'da 0x60 ve 31'de 0xA7 olan bir kelime oluşturur.
mstore(0, 0x60A7)
mstore, EVM'nin bellekle etkileşim için sağladığı üç işlem kodundan biridir - belleğe bir kelime yükler. Diğer ikisi, belleğe tek bir bayt yükleyen mstore8 ve bellekten yığına bir kelime taşıyan mload işlem kodlarıdır.
EVM ayrıca sistem durumunun bir parçası olarak korunan ayrı bir kalıcı depolama (storage) modeline sahiptir - bu bellek (yığındaki kelime adreslenebilir bayt dizilerinin aksine) kelime dizileri halinde düzenlenmiştir. Bu depolama, sözleşmelerin kalıcı verileri tuttuğu yerdir - bir sözleşme yalnızca kendi depolamasıyla etkileşime girebilir. Depolama, anahtar-değer eşlemeleri şeklinde düzenlenmiştir.
Sarı Bülten'in bu bölümünde bahsedilmese de, dördüncü bir bellek türü olduğunu bilmek de faydalıdır. Çağrı verisi (Calldata), bir işlemin data parametresiyle iletilen değeri depolamak için kullanılan bayt adreslenebilir salt okunur bellektir. EVM'nin calldata yönetimi için özel işlem kodları vardır. calldatasize verinin boyutunu döndürür. calldataload veriyi yığına yükler. calldatacopy veriyi belleğe kopyalar.
Standart Von Neumann mimarisi (yeni sekmede açılır) kodu ve veriyi aynı bellekte depolar. EVM güvenlik nedenleriyle bu standardı izlemez - geçici belleği paylaşmak program kodunu değiştirmeyi mümkün kılar. Bunun yerine, kod depolamaya kaydedilir.
Kodun bellekten yürütüldüğü yalnızca iki durum vardır:
- Bir sözleşme başka bir sözleşme oluşturduğunda (
CREATE(yeni sekmede açılır) veyaCREATE2(yeni sekmede açılır) kullanarak), sözleşme kurucusu için kod bellekten gelir. - Herhangi bir sözleşmenin oluşturulması sırasında, kurucu kodu çalışır ve ardından yine bellekten gelen asıl sözleşmenin koduyla geri döner.
İstisnai yürütme terimi, mevcut sözleşmenin yürütülmesinin durmasına neden olan bir istisna anlamına gelir.
9.2 Ücretlere genel bakış
Bu bölüm gaz ücretlerinin nasıl hesaplandığını açıklar. Üç maliyet vardır:
İşlem kodu maliyeti
Belirli bir işlem kodunun doğal maliyeti. Bu değeri elde etmek için, Ek H'de (s. 29, denklem (329) altında) işlem kodunun maliyet grubunu bulun ve denklem (326)'daki maliyet grubunu bulun. Bu size, çoğu durumda Ek G'deki (s. 28) parametreleri kullanan bir maliyet işlevi verir.
Örneğin, CALLDATACOPY (yeni sekmede açılır) işlem kodu Wcopy grubunun bir üyesidir. Bu grup için işlem kodu maliyeti Gverylow+Gcopy×⌈μs[2]÷32⌉ şeklindedir. Ek G'ye baktığımızda, her iki sabitin de 3 olduğunu görüyoruz, bu da bize 3+3×⌈μs[2]÷32⌉ verir.
Hala ⌈μs[2]÷32⌉ ifadesini çözmemiz gerekiyor. En dıştaki kısım olan ⌈ <değer> ⌉ tavan işlevidir (ceiling function), bir değer verildiğinde değerden daha küçük olmayan en küçük tam sayıyı döndüren bir işlevdir. Örneğin, ⌈2.5⌉ = ⌈3⌉ = 3. İç kısım μs[2]÷32'dir. Sayfa 3'teki bölüm 3'e (Kurallar) bakıldığında, μ makine durumudur. Makine durumu, sayfa 15'teki bölüm 9.4.1'de tanımlanmıştır. Bu bölüme göre, makine durumu parametrelerinden biri yığın (stack) için s'dir. Hepsini bir araya getirdiğimizde, μs[2] yığındaki 2 numaralı konum gibi görünüyor. İşlem koduna (yeni sekmede açılır) bakıldığında, yığındaki 2 numaralı konum verinin bayt cinsinden boyutudur. Wcopy grubundaki diğer işlem kodlarına, CODECOPY (yeni sekmede açılır) ve RETURNDATACOPY (yeni sekmede açılır)'ye bakıldığında, onların da aynı konumda bir veri boyutuna sahip oldukları görülür. Yani ⌈μs[2]÷32⌉, kopyalanan veriyi depolamak için gereken 32 baytlık kelimelerin (words) sayısıdır. Her şeyi bir araya getirdiğimizde, CALLDATACOPY (yeni sekmede açılır) işlem kodunun doğal maliyeti 3 gaz artı kopyalanan verinin her kelimesi için 3 gazdır.
Çalıştırma maliyeti
Çağırdığımız kodu çalıştırmanın maliyeti.
CREATE(yeni sekmede açılır) veCREATE2(yeni sekmede açılır) durumunda, yeni sözleşme için kurucu.CALL(yeni sekmede açılır),CALLCODE(yeni sekmede açılır),STATICCALL(yeni sekmede açılır) veyaDELEGATECALL(yeni sekmede açılır) durumunda, çağırdığımız sözleşme.
Belleği genişletme maliyeti
Belleği genişletmenin maliyeti (gerekirse).
Denklem 326'da bu değer Cmem(μi')-Cmem(μi) olarak yazılır. Bölüm 9.4.1'e tekrar baktığımızda, μi'nin bellekteki kelime sayısı olduğunu görüyoruz. Yani μi işlem kodundan önceki bellekteki kelime sayısıdır ve μi' işlem kodundan sonraki bellekteki kelime sayısıdır.
Cmem işlevi denklem 328'de tanımlanmıştır: Cmem(a) = Gmemory × a + ⌊a2 ÷ 512⌋. ⌊x⌋ taban işlevidir (floor function), bir değer verildiğinde değerden daha büyük olmayan en büyük tam sayıyı döndüren bir işlevdir. Örneğin, ⌊2.5⌋ = ⌊2⌋ = 2. a < √512 olduğunda, a2 < 512 olur ve taban işlevinin sonucu sıfırdır. Yani ilk 22 kelime (704 bayt) için maliyet, gereken bellek kelimesi sayısıyla doğrusal olarak artar. Bu noktanın ötesinde ⌊a2 ÷ 512⌋ pozitiftir. Gereken bellek yeterince yüksek olduğunda gaz maliyeti, bellek miktarının karesiyle orantılıdır.
Not: Bu faktörler yalnızca doğal gaz maliyetini etkiler - bir son kullanıcının ne kadar ödemesi gerektiğini belirleyen ücret piyasasını veya doğrulayıcılara verilen bahşişleri hesaba katmaz - bu sadece EVM'de belirli bir işlemi çalıştırmanın ham maliyetidir.
Gaz hakkında daha fazla bilgi edinin.
9.3 Yürütme ortamı
Yürütme ortamı, blokzincir durumunun veya EVM'nin bir parçası olmayan bilgileri içeren bir demettir (tuple), I.
| Parametre | Veriye erişmek için işlem kodu | Veriye erişmek için Solidity kodu |
|---|---|---|
| Ia | ADDRESS (yeni sekmede açılır) | address(this) |
| Io | ORIGIN (yeni sekmede açılır) | tx.origin |
| Ip | GASPRICE (yeni sekmede açılır) | tx.gasprice |
| Id | CALLDATALOAD (yeni sekmede açılır) vb. | msg.data |
| Is | CALLER (yeni sekmede açılır) | msg.sender |
| Iv | CALLVALUE (yeni sekmede açılır) | msg.value |
| Ib | CODECOPY (yeni sekmede açılır) | address(this).code |
| IH | NUMBER (yeni sekmede açılır) ve DIFFICULTY (yeni sekmede açılır) gibi blok başlığı alanları | block.number, block.difficulty vb. |
| Ie | Sözleşmeler arası çağrılar için çağrı yığınının derinliği (sözleşme oluşturma dahil) | |
| Iw | EVM'nin durumu değiştirmesine izin veriliyor mu yoksa statik olarak mı çalışıyor |
Bölüm 9'un geri kalanını anlamak için birkaç başka parametre daha gereklidir:
| Parametre | Tanımlandığı bölüm | Anlamı |
|---|---|---|
| σ | 2 (s. 2, denklem 1) | Blokzincirin durumu |
| g | 9.3 (s. 14) | Kalan gaz |
| A | 6.1 (s. 9) | Tahakkuk eden alt durum (işlem sona erdiğinde yapılması planlanan değişiklikler) |
| o | 9.3 (s. 14) | Çıktı - dahili işlem durumunda (bir sözleşme diğerini çağırdığında) ve görünüm (view) işlevlerine yapılan çağrılarda (sadece bilgi istediğinizde, bu nedenle bir işlem beklemenize gerek olmadığında) döndürülen sonuç |
9.4 Yürütmeye genel bakış
Artık tüm ön bilgilere sahip olduğumuza göre, nihayet EVM'nin nasıl çalıştığı üzerinde çalışmaya başlayabiliriz.
146-151 numaralı denklemler bize EVM'yi çalıştırmak için başlangıç koşullarını verir:
| Sembol | Başlangıç değeri | Anlamı |
|---|---|---|
| μg | g | Kalan gaz |
| μpc | 0 | Program sayacı, yürütülecek bir sonraki talimatın adresi |
| μm | (0, 0, ...) | Bellek, tamamı sıfır olarak başlatılır |
| μi | 0 | Kullanılan en yüksek bellek konumu |
| μs | () | Yığın, başlangıçta boş |
| μo | ∅ | Çıktı, dönüş verisiyle (RETURN (yeni sekmede açılır) veya REVERT (yeni sekmede açılır)) veya dönüş verisi olmadan (STOP (yeni sekmede açılır) veya SELFDESTRUCT (yeni sekmede açılır)) durana kadar ve durmadıkça boş küme. |
Denklem 152 bize yürütme sırasında her an dört olası koşul olduğunu ve bunlarla ne yapacağımızı söyler:
Z(σ,μ,A,I). Z, bir işlemin geçersiz bir durum geçişi yaratıp yaratmadığını test eden bir işlevi temsil eder (bkz. istisnai durma). Doğru (True) olarak değerlendirilirse, değişiklikler uygulanmadığı için yeni durum eskisiyle aynıdır (gazın yanması hariç).- Yürütülen işlem kodu
REVERT(yeni sekmede açılır) ise, yeni durum eski durumla aynıdır, bir miktar gaz kaybedilir. - İşlem dizisi bittiyse, ki bu bir
RETURN(yeni sekmede açılır) ile belirtilir, durum yeni duruma güncellenir. - 1-3 bitiş koşullarından birinde değilsek, çalışmaya devam edin.
9.4.1 Makine Durumu
Bu bölüm makine durumunu daha ayrıntılı olarak açıklar. w'nin mevcut işlem kodu olduğunu belirtir. Eğer μpc, kodun uzunluğu olan ||Ib||'den küçükse, o bayt (Ib[μpc]) işlem kodudur. Aksi takdirde, işlem kodu STOP (yeni sekmede açılır) olarak tanımlanır.
Bu bir yığın makinesi (yeni sekmede açılır) olduğundan, her işlem kodu tarafından çıkarılan (δ) ve itilen (α) öğelerin sayısını takip etmemiz gerekir.
9.4.2 İstisnai Durma
Bu bölüm, ne zaman anormal bir sonlandırma yaşayacağımızı belirten Z işlevini tanımlar. Bu bir Boole (yeni sekmede açılır) işlevidir, bu nedenle mantıksal veya için ∨ (yeni sekmede açılır) ve mantıksal ve için ∧ (yeni sekmede açılır) kullanır.
Bu koşullardan herhangi biri doğruysa istisnai bir durma yaşarız:
-
μg < C(σ,μ,A,I) Bölüm 9.2'de gördüğümüz gibi, C gaz maliyetini belirten işlevdir. Bir sonraki işlem kodunu karşılayacak kadar gaz kalmamıştır.
-
δw=∅ Bir işlem kodu için çıkarılan öğelerin sayısı tanımsızsa, işlem kodunun kendisi de tanımsızdır.
-
|| μs || < δw Yığın yetersizliği (stack underflow), mevcut işlem kodu için yığında yeterli öğe yok.
-
w = JUMP ∧ μs[0]∉D(Ib) İşlem kodu
JUMP(yeni sekmede açılır) ve adres birJUMPDEST(yeni sekmede açılır) değil. Atlamalar yalnızca hedef birJUMPDEST(yeni sekmede açılır) olduğunda geçerlidir. -
w = JUMPI ∧ μs[1]≠0 ∧ μs[0] ∉ D(Ib) İşlem kodu
JUMPI(yeni sekmede açılır), koşul doğru (sıfır değil) bu yüzden atlama gerçekleşmeli ve adres birJUMPDEST(yeni sekmede açılır) değil. Atlamalar yalnızca hedef birJUMPDEST(yeni sekmede açılır) olduğunda geçerlidir. -
w = RETURNDATACOPY ∧ μs[1]+μs[2]>|| μo || İşlem kodu
RETURNDATACOPY(yeni sekmede açılır). Bu işlem kodunda yığın öğesi μs[1] dönüş verisi arabelleğinden okunacak ofsettir ve yığın öğesi μs[2] verinin uzunluğudur. Bu koşul, dönüş verisi arabelleğinin sonunun ötesini okumaya çalıştığınızda oluşur. Çağrı verisi (calldata) veya kodun kendisi için benzer bir koşul olmadığına dikkat edin. Bu arabelleklerin sonunun ötesini okumaya çalıştığınızda sadece sıfırlar alırsınız. -
|| μs || - δw + αw > 1024
Yığın taşması (stack overflow). İşlem kodunu çalıştırmak 1024 öğeden fazla bir yığınla sonuçlanacaksa, iptal edin.
-
¬Iw ∧ W(w,μ) Statik olarak mı çalışıyoruz (¬ olumsuzlamadır (yeni sekmede açılır) ve blokzincir durumunu değiştirmemize izin verildiğinde Iw doğrudur)? Eğer öyleyse ve durumu değiştiren bir işlem deniyorsak, bu gerçekleşemez.
W(w,μ) işlevi daha sonra denklem 159'da tanımlanmıştır. Bu koşullardan biri doğruysa W(w,μ) doğrudur:
-
w ∈ {CREATE, CREATE2, SSTORE, SELFDESTRUCT} Bu işlem kodları, yeni bir sözleşme oluşturarak, bir değer depolayarak veya mevcut sözleşmeyi kendi kendini yok etme yoluyla yok ederek durumu değiştirir.
-
LOG0≤w ∧ w≤LOG4 Statik olarak çağrılırsak günlük girişleri yayamayız. Günlük işlem kodlarının tümü
LOG0(A0) (yeni sekmede açılır) ileLOG4(A4) (yeni sekmede açılır) aralığındadır. Günlük işlem kodundan sonraki sayı, günlük girişinin kaç konu içerdiğini belirtir. -
w=CALL ∧ μs[2]≠0 Statik olduğunuzda başka bir sözleşmeyi çağırabilirsiniz, ancak yaparsanız ona ETH transfer edemezsiniz.
-
-
w = SSTORE ∧ μg ≤ Gcallstipend Gcallstipend'den (Ek G'de 2300 olarak tanımlanmıştır) daha fazla gazınız yoksa
SSTORE(yeni sekmede açılır) çalıştıramazsınız.
9.4.3 Atlama Hedefi Geçerliliği
Burada JUMPDEST (yeni sekmede açılır) işlem kodlarının ne olduğunu resmi olarak tanımlıyoruz. Sadece 0x5B bayt değerini arayamayız, çünkü bir PUSH içinde olabilir (ve bu nedenle bir işlem kodu değil, veridir).
Denklem (162)'de bir N(i,w) işlevi tanımlıyoruz. İlk parametre olan i, işlem kodunun konumudur. İkincisi olan w, işlem kodunun kendisidir. Eğer w∈[PUSH1, PUSH32] ise bu, işlem kodunun bir PUSH olduğu anlamına gelir (köşeli parantezler uç noktaları içeren bir aralığı tanımlar). Bu durumda bir sonraki işlem kodu i+2+(w−PUSH1) konumundadır. PUSH1 (yeni sekmede açılır) için iki bayt (PUSH'un kendisi ve bir baytlık değer) ilerlememiz gerekir, PUSH2 (yeni sekmede açılır) için üç bayt ilerlememiz gerekir çünkü iki baytlık bir değerdir vb. Diğer tüm EVM işlem kodları sadece bir bayt uzunluğundadır, bu nedenle diğer tüm durumlarda N(i,w)=i+1'dir.
Bu işlev, denklem (161)'de, i işlem kodu konumundan başlayarak c kodundaki tüm geçerli atlama hedeflerinin kümesi (yeni sekmede açılır) olan DJ(c,i)'yi tanımlamak için kullanılır. Bu işlev özyinelemeli (recursively) olarak tanımlanır. Eğer i≥||c|| ise, bu kodun sonunda veya sonrasında olduğumuz anlamına gelir. Daha fazla atlama hedefi bulamayacağız, bu yüzden sadece boş kümeyi döndürün.
Diğer tüm durumlarda, bir sonraki işlem koduna giderek ve ondan başlayan kümeyi alarak kodun geri kalanına bakarız. c[i] mevcut işlem kodudur, bu nedenle N(i,c[i]) bir sonraki işlem kodunun konumudur. Dolayısıyla DJ(c,N(i,c[i])), bir sonraki işlem kodundan başlayan geçerli atlama hedefleri kümesidir. Mevcut işlem kodu bir JUMPDEST değilse, sadece o kümeyi döndürün. Eğer JUMPDEST ise, onu sonuç kümesine dahil edin ve onu döndürün.
9.4.4 Normal durma
Durma işlevi H, üç tür değer döndürebilir.
- Bir durma işlem kodunda değilsek, boş küme olan ∅ döndürün. Geleneksel olarak, bu değer Boole yanlışı (false) olarak yorumlanır.
- Çıktı üretmeyen bir durma işlem kodumuz varsa (
STOP(yeni sekmede açılır) veyaSELFDESTRUCT(yeni sekmede açılır)), dönüş değeri olarak sıfır bayt boyutunda bir dizi döndürün. Bunun boş kümeden çok farklı olduğuna dikkat edin. Bu değer, EVM'nin gerçekten durduğu, sadece okunacak dönüş verisi olmadığı anlamına gelir. - Çıktı üreten bir durma işlem kodumuz varsa (
RETURN(yeni sekmede açılır) veyaREVERT(yeni sekmede açılır)), o işlem kodu tarafından belirtilen bayt dizisini döndürün. Bu dizi bellekten alınır, yığının en üstündeki değer (μs[0]) ilk bayttır ve ondan sonraki değer (μs[1]) uzunluktur.
H.2 Talimat seti
EVM'nin son alt bölümü olan 9.5'e geçmeden önce, talimatların kendilerine bakalım. Bunlar, s. 30'da başlayan Ek H.2'de tanımlanmıştır. O belirli işlem koduyla değiştiği belirtilmeyen her şeyin aynı kalması beklenir. Değişen değişkenler <bir şey>′ olarak belirtilir.
Örneğin, ADD (yeni sekmede açılır) işlem koduna bakalım.
| Değer | Anımsatıcı | δ | α | Açıklama |
|---|---|---|---|---|
| 0x01 | ADD | 2 | 1 | Toplama işlemi. |
| μ′s[0] ≡ μs[0] + μs[1] |
δ, yığından çıkardığımız değerlerin sayısıdır. Bu durumda iki, çünkü en üstteki iki değeri topluyoruz.
α, geri ittiğimiz değerlerin sayısıdır. Bu durumda bir, yani toplam.
Yani yeni yığın tepesi (μ′s[0]), eski yığın tepesi (μs[0]) ile onun altındaki eski değerin (μs[1]) toplamıdır.
Tüm işlem kodlarının üzerinden "gözleri yoran bir listeyle" geçmek yerine, bu makale yalnızca yeni bir şey sunan işlem kodlarını açıklar.
| Değer | Anımsatıcı | δ | α | Açıklama |
|---|---|---|---|---|
| 0x20 | KECCAK256 | 2 | 1 | Keccak-256 hash'ini hesapla. |
| μ′s[0] ≡ KEC(μm[μs[0] . . . (μs[0] + μs[1] − 1)]) | ||||
| μ′i ≡ M(μi,μs[0],μs[1]) |
Bu, belleğe erişen ilk işlem kodudur (bu durumda, salt okunur). Ancak, belleğin mevcut sınırlarının ötesine genişleyebilir, bu nedenle μi'yi güncellememiz gerekir. Bunu s. 30'daki denklem 330'da tanımlanan M işlevini kullanarak yapıyoruz.
| Değer | Anımsatıcı | δ | α | Açıklama |
|---|---|---|---|---|
| 0x31 | BALANCE | 1 | 1 | Verilen hesabın bakiyesini al. |
| ... |
Bakiyesini bulmamız gereken adres μs[0] mod 2160'tır. Yığının en üstü adrestir, ancak adresler yalnızca 160 bit olduğundan, değeri 2160 modülüne (modulo) (yeni sekmede açılır) göre hesaplarız.
Eğer σ[μs[0] mod 2160] ≠ ∅ ise, bu adres hakkında bilgi olduğu anlamına gelir. Bu durumda, σ[μs[0] mod 2160]b o adresin bakiyesidir. Eğer σ[μs[0] mod 2160] = ∅ ise, bu adresin başlatılmadığı ve bakiyenin sıfır olduğu anlamına gelir. Hesap bilgisi alanlarının listesini s. 4'teki bölüm 4.1'de görebilirsiniz.
İkinci denklem olan A'a ≡ Aa ∪ {μs[0] mod 2160}, sıcak depolamaya (yakın zamanda erişilen ve muhtemelen önbelleğe alınmış depolama) ve soğuk depolamaya (erişilmemiş ve muhtemelen alınması daha pahalı olan daha yavaş depolamada bulunan depolama) erişim arasındaki maliyet farkıyla ilgilidir. Aa, s. 9'daki bölüm 6.1'de tanımlandığı gibi, işlem tarafından daha önce erişilen ve bu nedenle erişimi daha ucuz olması gereken adreslerin listesidir. Bu konu hakkında daha fazla bilgiyi EIP-2929 (yeni sekmede açılır) içinde okuyabilirsiniz.
| Değer | Anımsatıcı | δ | α | Açıklama |
|---|---|---|---|---|
| 0x8F | DUP16 | 16 | 17 | 16. yığın öğesini çoğalt. |
| μ′s[0] ≡ μs[15] |
Herhangi bir yığın öğesini kullanmak için onu çıkarmamız gerektiğine dikkat edin, bu da onun üzerindeki tüm yığın öğelerini de çıkarmamız gerektiği anlamına gelir. DUP<n> (yeni sekmede açılır) ve SWAP<n> (yeni sekmede açılır) durumunda, bu, on altı değere kadar çıkarıp ardından itmek zorunda olmak anlamına gelir.
9.5 Yürütme döngüsü
Artık tüm parçalara sahip olduğumuza göre, nihayet EVM'nin yürütme döngüsünün nasıl belgelendiğini anlayabiliriz.
Denklem (164), şu durum verildiğinde:
- σ (küresel blokzincir durumu)
- μ (EVM durumu)
- A (alt durum, işlem sona erdiğinde gerçekleşecek değişiklikler)
- I (yürütme ortamı)
Yeni durumun (σ', μ', A', I') olduğunu söyler.
(165)-(167) numaralı denklemler yığını ve bir işlem kodu (μs) nedeniyle yığındaki değişikliği tanımlar. Denklem (168) gazdaki (μg) değişikliktir. Denklem (169) program sayacındaki (μpc) değişikliktir. Son olarak, (170)-(173) numaralı denklemler, işlem kodu tarafından açıkça değiştirilmedikçe diğer parametrelerin aynı kaldığını belirtir.
Bununla birlikte EVM tamamen tanımlanmış olur.
Sonuç
Matematiksel gösterim kesindir ve Sarı Bülten'in Ethereum'un her detayını belirtmesine olanak tanımıştır. Ancak bazı dezavantajları vardır:
- Sadece insanlar tarafından anlaşılabilir, bu da uyumluluk testlerinin (yeni sekmede açılır) manuel olarak yazılması gerektiği anlamına gelir.
- Programcılar bilgisayar kodunu anlar. Matematiksel gösterimi anlayabilirler veya anlamayabilirler.
Belki de bu nedenlerden dolayı, daha yeni mutabakat katmanı spesifikasyonları (yeni sekmede açılır) Python'da yazılmıştır. Python'da yürütme katmanı spesifikasyonları (yeni sekmede açılır) vardır, ancak bunlar tam değildir. Tüm Sarı Bülten de Python veya benzeri bir dile çevrilene kadar Sarı Bülten hizmet vermeye devam edecektir ve onu okuyabilmek faydalıdır.