Sarı Bülten'in EVM Spesifikasyonlarını Anlamak
Sarı Bülten (opens in a new tab), 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ü 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. 12-14), 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 (opens in a new tab) 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ığına dair çeşitli teoremleri kanıtlamayı kolaylaştırır.
Turing-tam (opens in a new tab) 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 yüzden sadece yarı Turing-tamdır.
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 (opens in a new tab), ara verileri yazmaçlarda değil, bir yığında (stack) (opens in a new tab) 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 (opens in a new tab) 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 (opens in a new tab) 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(opens in a new tab) veyaCREATE2(opens in a new tab) 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 işlem kodunun doğal maliyeti. Bu değeri elde etmek için, Ek H'de (s. 28, denklem (327) altında) işlem kodunun maliyet grubunu bulun ve denklem (324)'teki maliyet grubunu bulun. Bu size, çoğu durumda Ek G'deki (s. 27) parametreleri kullanan bir maliyet işlevi verir.
Örneğin, CALLDATACOPY (opens in a new tab) 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.
Hâlâ ⌈μs[2]÷32⌉ ifadesini çözmemiz gerekiyor. En dıştaki kısım olan ⌈ <değer> ⌉ tavan işlevidir, 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 13'teki bölüm 9.4.1'de tanımlanmıştır. Bu bölüme göre, makine durumu parametrelerinden biri yığın için s'dir. Hepsini bir araya getirdiğimizde, μs[2]'nin yığındaki 2 numaralı konum olduğu görülüyor. İşlem koduna (opens in a new tab) bakıldığında, yığındaki 2 numaralı konum bayt cinsinden verinin boyutudur. Wcopy grubundaki diğer işlem kodlarına, CODECOPY (opens in a new tab) ve RETURNDATACOPY (opens in a new tab)'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 sayısıdır. Her şeyi bir araya getirdiğimizde, CALLDATACOPY (opens in a new tab)'nin doğal maliyeti 3 gaz artı kopyalanan verinin her kelimesi için 3'tür.
Çalıştırma maliyeti
Çağırdığımız kodu çalıştırmanın maliyeti.
CREATE(opens in a new tab) veCREATE2(opens in a new tab) durumunda, yeni sözleşme için kurucu.CALL(opens in a new tab),CALLCODE(opens in a new tab),STATICCALL(opens in a new tab) veyaDELEGATECALL(opens in a new tab) durumunda, çağırdığımız sözleşme.
Bellek genişletme maliyeti
Belleği genişletmenin maliyeti (gerekirse).
Denklem 324'te 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 326'da tanımlanmıştır: Cmem(a) = Gmemory × a + ⌊a2 ÷ 512⌋. ⌊x⌋ taban işlevidir, 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 yürütmenin 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 (opens in a new tab) | address(this) |
| Io | ORIGIN (opens in a new tab) | tx.origin |
| Ip | GASPRICE (opens in a new tab) | tx.gasprice |
| Id | CALLDATALOAD (opens in a new tab), vb. | msg.data |
| Is | CALLER (opens in a new tab) | msg.sender |
| Iv | CALLVALUE (opens in a new tab) | msg.value |
| Ib | CODECOPY (opens in a new tab) | address(this).code |
| IH | NUMBER (opens in a new tab) ve DIFFICULTY (opens in a new tab) 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. 13) | Kalan gaz |
| A | 6.1 (s. 8) | Tahakkuk eden alt durum (işlem sona erdiğinde yapılması planlanan değişiklikler) |
| o | 9.3 (s. 13) | Çıktı - dahili işlem durumunda (bir sözleşme diğerini çağırdığında) ve 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.
137-142 denklemleri 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 (opens in a new tab) veya REVERT (opens in a new tab)) veya dönüş verisi olmadan (STOP (opens in a new tab) veya SELFDESTRUCT (opens in a new tab)) durmadığımız sürece boş küme. |
Denklem 143 bize yürütme sırasındaki her zaman noktasında 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). Eğer 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(opens in a new tab) ise, yeni durum eski durumla aynıdır, bir miktar gaz kaybedilir. - İşlem dizisi bittiyse (bir
RETURN(opens in a new tab) ile belirtildiği gibi), 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 (opens in a new tab) olarak tanımlanır.
Bu bir yığın makinesi (opens in a new tab) 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 (opens in a new tab) işlevidir, bu nedenle mantıksal veya için ∨ (opens in a new tab) ve mantıksal ve için ∧ (opens in a new tab) 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 (underflow), mevcut işlem kodu için yığında yeterli öğe yok.
-
w = JUMP ∧ μs[0]∉D(Ib) İşlem kodu
JUMP(opens in a new tab)'tır ve adres birJUMPDEST(opens in a new tab) değildir. Atlamalar (jumps) yalnızca hedef birJUMPDEST(opens in a new tab) olduğunda geçerlidir. -
w = JUMPI ∧ μs[1]≠0 ∧ μs[0] ∉ D(Ib) İşlem kodu
JUMPI(opens in a new tab)'dir, koşul doğrudur (sıfır değil) bu nedenle atlama gerçekleşmelidir ve adres birJUMPDEST(opens in a new tab) değildir. Atlamalar yalnızca hedef birJUMPDEST(opens in a new tab) olduğunda geçerlidir. -
w = RETURNDATACOPY ∧ μs[1]+μs[2]>|| μo || İşlem kodu
RETURNDATACOPY(opens in a new tab)'dir. Bu işlem kodunda yığın öğesi μs[1] dönüş verisi arabelleğinde 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 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ı (overflow). İşlem kodunu çalıştırmak 1024 öğeden fazla bir yığınla sonuçlanacaksa iptal et.
-
¬Iw ∧ W(w,μ) Statik olarak mı çalışıyoruz (¬ olumsuzlamadır (opens in a new tab) 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 150'de 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 yok ederek durumu değiştirir.
-
LOG0≤w ∧ w≤LOG4 Statik olarak çağrılırsak günlük (log) girdileri yayımlayamayız. Günlük işlem kodlarının tümü
LOG0(A0) (opens in a new tab) ileLOG4(A4) (opens in a new tab) aralığındadır. Günlük işlem kodundan sonraki sayı, günlük girdisinin kaç konu (topic) içerdiğini belirtir. -
w=CALL ∧ μs[2]≠0 Statik olduğunuzda başka bir sözleşmeyi çağırabilirsiniz, ancak bunu yaparsanız ona ETH transfer edemezsiniz.
-
-
w = SSTORE ∧ μg ≤ Gcallstipend Gcallstipend (Ek G'de 2300 olarak tanımlanmıştır) gazından daha fazlasına sahip olmadığınız sürece
SSTORE(opens in a new tab) çalıştıramazsınız.
9.4.3 Atlama Hedefi Geçerliliği
Burada JUMPDEST (opens in a new tab) 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 (153)'te 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 (opens in a new tab) için iki bayt (PUSH'un kendisi ve bir baytlık değer) ilerlememiz gerekir, PUSH2 (opens in a new tab) 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 (152)'de, i işlem kodu konumundan başlayarak c kodundaki tüm geçerli atlama hedeflerinin kümesi (opens in a new tab) olan DJ(c,i)'yi tanımlamak için kullanılır. Bu işlev özyinelemeli 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. Bu nedenle 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(opens in a new tab) veyaSELFDESTRUCT(opens in a new tab)), 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(opens in a new tab) veyaREVERT(opens in a new tab)), 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 sayfa 29'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 (opens in a new tab) 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 üstü (μ′s[0]), eski yığın üstü (μ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çıklamaktadır.
| 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 sayfa 29'daki denklem 328'de 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 (opens in a new tab) 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 bilgi alanlarının listesini sayfa 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, sayfa 8'deki 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 (opens in a new tab)'da 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> (opens in a new tab) ve SWAP<n> (opens in a new tab) durumunda bu, on altı değere kadar çıkarıp ardından itmek zorunda kalmak anlamına gelir.
9.5 Yürütme döngüsü
Artık tüm parçalara sahip olduğumuza göre, EVM'nin yürütme döngüsünün nasıl belgelendiğini nihayet anlayabiliriz.
Denklem (155), durum verildiğinde şunları söyler:
- σ (küresel blokzincir durumu)
- μ (EVM durumu)
- A (alt durum, işlem bittiğinde gerçekleşecek değişiklikler)
- I (yürütme ortamı)
Yeni durum (σ', μ', A', I') şeklindedir.
(156)-(158) denklemleri yığını ve bir işlem kodu (μs) nedeniyle yığındaki değişikliği tanımlar. Denklem (159) gazdaki (μg) değişikliktir. Denklem (160) program sayacındaki (μpc) değişikliktir. Son olarak, (161)-(164) denklemleri, işlem kodu tarafından açıkça değiştirilmedikçe diğer parametrelerin aynı kaldığını belirtir.
Bununla birlikte EVM tam olarak 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 (opens in a new tab) 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ı (opens in a new tab) Python'da yazılmıştır. Python'da yürütme katmanı spesifikasyonları (opens in a new tab) 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.