Sarı Kağıdın Ethereum Sanal Makinesi Spesifikasyonlarını Anlama
Sarı Kağıt(opens in a new tab), Ethereum'un resmi spesifikasyonudur. EIP süreci tarafından düzenlenen yerler dışında, her şeyin nasıl çalıştığına dair net bir açıklama içerir. Programcıların anlaşılır bulmayabileceği terimler içeren matematiksel bir kağıt olarak yazılmıştır. Bu kağıtta, spesifikasyonu ve dolayısıyla bağlantılı diğer matematiksel kağıtları nasıl okuyacağınızı öğreneceksiniz.
Hangi Sarı Kağıt?
Ethereum'daki her şey gibi, Sarı Kağıt da zamanla evrimleşiyor. Spesifik bir versiyona atıfta bulunabilmek için yazımı devam eden versiyonu yükledim. Kullanacağım bölüm, sayfa ve denklem numaraları o versiyona ait olacaktır. Bu dokümanı okurken farklı bir pencerede Sarı Kağıdı açık tutmak iyi bir fikir olabilir.
Neden Ethereum Sanal Makinesi?
Orijinal sarı kağıt, Ethereum'un geliştirme sürecinin başında yazılmıştı. Başlangıçta ağı korumak için kullanılan mutabakat mekanizmasını temel alan orijinal iş ispatını açıklamaktadır. Bununla birlikte, Ethereum Eylül 2022'de iş ispatını bırakıp hisse ispatı tabanlı istemciyi kullanmaya başladı. Bu öğretici, sarı kağıdın Ethereum Sanal Makinesi'ni tanıttığı bölümlere değinecektir. EVM, (DIFFICULTY işlem kodunun dönüş değeri dışında) hisse ispatına geçiş nedeniyle değiştirilmemiştir.
9 Yürütüm modeli
Bu bölüm (sayfa 12-14) daha çok EVM'nin tanıtımını içeriyor.
Sistem durumu terimi, sistemi çalıştırmak için bilmeniz gereken her şeyi içerir. Bu, tipik bir bilgisayarda bellek, kayıt içerikleri vs. anlamlarına gelir.
Turing makinesi(opens in a new tab), bir hesaplama modelidir. Aslında bir bilgisayarın basitleştirilmiş bir halidir ve normal bir bilgisayarın hesaplamaları yapma kabiliyetine sahip olduğu kanıtlanmıştır (bir bilgisayarın hesaplayabileceği her şeyi bir Turing makinesi de hesaplayabilir). Bu model neyin hesaplanabilir olduğuna ve olmadığına dair değişik teorileri kanıtlamayı kolaylaştırır.
Turing-tamam(opens in a new tab) terimi, bir bilgisayarın hesapları bir Turing makinesi gibi çalıştırabileceği anlamına gelir. Turing makineleri sonsuz döngülere girebilir ancak EVM giremez; çünkü gazı biter, yani EVM sadece yarı-Turing-tamam niteliğindedir.
9.1 Temeller
Bu bölüm EVM'nin temellerini ve diğer hesaplama modelleri ile nasıl benzerlik ve farklılıklarını gösterir.
Bir yığın makinesi(opens in a new tab), ara verileri kayıtlarda değil, yığın(opens in a new tab)da depolayan bir bilgisayardır. Bu, hata ve güvenlik açıklarının bulunma olasılığının az olması sayesinde uygulanması kolay olduğundan sanal makineler için tercih edilen mimaridir. Yığındaki bellek 256 bitlik kelimelere bölünür. Bunun seçilme sebebi, Keccak-256 karmalaması ve eliptik eğri hesaplamaları gibi Ethereum'un temel kriptografik operasyonları için uygun olmasıdır. Yığının sahip olabileceği maksimum boyut 1024 bayttır. İşlem kodları yürütüldüklerinde parametrelerini genelde yığından alırlar. Yığındaki elementleri yeniden düzenlemeye yarayan POP
(yığının başındaki öğeyi siler), DUP_N
(yığındaki n'inci öğeyi kopyalar) gibi işlem kodları vardır.
EVM'nin ayrıca çalıştırma sürecinde veri depolama amacıyla kullanılan bellek adında geçici bir alanı vardır. Bu bellek, 32 baytlık kelimeler halinde düzenlenmiştir. Her bellek konumu sıfırdan başlatılır. Yul(opens in a new tab) kodunu belleğe bir kelime eklemek için çalıştırırsanız, 32 baytlık bir belleği kelimedeki sıfırlı boş alan ile dolduracaktır, yani 0-29, 0x60'tan 30'a ve 0xA7'den 31'e konumlarındaki sıfırlarla yeni bir kelime oluşturur.
1mstore(0, 0x60A7)
mstore
, EVM'nin bellekle etkileşime girebilmek için sağladığı üç işlem kodundan biridir; belleğe bir kelime yükler. Diğer ikisi ise belleğe tek bir bayt yükleyen mstore8
ile bellekteki bir kelimeyi yığına taşıyan mload
'dur.
EVM ayrıca sistem durumunun bir parçası olarak korunan ve geçici olmayan ayrı bir depolamaya sahiptir; bu bellek, kelime dizileri olarak düzenlenir (yığındaki kelime adreslenebilir bayt dizilerinin aksine). Bu depolama, sözleşmelerin kalıcı verilerini tuttuğu yerdir, bir sözleşme sadece kendi depolamasıyla etkileşime girebilir. Depolama, anahtar-değer eşlemeleri şeklinde düzenlenir.
Sarı Kağıdın bu kısmında bahsedilmemiş olsa da, dördüncü bir bellek türü olduğunu bilmemizde fayda var. Çağrı verileri, bir işlemin data
parametresiyle aktarılan değerini depolamak için kullanılan bayt-adreslenebilir, salt okunur bir bellektir. EVM'nin calldata
yönetimine yönleik ö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), kod ile veriyi aynı bellekte depolar. EVM güvenlik sebebiyle bu standarda uymaz; geçici belleğin paylaşılması, program kodunun değiştirilmesini mümkün kılar. Bunun yerine kod, depolamaya kaydedilir.
Kodun bellekten yürütüldüğü sadece iki durum vardır:
- Bir sözleşme (
CREATE
(opens in a new tab) ya daCREATE2
(opens in a new tab)) kullanarak başka bir sözleşme oluşturduğunda, sözleşme oluşturucunun kodu bellekten gelir. - Herhangi bir sözleşmenin oluşturulma sürecinde, oluşturucu kodu çalışır ve yine bellekten asıl sözleşmenin kodunu döndürür.
İstisnai yürütüm terimi, güncel sözleşmenin yürütümünün durmasına sebep olan bir istisnayı ifade eder.
9.2 Ücretlerle ilgili genel bilgi
Bu bölüm, gaz ücretlerinin nasıl hesapladığını anlatır. Üç maliyet kalemi vardır:
İşlem kodu maliyeti
Spesifik işlem kodunun öz maliyeti. Bu değere ulaşabilmek için Ek H'de (sayfa 28, (327). denklemin altında) işlem kodunun maliyet grubunu ve (324.) denklemdeki maliyet grubunu bulun. Bu size bir maliyet fonksiyonu verir, bu da çoğu durumda Ek G'deki (sayfa 27) parametreleri kullanır.
Örnek olarak 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, iki sabit değerin de 3 olduğunu görürüz, bu da bize 3+3×⌈μs[2]÷32⌉ değerini verir.
Hala ⌈μs[2]÷32⌉ ifadesini çözmemiz gerekiyor. En dıştaki kısım olan ⌈ \<value> ⌉ tavan fonksiyonudur ve değerden küçük olmayan en küçük tam sayıyı verir. Örneğin ⌈2.5⌉ = ⌈3⌉ = 3. İç kısım μs[2]÷32 şeklindedir. 3. bölüme (Yöntemler) bakarsak, sayfa 3'te μ, makinenin durumudur. Makine durumu sayfa 13, bölüm 9.4.1'de açıklanmıştır. O bölüme göre yığın için makine durumu parametrelerinden biri s'dir. Hepsini birleştirdiğimizde μs[2], yığındaki 2. konumdur. İşlem koduna(opens in a new tab) bakarsak, yığındaki 2. konum, verinin bayt cinsinden boyutudur. Grup Wcopy, CODECOPY
(opens in a new tab) ve RETURNDATACOPY
(opens in a new tab) içindeki diğer işlem kodlarına bakarsak, işlem kodlarının da aynı konumda veri boyutları olduğunu görürüz. Yani ⌈μs[2]÷32⌉, kopyalanan veriyi depolayabilmek için gereken 32 baytlık kelimelerin sayısıdır. Toparlamak gerekirse, CALLDATACOPY
(opens in a new tab) işlem kodunun kalıtımsal maliyeti, kopyalanan veri kelimesi başına 3 gaz artı 3'tür.
Çalıştırma maliyeti
Çağrı yaptığımız kodun çalıştırma maliyetidir.
CREATE
(opens in a new tab) veCREATE2
(opens in a new tab) durumlarında, yeni sözleşmenin oluşturucusu.CALL
(opens in a new tab),CALLCODE
(opens in a new tab),STATICCALL
(opens in a new tab), ya daDELEGATECALL
(opens in a new tab) durumlarında, çağırdığımız sözleşme.
Bellek maliyetini genişletme
Bellek genişletme maliyeti (eğer gerekliyse).
- denklemde bu değer Cmem(μi')-Cmem(μi) olarak yazılmıştır. 9.4.1. bölüme baktığımızda μi değerinin bu bellekteki kelime sayısı olduğunu görürüz. Yani μi, bellekte işlem kodundan önce bulunan kelime sayısı ve μi', bellekte işlem kodundan sonra bulunan kelime sayısıdır.
Cmem fonksiyonu 326. denklemde tanımlanmıştır: Cmem(a) = Gmemory × a + ⌊a2 ÷ 512⌋. ⌊x⌋ taban fonksiyonudur. Bir değer verildiğinde o değerden büyük olmayan en büyük tam sayıyı verir. Örneğin, ⌊2.5⌋ = ⌊2⌋ = 2. a < √512, a2 < 512 ve taban fonksiyonunun sonucu 0 olduğunda. Yani ilk 22 kelime için (704 bayt), gereken bellek kelimesi sayısı arttıkça maliyet de doğrusal olarak artar. O noktanın ötesinde ⌊a2 ÷ 512⌋ pozitiftir. Gereken bellek yeteri kadar yüksek olduğunda gaz maliyeti bellek miktarının karesiyle orantılıdır.
Bu faktörlerin sadece kalıtımsal gaz maliyetini etkilediğini unutmayın. Ücret piyasasını ya da doğrulayıcılara yönelik son kullanıcının ne kadar ödemesi gerektiğini belirleyen ipuçlarını dikkate almaz; 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ütüm ortamı
Yürütme ortamları veri tabanında kayıtları oluşturan bir veri grubudur, I, blokzincirin durumu ya da ESM'nin bir parçası olmayan bilgiyi içerir.
Parametre | Veriye erişecek işlem kodu | Veriye erişecek 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), vs. | 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 , vs. |
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ştirme izni var mı yoksa statik olarak mı çalışıyor? |
- bölümün geri kalanını anlamak için birkaç parametre daha gereklidir:
Parametre | Anlatıldığı bölüm | Anlam |
---|---|---|
σ | 2 (2. sayfa, 1. denklem) | Blokzincirin durumu |
g | 9.3 (13. sayfa) | Kalan gaz |
A | 6.1 (8. sayfa) | Birikmiş yan durum (değişimler, işlem sonuna göre programlanmıştır) |
o | 9.3 (13. sayfa) | Çıktı - İç işlem durumunda (bir sözleşme bir diğerini aradığında) ve fonksiyonları görüntülemek için yapılan aramalarda (sadece bilgi istiyorken, yani bir işlem için beklemeye gerek yokken) döndürülen sonuçtur |
9.4 Yürütme ile ilgili temel bilgiler
Ön hazırlıkların hepsi tamam olduğuna göre, artık EVM'nin nasıl çalıştığı üzerinde çalışmaya başlayabiliriz.
137-142 denklemleri bize EVM'yi çalıştırmak için ilk şartları veriyor:
Sembol | Başlangıç değeri | Anlam |
---|---|---|
μg | g | Kalan gaz |
μpc | 0 | Program sayacı, yürütülecek yeni talimatın adresi |
μm | (0, 0, ...) | Bellek, tamamen sıfırlardan başlatılır |
μi | 0 | Kullanılan en yüksek bellek konumu |
μs | () | Yığın, başlangıçta boştur |
μo | ∅ | Çıktı, döndürülen veriyle (RETURN (opens in a new tab) ya da REVERT (opens in a new tab)) ya da onsuz (STOP (opens in a new tab) ya da SELFDESTRUCT (opens in a new tab)) durmazsak boş olan küme. |
denklem bize yürütüm sırasında her bir zaman noktasında dört olası durum olduğunu ve onlarla ne yapacağımızı söylüyor:
Z(σ,μ,A,I)
. Z, bir işlemin geçersiz bir durum geçişi yapıp yapmadığını test eden bir fonksiyonu temsil eder (bkz. istisnai durma). Değerlendirme sonucu Doğru olursa, yeni durum eskisiyle aynı olur (gazın yanması dışında) çünkü değişiklikler uygulanmamıştır.Yürütülen işlem kodu
REVERT
(opens in a new tab) ise yeni durum yine eski durumla aynıdır, bir miktar gaz kaybedilmiştir.Eğer işlem dizisi
RETURN
(opens in a new tab)) ile gösterildiği gibi tamamlanmışsa durum, yeni duruma güncellenir.1-3 uç koşullarından birinde değilsek, çalıştırmaya devam edin.
9.4.1 Makine Durumu
Bu bölüm makine durumunu daha detaylı bir şekilde anlatıyor. w'nin güncel işlem kodu olduğunu belirtiyor. Eğer μpc ||Ib|| kodun uzunluğundan daha azsa, o zaman o bayt (Ib[μpc]) işlem kodudur. Aksi halde işlem kodu, STOP
(opens in a new tab) olarak tanımlanır.
Bu bir yığın makinesi olduğundan(opens in a new tab), her bir işlem kodu tarafından çıkarılmış (δ) ve sokulmuş (α) öğeleri takip etmemiz gerekir.
9.4.2 İstisnai Durma
Bu bölüm, anormal bir sonuca ulaştığımızda verilen Z fonksiyonunu tanımlar. Bu bir Boole(opens in a new tab) fonksiyonudur, dolayısıyla bir mantıksal veya için ∨ işaretini(opens in a new tab) ve bir mantıksal ve için ∧ işaretini kullanır(opens in a new tab).
Bu durumlardan biri doğruysa bir istisnai durma söz konusudur:
μg < C(σ,μ,A,I), 9.2.Bölümde gördüğümüz gibi C gaz maliyetini belirten fonksiyondur. Sonraki işlem kodunu karşılayacak kadar gaz kalmamıştır.
δw=∅ Eğer bir işlem kodu için çıkarılmış öğe sayısı tanımlanmamışsa, işlem kodunun kendisi tanımsız olur.
|| μs || < δwYığın yetersizliği, güncel 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. Sıçramalar sadece varış noktası birJUMPDEST
(opens in a new tab) olduğunda geçerlidirler.w = JUMPI ∧ μs[1]≠0 ∧ μs[0] ∉ D(Ib) İşlem kodu
JUMPI
(opens in a new tab), durum doğru (sıfır değil), bu yüzden sıçrama gerçekleşmeli ve adres birJUMPDEST
(opens in a new tab) değil. Sıçramalar sadece varış noktası birJUMPDEST
(opens in a new tab) olduğunda geçerlidirler.w = RETURNDATACOPY ∧ μs[1]+μs[2]>|| μo || İşlem kodu
RETURNDATACOPY
(opens in a new tab). Bu işlem kodu yığın öğesinde μs[1] dönen veri arabelleğinden okunacak kaymadır ve yığın öğesi μs[2], verinin uzunluğudur. Bu durum, döndürülen arabelleğin son kısmının ötesini okumaya çalıştığınızda gerçekleşir. Çağrı verisi ya da kodun kendisi için benzer bir durum olmadığını dikkate alın. O arabelleklerin sonunun ötesini okumaya çalıştığınızda sadece sıfırlar elde edersiniz.|| μs || - δw + αw > 1024
Yığın taşması. Eğer işlem kodunu çalıştırmak 1024 öğeden de büyük bir yığın ile sonuçlanacaksa, iptal edilir.
¬Iw ∧ W(w,μ) Statik olarak mı çalışıyoruz (¬ olumsuzlama(opens in a new tab) ve Iw blokzincir durumunu değiştirmemize izin veriliyorken doğrudur)? Eğer böyleyse ve durum değiştirecek bir işlem deniyorsak bu gerçekleşemez.
W(w,μ) fonksiyonu daha sonra 150.denklemde anlatılacaktır. W(w,μ) aşağıdaki durumlardan biri doğruysa doğru olur:
w ∈ {CREATE, CREATE2, SSTORE, SELFDESTRUCT} Bu işlem kodları, yeni bir söyleşme oluşturarak, bir değer depolayarak ya da güncel sözleşmeyi yok ederek durumu değiştirirler.
LOG0≤w ∧ w≤LOG4 statik olarak çağrıldıysak günlük girdileri yayımlayamayız. Günlük işlem kodları
LOG0
(A0)(opens in a new tab) veLOG4
(A4)(opens in a new tab) arasında değişmektedir. Günlük işlem kodundan sonraki numara, günlük girdisinin kaç konu içerdiğini belirtir.w=CALL ∧ μs[2]≠0 Statikken başka bir sözleşme çağırabilirsiniz fakat ona ETH transfer edemezsiniz.
w = SSTORE ∧ μg ≤ Gcallstipend
SSTORE
(opens in a new tab) değerini Gcallstipend değerinden daha fazla gazınız yoksa çalıştıramazsınız (Ek G'de 2300 olarak tanımlanmıştır).
9.4.3 Sıçrama Varış Noktası Doğruluğu
Burada resmi olarak JUMPDEST
(opens in a new tab) işlem kodlarını tanımlıyoruz. Sadece 0x5B bayt değerini arayamayız, çünkü bir PUSH'un içinde de olabilir (ve bu yüzden bir işlem kodu değil, veridir).
(153). denklemde bir fonksiyon tanımlıyoruz, N(i,w). İlk parametre olan i, işlem kodunun konumudur. İkinci parametre olan w, işlem kodunun kendisidir. w∈[PUSH1, PUSH32] uygularsak bu, işlem kodunun bir PUSH olduğu anlamına gelir (kare parantezler başlangıç ve bitiş noktaları arasında bir değer olabileceğini ifade eder). Bu durumda bir sonraki işlem kodu i+2+(w−PUSH1)'dedir. PUSH1
(opens in a new tab) için iki bayt ilerlemeliyiz (PUSH'un kendisi ve bir bayt değeri), PUSH2
(opens in a new tab) için de 3 bayt ilerlemeliyiz çünkü kendisi iki baytlık bir değerdir, vs. Diğer tüm EVM işlem kodları sadece bir bayt uzunluğundadır, bu yüzden bütün diğer durumlarda N(i,w)=i+1.
Bu fonksiyon 152. denklemde DJ(c,i) öğesini tanımlamak için kullanılır; söz konusu öğe, c kodunun içindeki tüm geçerli sıçrama varış noktalarından oluşan bir kümedir(opens in a new tab) ve i işlem kodu konumundan başlar. Bu fonksiyon tekrarlı olarak tanımlanır. i≥||c|| ise bu, kodumuzun sonunda ya da sonrasındayız demektir. Daha fazla sıçrama varış noktası bulmayacağız, sadece boş kümeyi döndüreceğiz.
Tüm ayrı durumlarda yeni işlem koduna giderek kodun geri kalanına bakarız ve buradan başlayan kümeyi alırız. c[i] güncel işlem kodudur, bu yüzden N(i,c[i]) bir sonraki işlem kodunun konumudur. Bu yüzden DJ(c,N(i,c[i])), sonraki işlem kodunda başlayan geçerli işlem kodlarının bir kümesidir. Eğer şu anki işlem kodu JUMPDEST
değilse, sadece o kümeyi döndürün. JUMPDEST
ise, sonuç kümesine dahil edin ve döndürün.
9.4.4 Normal durma
Durma fonksiyonu H, üç farklı değer türü döndürebilir.
- Durma işlem kodunda değilsek, ∅ boş kümesini döndürün. Kural olarak bu değer, bir Boole yanlış değeri olarak yorumlanır.
- Eğer çıktı oluşturmayan bir durma işlem kodumuz varsa, (
STOP
(opens in a new tab) ya daSELFDESTRUCT
(opens in a new tab)), sıfır boyutlu baytlardan oluşan bir diziyi dönen veri olarak döndürün. Bunun boş bir kümeden çok daha farklı olduğunu not edin. Bu değer EVM'nin gerçekten durduğu anlamına gelir, yalnız okunacak bir dönen veri yoktur. - Eğer çıktı oluşturan bir işlem kodumuz varsa (
RETURN
(opens in a new tab) ya daREVERT
(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 başındaki değer (μs[0]) ilk bayttır ve ondan sonraki değer de (μs[1]) uzunluktur.
H.2 Talimat kümesi
EVM'nin son alt kümesine olan 9.5'e gitmeden önce, talimatların kendilerine bir bakalım. Bu talimatlar, 29. sayfada başlayan Ek H.2'de tanımlanmıştır. O spesifik işlem koduyla değişen olarak belirtilmeyen her şeyin aynı kalması beklenir. Değişen değişkenler \<something>′ olarak belirtilir.
Örnek olarak ADD
(opens in a new tab) işlem koduna bakalım.
Değer | Anımsatıcı | δ | α | Açıklama |
---|---|---|---|---|
0x01 | EKLE | 2 | 1 | Ekleme işlemi. |
μ′s[0] ≡ μs[0] + μs[1] |
δ yığından çıkardığımız değerlerin sayısıdır. Bu durumda iki tane var, çünkü en üst iki değeri ekliyoruz.
α geri ittiğimiz değerlerin sayısıdır. Bu durumda bir, toplam.
Bu yüzden yığının yeni başı (μ′s[0]), eski yığın başının (μs[0]) ve aşağısındaki eski değerin (μs[1]) toplamı olur.
Bu belge, "bıktırıcı bir listeyle" tüm işlem kodlarının üstünden geçmek yerine, sadece yeni bir şey tanıtan işlem kodlarını açıklıyor.
Değer | Anımsatıcı | δ | α | Açıklama |
---|---|---|---|---|
0x20 | KECCAK256 | 2 | 1 | Keccak-256 karmasını hesaplar. |
μ′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). Yine de, belleğin güncel sınırlarının ötesine kadar büyüyebilir, bu yüzden μi değerini güncellememiz gerekir. Bunu 29. sayfadaki 328. denklemde tanımlanan M fonksiyonunu kullanarak yaparız.
Değer | Anımsatıcı | δ | α | Açıklama |
---|---|---|---|---|
0x31 | BALANCE | 1 | 1 | Söz konusu hesabın bakiyesini alın. |
... |
Bakiyesini bulmamız gereken hesap: μs[0] mod 2160. Yığının başı adrestir, fakat adresler sadece 160 bit olduğu için modulo(opens in a new tab) 2160 değerini hesaplarız.
Eğer σ[μs[0] mod 2160] ≠ ∅ ise, bu adresle ilgili bilgi bulunduğu anlamına gelir. Bu durumda σ[μs[0] mod 2160]b, bu hesabın bakiyesidir. Eğer σ[μs[0] mod 2160] = ∅ ise, bu da adresin başlatılmadığını ve bakiyenin 0 olduğu anlamına gelir. Hesap bilgisi alanları listesini 4. sayfadaki 4.1. bölümünde bulabilirsiniz.
İkinci denklem olan A'a ≡ Aa ∪ {μs[0] mod 2160}, sıcak depolama (yakın zamanda erişilmiş ve muhtemelen önbellekte olan depolama) ile soğuk depolama (erişilmemiş ve muhtemelen daha yavaş ve alması daha pahalı olan depolama) arasındaki maliyet farkıyla alakalıdır. Aa, işlem tarafından önceden erişilmiş adreslerin listesidir, bu yüzden 8. sayfada 6.1. bölümde anlatıldığı üzere erişilmesi daha ucuz olmalıdır. EIP-2929(opens in a new tab)'da bu konuyla ilgili daha fazla okuma yapabilirsiniz.
Değer | Anımsatıcı | δ | α | Açıklama |
---|---|---|---|---|
0x8F | DUP16 | 16 | 17 | 16. yığın öğesini çoğaltın. |
μ′s[0] ≡ μs[15] |
Herhangi bir yığın öğesini kullanabilmek için onu çıkarmamız gerektiğini, yani üstündeki her yığın öğesini çıkarmamız gerektiğini unutmayın. DUP<n>
(opens in a new tab) ve SWAP<n>
(opens in a new tab) durumlarında bu, on altı değere kadar ekleme ve çıkarma yapmak mecburiyeti anlamına gelir.
9.5 Yürütme döngüsü
Artık her parçasına hakim olduğumuza göre, EVM'nin yürütme döngüsünün nasıl belgelendiğini sonunda anlayabiliriz.
(155). denklem, durum belirtildiğinde şunu söyler:
- σ (küresel blokzincir durumu)
- μ (EVM durumu)
- A (alt durum, değişiklikler işlem bittiğinde gerçekleşir)
- I (yürütme ortamı)
Yeni durum: (σ', μ', A', I').
(156) ila (158). denklemler yığını ve işlem kodu sebepleri yığında olan değişiklikleri tanımlar (μs). (159). denklem gazdaki değişimdir (μg). (160). denklem program sayacındaki değişikliktir (μpc). Son olarak, (161) ila (164). denklemler, diğer parametrelerin işlem kodu tarafından açıkça değiştirilmediği sürece aynı kalacaklarını belirtir.
Artık EVM tamamen açıklanmıştır.
Sonuç
Matematiksel gösterim kesindir ve Sarı Kağıdın Ethereum'un her detayını belirtmesini sağlamıştır. Yine de, bazı dezavantajları vardır:
- Sadece insanlar tarafından anlaşılabilir, bu da uygunluk testlerinin(opens in a new tab) manuel olarak yazılması zorunluluğunu doğurur.
- Programcılar bilgisayar kodunu anlar. Matematiksel gösterimleri anlayabilir ya da anlamayabilirler.
Belki bu sebeplerden yeni fikir birliği katmanı spesifikasyonları(opens in a new tab) Python'da yazılmaktadır. Python'da yürütüm katmanı spesifikasyonları(opens in a new tab) da mevcuttur fakat bunlar henüz tamamlanmamıştır. Sarı Kağıt eksiksiz olarak Python ya da başka bir dile çevrilmeden, Sarı Kağıt kullanımda kalmaya devam edecektir ve onu okuma olanağına sahip olmak faydalıdır.
Son düzenleme: @wackerow(opens in a new tab), 26 Mart 2024