Ethereum Virtual Machine

Kısaca EVM diye adlandırılan bu yapı sayesinde yazdığınız DAPP kodunuzu derleyebilir ve Ethereum ağına yollayabilirsiniz.

Solidity dili, Ethereum ağının geliştiricileri tarafından tasarlanmış ve Akıllı Sözleşme diye adlandırılan merkezsiz programların yazılmasını kolaylaştıran bir script dilidir. Solidity ile yazdığınız kod öncelikle EVM adlı sanal makine üzerine derlenmek için yollanır. EVM tamamen izole bir yapıdır ve Ethereum ağının ana omurgası üzerinde bir tür katman olarak tüm üçüncü parti akıllı sözleşmeleri yönetmekle yükümlüdür. Kontratın (yani programın) hükümlerinin işlenmesi ve gerekiyorsa sonlanması gibi kontrol işlemlerini de EVM gerçekleştirir. Bir başka deyişle, Ethereum ağı üzerindeki hesapları ve işlemleri EVM yönetir diyebiliriz.

Hesaplar

Ethereum ağında kullanılan iki tür hesap vardır. İlki hemen hepimizin bildiği ve kullanımımıza açık olan, standart ETH cüzdanlarda kullanılan ve “açık anahtar çiftleri (public)” tarafından kontrol edilen dış hesaplar. Ödeme aldığınız bir ETH adresiniz varsa bu kesinlikle ilk grup adreslere giriyor diyebilirim. İkincil hesaplar ise, hesapla birlikte saklanan kod tarafından kontrol edilen sözleşme hesaplarıdır. Yazdığınız Solidity kodu sizin cüzdan adresinizden türetilmiş adres de kullanabilir.

Bir dış hesabın adresi, genel anahtarlar tarafından belirlenirken, bir sözleşmenin adresi sözleşmenin yapıldığı sırada belirlenir (geliştiricinin sahip olduğu cüzdan adresinden ve bu adresten gönderilen işlemlerin adından türetilir, ki bunlara “nonce” da denir).

Hesabın bir Akıllı Sözleşme olduğuna bakılmaksızın (hesabın içerisinde bir kod saklayıp saklamadığına bakılmaksızın), iki tür hesap da EVM tarafından eşit değer ya da öncelikle ele alınır. Her hesap kalıcı nitelikte 256 bit anahtar-değer eşlemesine sahiptir. Dahası, her hesabın ETH değerinde bir bakiyesi vardır ve bu bakiye değeri işlemler sonucunda yine ETH cinsinde değişime uğrar.

İşlemler

Blockchain yapılarının genelinde işlemler mesajlaşma esasıyla gerçekleşir. Bu mesajlaşmalar da aslında cüzdandan cüzdana kripto para yollayarak yapılır. İkili veri (“faydalı yük” olarak adlandırılır) ve ETH içerebilir. Hedef hesap kod içeriyorsa, bu kod çalıştırılır ve sonucunda elde edilen veri yükü girdi olarak kabul edilir.

Eğer yapılan gönderimde bir alıcı hesabı tanımlanmamışsa EVM bu durumu geliştiricinin yeni bir akıllı sözleşme oluşturmak istediği şeklinde yorumlar. Böyle bir sözleşme yaratma işleminin yükü EVM bytecode olarak alınır ve çalıştırılır. Bu uygulamanın çıktısından oluşan veri blokları ise, sözleşmenin kodu olarak tanımlanır ve kalıcı olacak şekilde depolanır. Yani, ağa, bir sözleşme oluşturmak için sözleşmenin asıl kodunu göndermeseniz bile, yazdığınız kod derlenip çalıştırıldığında ortaya çıkan verinin gönderilecektir. Yani mutlaka bir mesajlaşma gerçekleşmek durumundadır.

Akıllı Sözleşme yazarken bir script dili kullandığımız için aklınıza web geliştiriciliği yapar gibi kod yazdığınız gelmesin. Javascript ile yazdığınızı kodu denemek istersiniz, kodunuzun sayfada nasıl duracağını merak edersiniz ve sürekli kodunuzu çalıştırıp çıktısına bakarsınız. Ancak Solidity ile yazdığınız kodu EVM’ye yolladığınızda EVM bu kodu hemen derleyip çalıştırmaz. Öncelikle sözleşmenin kodlanmasının bitmesini bekler. Bu yüzden DAPP’ınızı kodlaması bitmeden çağırmaya kalkmayın.

Gaz

Ethereum ağında gerçekleşen her bir mesajlaşma ya da yapmak istediğiniz her bir işlem, işlemi belirli bir miktarda gaz ile ücretlendirilir. EVM işlemi gerçekleştirirken, gaz belirli kurallara göre kademeli olarak değişkenlik gösterir. Gaz ücreti, işlemin yaratıcısı tarafından yani gönderen hesabından gaz_ücreti * gaz miktarında ödemek zorunda olduğu bir değerdir. Uygulamadan sonra bir miktar gaz kalırsa, kalan gaz miktarına tekabül eden ETH aynı şekilde gönderen hesabına iade edilir.

Verinin Saklanması

EVM, verileri depolama, bellek ve yığın adlı farklı alanlarda saklar. Her hesap, fonksiyon çağrıları ve işlemler arasında kalıcı olan, depolama adı verilen bir veri alanına sahiptir. Depolama, 256bit değeleri 256bit değerlerle eşleyen anahtar-değer ikilisini barındırır. Depolamayı bir sözleşme içinde belirtmek mümkün değildir. Depolamayı okumak pahalı bir işlemken değiştirmek çok daha büyük maliyetlere sebep olabilir. Bir sözleşme, kendisinden başka hiçbir depolamayı okuyamaz veya müdahale edemez. Böylece ağdaki diğer sözleşmeler güvende tutulmuş olur.

İkinci veri alanı ise, hafıza adını verdiğimiz alandır. Hafıza doğrusaldır ve bayt düzeyinde adreslenebilir, ancak yazma işlemi 8 bit veya 256 bit genişliğinde olabilirken, okuma işlemi 256 bit genişliğiyle sınırlıdır. Önceden dokunulmamış bir hafıza alanına erişirken bu alan yazıldığı alanın ötesine genişletilebilir. Bu genişleme sırasında ortaya çıkabilecek ekstra gaz maliyeti gönderici tarafından ödenmelidir. Bellek, büyüdükçe maliyet de artacaktır.

Mesaj Çağrıları

Sözleşmeler, diğer sözleşmeleri çağırabilir ya da sözleşmesiz hesaplara mesaj çağrısı ile ETH gönderebilir. Mesaj çağrıları, kaynak, hedef, veri taşıma yükü, ETH, gaz ve iade verilerine sahip olmaları nedeniyle işlemlere benzerler. Bu mantıkla bakıldığında, her işlem sırayla daha fazla çağrı yaratabilen üst düzey bir mesaj çağrısı kümesinden oluşur.

Bir sözleşme, kalan gazın ne kadarının iç mesaj çağrısı ile gönderilmesi gerektiğine ve ne kadarının gönderim sırasında kullanılacağına karar verebilir. İç çağrıda gaz dışı bir istisna olursa, bu, yığına eklenen bir hata değeriyle bildirilir. Bu durumda, yalnızca çağrı ile birlikte gönderilen gaz tüketilir. Solidity dilinde, bu gibi istisnaların oluşması varsayılan olarak manuel başka zincirleme istisnalar da yaratmaya meyilli olduğundan totalde yığınını “kabarcıklandıran” durum olarak nitelendirilir.

Çağrılar, 1024 bitlik alanlar ile sınırlıdır; bu, daha karmaşık işlemler için tekrarlamalı çağrılar yerine döngüler tercih edileceği anlamına gelir. Ayrıca, bir mesaj çağrısında gazın sadece 63 / 64’ü iletilebilir; bu, pratikte 1000 bit’ten daha az bir alan sınırlamasına neden olur.

Delegatecall / Çağrı Kodu & Kütüphaneler

Bir mesaj çağrısı ile temelde aynı anlama gelen delegatecall, hedef adresteki kodun arama sözleşmesi bağlamında yürütülmesi ve .msg.sender ve .msg.value değerlerinin değiştirilememesi gibi özellikleri ile mesaj çağrısının özel bir çeşidi olarak kabul edilir. Bu, bir sözleşmenin çalışması sırasında farklı bir adresten dinamik olarak kod yükleyebileceği anlamına gelir. Depolama, geçerli adres ve bakiye hala aranan sözleşmeye atıfta bulunurken, yalnızca kod aranan adresten temin edilir.

İşte, “kütüphane kullanımı” özelliğinin Solidity dilinde uygulanabilir olmasını mümkün kılan budur. Solidity dilinde kütüphanelerin kullanılması kompleks data yapısı ile başa çıkmak ve başka projelerde yeniden kullanılabilmek gibi büyük kolaylıklar sağlar.

Kayıtlar

Verileri tümüyle blok seviyesine kadar haritalayan özel indeksli bir veri yapısında depolamak mümkündür. Kayıt adı verilen bu özellik, kodda değinmiş olduğumuz olayları (events) uygulayabilmek için Solidity tarafından kullanılır. Sözleşmeler, oluşturulduktan sonra kayıt verilerine erişilemez, ancak zincirin dışından etkin bir şekilde erişilebilir. Kayıt verilerinin bir kısmı bloom filtrelerinde saklandığından, bu verileri etkin ve kriptografik olarak güvenli bir şekilde aramak mümkündür, böylece tüm zinciri indirmek zorunda kalmayan ağ elemanları (“hafif istemciler” olarak da bilinirler) bu kayıtlara erişim sağlayabilirler.

Çağrı Oluşturmak

Sözleşmeler, özel bir opcode kullanarak başka sözleşmeler bile oluşturabilir (bunu, hedef adresi boş bırakarak yaparlar). Bu arama çağrıları ve normal mesaj çağrıları arasındaki tek fark, açığa çıkan veri yükünün yürütülmesi ve sonucun kod olarak saklanarak arayan tarafın(yaratıcının) yığındaki yeni sözleşmenin adresini almasıdır.

Sözleşmeyi Devre Dışı Bırakmak ya da Yoketmek

Bir zincirden kodu kaldırmanın tek yolu, söz konusu adresteki bir sözleşmenin .selfdestruct özelliğini aktif hale getirmesidir. Bu adreste kalan ETH, önceden belirlenmiş bir hedefe gönderilir ve ardından depolama ve kod durumdan çıkarılır. Sözleşmeyi teoride çıkarmak iyi bir fikir gibi görünse bile, birileri kaldırılmış sözleşmelere ETH gönderirse, ETH sonsuza dek kaybedilme tehlikesi ile karşı karşıya kalır. Sözleşmeleri devre dışı bırakmak yerine, tüm fonksiyonların geri alınmasına neden olan bazı iç durumları değiştirerek bunları devre dışı bırakmalısınız. Bu hamle, ETH’yi derhal iade edeceğinden sözleşmeyi kullanımdan çeker.

Gördüğünüz gibi EVM, ağdaki hemen her işlemi yöneten bir derleyici ve yönetici katmandır. Solidity için vazgeçilmezdir. Çünkü kodunuzu çalıştırmanın başka bir yolu yoktur.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir