
Giriş
Bu sınırlamaları aşmak için, Base gibi birkaç Katman 2 çözümü geliştirilmiştir ve bunlar ölçeklenebilirlik ve azaltılmış gaz giderleri ile kontrol edilmektedir. L2'ler Ethereum ana ağına göre önemli ölçüde ücret indirimlerine sahip olsa da, akıllı sözleşmelerin geliştiricileri, geliştirmelerinde gaz optimizasyonunu göz ardı edemezler.
Bu eğitim, test edilecek akıllı sözleşmelerde gaz maliyetini düşüren gelişmiş stratejiler aracılığıyla kullanıcı deneyimini birleştirmek ve daha rekabetçi, merkezi olmayan uygulamalar oluşturmak için çaba gösterecektir. Sağladıkları örnekler, basit sözleşmelerle simüle edilmiştir ve dağıtım maliyetleri sözleşmenin boyutuna göre büyük ölçüde farklılık gösterdiğinden, esas olarak çalışma zamanı gaz fiyatlarını dikkate almaktadır.
Gaz optimizasyonu, geliştiriciler, kullanıcılar ve uzun vadeli proje başarısı için önemlidir. Akıllı sözleşme gazının ekonomik kullanımı, protokollerin daha uygun maliyetli ve ölçeklenebilir olmasını ve hizmet reddi saldırıları gibi güvenlik tehditlerine daha az maruz kalmasını sağlayabilir.
Akıllı sözleşmelerin pratik uygulaması, her akıllı sözleşmenin kapsamlı ve sistematik bir şekilde denetlenmesini gerektirir.
Solidity Gaz Optimizasyonunun Önemi
Gaz optimizasyonu, akıllı sözleşmelerin, protokollerin ve projelerin yoğun ağ koşullarında çalışmasını sağlar ve bunları hem ucuz hem de verimli hale getirir. Sözleşme kodunu geliştirerek, olası güvenlik açıklarını ve protokolleri ortaya çıkarma olasılığı vardır ve kullanıcılar daha güvende hissederler.
Gaz optimizasyonu da geliştirmenin önemli bir odak noktasıdır. Bu, sadece hoş bir özellik değil, akıllı sözleşmelerin uzun vadeli başarısı ve güvenliğinin anahtarıdır. Nispeten düşük ücretlerle L2'ler üzerinde geliştirme yapmanın mümkün olması, gaz ücretlerinin rakiplerinden önemli ölçüde daha yüksek olmayacağı anlamına gelmez.
Tüm testler Foundry ve Solidity sürüm 0.8.13, yerel blok zinciri düğümü Anvil, forge test komutları ve 100 optimizasyon çalıştırması kullanılarak gerçekleştirilmektedir.
Profesyonel denetim firmaları tam güvenlik kontrollerine dahil edilmelidir, bu kılavuz yardımcı nitelikte olmalıdır.
Zincir Üzerindeki Verileri Azaltın
Non-Fungible Tokens (Değiştirilemez Tokenlar) 2021 yılında popüler hale geldi ve tamamen zincir üzerinde bulunan NFT'lere ilgiyi çekti. Zincir üzerinde bulunan NFT'ler, meta veriler ve görüntü referansları dahil olmak üzere zincir dışı verileri kullanan geleneksel NFT'lere kıyasla, tüm bilgileri doğrudan blok zincirine yerleştirir.
Bu tokenlarla iletişim kurmak oldukça maliyetlidir ve kullanıcılar ücretlerden etkilendiğinde hibrit çözümler varsayılan seçenek haline gelir. NFT'ler, oyunlar veya DeFi protokolleri geliştiriyor olsanız da, blok zincirinde depolanması gereken verilerin hangileri olduğunu ve her iki alternatifin avantaj ve dezavantajlarını her zaman göz önünde bulundurmalısınız.
Gaz kullanımını önemli ölçüde azaltın bilgileri zincir dışında depolayarak, daha az değişken depolama alanı gerektirin. Bunun için belirli bir yöntem, verileri gerçek zincir içi depolama yerine zincir dışında depolamak için olayları kullanmaktır.
İşlem gaz maliyetleri, olayların neden olduğu ek emit işlevleri nedeniyle artar; ancak bilgiler zincir üzerinde depolanmadığından, tasarruflar genellikle maliyetleri aşar.
Kullanıcıların doğru veya yanlış oy kullanmasına izin veren akıllı bir sözleşmeyi düşünün. İlki, kullanıcı oylarını zincir üzerinde yapıların içinde depolayan sözleşmedir. Foundry ile 100'den fazla yineleme içeren oy fonksiyonu testinin gösterimi, belirli gaz maliyetlerini gösterir.
Zincir üzerinde bilgi depolamayan, ancak oy verme işlevi çağrıldığında bir olay yayınlayan akıllı sözleşme ile karşılaştırın. Yeni oy verme işlevinde Foundry'yi 100'den fazla kez içeren bir test sonuçlar vermektedir.
Zincir üzerindeki verilerin azaltılması, ortalama gazı %90,34 oranında düşürdü.
Zincir dışı verilere zincir üzerinden erişmek için Chainlink işlevleri ve destek çözümleri, Base gibi en popüler L2 ağlarıyla entegre edilebilir.
Diziler Üzerinde Eşlemeler Kullanın
Solidity'de iki ana veri yapısı vardır: diziler ve eşlemeler.
- •Diziler, belirli endekslere atfedilen öğe kümelerini depolamak için kullanılır
- •Anahtar-değer eşlemeleri, benzersiz anahtarlar kullanarak verilere doğrudan erişimi destekleyen veri yapılarıdır.
Diziler vektörlerin ve diğer benzer verilerin depolanmasında yararlı olabilir, ancak gaz verimliliği nedeniyle genellikle eşlemeler tercih edilir. Eşlemeler, özellikle isim, cüzdan adresi veya hesap bakiyesi gibi isteğe bağlı verilerin gerekli olduğu durumlara en uygun şekilde uyarlanmıştır.
Dizileri veya eşlemeleri kullanırken gaz kullanımını anlamak için, ilişkili EVM opkodları tarafından kullanılan gazı incelemek gerekebilir. Opkodlar, Ethereum Sanal Makinesi'nin akıllı sözleşmelerin yürütülmesinde uyguladığı düşük seviyeli talimatlardır ve her opkodun bir gaz maliyeti vardır.
Dizinin değerlerine erişmek için, EVM opkodları tarafından kullanılan gaz birimi başına ödeme yapılmalıdır. Kullanıcı adreslerini ve karşılık gelen bakiyeleri dizi biçiminde depolamak, dizideki tüm öğeleri döngüye sokmayı, userAddress ve verilen argümanın eşleşip eşleşmediğini kontrol etmeyi ve eşleşme durumunda bakiyeyi döndürmeyi gerektirir.
Doğrudan kullanıcının belirli bakiyesine geçmek, dizideki tüm öğeleri incelemek zorunda kalmamayı sağlar. Diziler eşlemelerle değiştirildikten sonra, verilere erişmek için kullanılan gaz miktarı yüzde 89 azaldı.
Gaz Kullanımı Karşılaştırması: Diziler ve Eşlemeler
| Yöntem | Optimizasyon Öncesi | Optimizasyondan Sonra | Yakıt Tasarrufu |
|---|---|---|---|
| Veri Erişimi | 30.586 | 3.081 | %89 |
| Veri Ekleme | - | - | %93 |
Akıllı Sözleşme Gaz Maliyetlerini Azaltmak için Sabit ve Değişmez Kullanın
Bir başka optimizasyon ipucu da sabitler ve değiştirilemez değişkenler kullanmaktır. Değişkenleri değiştirilemez veya sabit olarak belirtirken, değerleri yalnızca sözleşme oluşturulduğu anda sağlanır ve daha sonra sağlanmaz.
Diğer değişkenlere kıyasla EVM'de depolama alanı kaplamazlar. Değerleri akıllı sözleşme bayt kodunda doğrudan kodlamak mümkündür, bu da maxSupply ve owner gibi değişkenlerin sabit veya değişmez anahtar kelimelere sahip olmaması nedeniyle veri depolama maliyetinin azaldığı anlamına gelir.
Testler 100 kez çalıştırıldığında, ortalama gaz maliyeti 112.222 birimdir. maxSupply ve owner, değiştirilmesi amaçlanmayan bilinen değerler olduğundan, depolama alanı kullanmayan maksimum arz ve sahibi beyan etmek en iyi seçimdir.
Sabit veya değişmez değişken testleri ortalama %35,89 tasarruf sağlar (112.222'den 71.940 gaz birimine).
Kullanılmayan Değişkenleri Optimize Edin
Akıllı sözleşmelerdeki değişkenleri optimize etmek, gaz optimizasyonu konusunda en bariz tavsiyedir. Ancak, çoğu durumda, kullanışsız değişkenler sözleşmenin yürütülmesi sırasında korunur ve bu da gereksiz gaz kullanımına yol açar.
Kullanılmayan tekil değişkenlerin kaldırılması, gaz maliyetlerinden tasarruf etmek için kullanılabilir. İşlevlerde tanımlanan ve işlenen ancak başka hiçbir yerde çağrılmayan kullanılmayan değişkenleri içeren sözleşmelerde ortalama %18 tasarruf sağlanabilir.
Kullanılmayan Değişkenlerin Optimizasyon Sonuçları
| Optimizasyon Aşaması | Gaz Kullanımı | Tasarruflar |
|---|---|---|
| Optimizasyon Öncesi | 32.513 | - |
| Optimizasyondan Sonra | 27.429 | %18 |
Solidity Gaz İadesi: Kullanılmayan Değişkenleri Silme
Kullanılmayan değişkenleri ortadan kaldırmak, değişkenlere veri bellekte depolanmadan tamamen hesaplandıktan sonra varsayılan değerler atama girişimidir. Örnek olarak, uint türündeki değişkenlerin varsayılan değeri 0'dır.
İşlevler sona erdiğinde işlevlerin değişkenlerini yok etmemek suretiyle, değişkenleri verilere atamak için ortalama gaz maliyeti 100.300 birimdir. Ortalama %19 gaz tasarrufu sil tuşunu kullanarak veri değişkenlerini kaldırmak (değişkenleri 0 olarak ayarlamak).
Akıllı Sözleşme Gaz Maliyetlerini En Aza İndirmek İçin Dinamik Diziler Yerine Sabit Boyutlu Diziler Kullanın
Akıllı sözleşme gaz maliyetlerini azaltmak için mümkün olduğunca eşlemeler kullanın. Bununla birlikte, dizilerin gerekli olduğu durumlarda, dinamik boyutlu diziler sınırsız olarak genişletilebildiğinden ve daha yüksek gaz maliyetlerine yol açtığından, sabit boyutlu diziler gaz açısından daha ekonomiktir.
Dinamik diziler genişletilebilir, bu nedenle EVM uzunlukları izlemeli ve yeni öğeler eklendiğinde bunları yenilemelidir.
Dinamik boyutlu dizileri tanımlayan ve bunları updateArray işlevleriyle güncelleyen kodu göz önünde bulundurun. Require ifadeleri, sağlanan indekslerin sabit boyutlu bir dizi aralığı içinde olmasını sağlar. Bir test 100 kez tekrarlandığında, kullanılan ortalama gaz miktarı 12.541'dir.
Dizileri sabit boyut 5 olarak değiştirmek, uzunluğu 5 olan sabit boyutlu uint256 tipi diziler oluşturur. EVM, durum değişkeni boyutu 5 olan fixedArray'in 5 yuvaya sahip olduğunu bilir ve uzunluk depolama alanında saklanmaz. Dinamik dizileri sabit dizilerle değiştirmek %17,99 gaz tasarrufu sağlar.
Akıllı Sözleşmelerinizi Bugün Optimize Edin
Base ve diğer L2 zincirlerinde maliyetleri %90'a kadar azaltmak için bu gaz optimizasyon tekniklerini uygulamaya başlayın.
uint256 yerine uint8 kullanma
Bu, EVM'nin çalışması nedeniyle uint256'dan daha az verimli ve kullanımı daha pahalı olabilir. EVM'nin 256 bitlik kelime boyutları vardır. 256 bitlik tamsayılarla (uint256) yapılan işlemler, EVM kelime boyutuna uydukları için en verimli olanlardır. Daha küçük türler (uint8 gibi) ise Solidity derleyicisinin, daha küçük türleri tek bir 256 bitlik depolama yuvasına sığdırmak için ek işlemler oluşturmasını gerektirir.
Genel olarak, uint8 gibi küçük türler depolama açısından faydalı olabilirken (bir dizi küçük tür, 256 bitlik bir depolama yuvası ile tek bir işlemde paketlenebilir), daha küçük türlerin yalnızca depolamaya yardımcı olduğu görülmüştür. Hesaplamalar yapmak için uint256'ya dönüştürme ve uint256'dan dönüştürme işlemleri, depolama tasarrufunu geçersiz kılabilir.
256 Bit'ten Küçük Değişkenleri Birleştirme
256 bitten küçük değişkenleri birleştirmek genellikle 256 bitlik değişkenler kadar verimli değildir. Ancak, birlikte çalışabilir olmayan durumlar, daha küçük boyutlarda daha az güçlü türlerin kullanılmasını gerektirir, örneğin depolanmak için 1 bayt veya 8 bit tüketen boole değişkenleri.
Daha az güçlü türler kullanıldığında, depolama alanını göz önünde bulundurarak durum değişkenleri tanımlamak mümkündür ve Solidity bunları bir araya toplayabilir ve aynı depolama yuvasını kullanarak saklayabilir. Değişkenlerin bir araya toplanmasının avantajı genellikle bellek işlemlerinde veya yığın işlemlerinde değil, depolama işlemlerinde dikkate alınır.
İki yönlü kombinasyon boyutları 16 bit, yani tek bir depolama yuvasını depolama kapasitesinden 240 bit daha küçük olduğundan, Solidity, durum değişkenlerini depolamak için çok sayıda yuva gerektirmeden dağıtım gazı kullanımını en aza indirmek için değişkenleri aynı yuvaya paketlemek için kullanılabilir.
Değişken bildirimlerini yeniden düzenlemek, ortalama %13 gaz optimizasyonu sağlar.
Değişken Paketleme Sonuçları
| Aşama | Gaz Kullanımı | Tasarruflar |
|---|---|---|
| Ön optimizasyon | 1.678 | - |
| Optimizasyon sonrası | 1.447 | %13 |
Harici Görünürlük Değiştiricisini Seçin
Akıllı sözleşme gazını en üst düzeye çıkarmak için, işlevlerin doğru görünürlüğünü seçmek mantıklıdır. Harici görünürlük değiştiriciler, genel işlevlerin argümanlarını yönetme şekli ve verilerin işlevlere aktarılma şekli nedeniyle, gaz kullanımında genel işlevlerden daha verimli olabilir.
Harici işlevler, EVM'de işlev çağrısının parametrelerini içeren salt okunur geçici bir alan olan calldata'ya erişebilir. Genel işlevler çağrılabilir:
- •Harici olarak (calldata kullanılarak bir işlem tarafından harici olarak çağrıldıklarında)
- •Dahili olarak (calldata kullanılarak bir sözleşme içinde çağrıldıklarında)
İşlevler halka açık olduğundan, bellekteki dizileri almaları gerekir ve bu, diziler büyükse gaz maliyetinde pahalı olabilir. İşlevleri hariciye geçirmek, calldata'da dizilerin alınmasını sağlar, bu da büyük dizilerin olduğu durumlarda daha uygun maliyetlidir ve her çağrı başına ortalama %0,3 gaz birimi tasarrufu sağlar.
Aynı değeri yeniden okumak için depolama
Gaz tasarrufu için iyi bir teknik, depolamada aynı değeri birçok kez okumamaktır. Depolamadan okuma, bellekten okumaya göre daha maliyetlidir. Depolamadaki aynı değişkenleri birçok kez yeniden okumak ve gerekli olmadığında depolamaya yazmak, akıllı sözleşmelerde gaz israfına neden olabilir.
Bu, fonksiyonların başında bellekte bulunan değişkenleri tanımlayarak ve onlara sayı değişkenlerinin değerlerini vererek önlenebilir.
Bu, sumNumbers işlevleri tarafından tüketilen gazın %17'sini tasarruf sağlar, ancak dizi ne kadar büyükse, yineleme sayıları ve kullanılan gaz da o kadar fazla olacaktır.
Önbellekleme Değişkenleri Sonuçları
| Aşama | Gaz Kullanımı | Tasarruflar |
|---|---|---|
| Optimizasyon Öncesi | 3.527 | - |
| Optimizasyondan Sonra | 2.905 | %17 |
Değişkenleri Varsayılan Değerlerle Başlatmayın
Değişkenleri başlatmadan (yani, onlara bir başlangıç değeri atamadan) durum değişkenleri olarak bildirirken, bu değişkenler otomatik olarak varsayılan değerlere başlatılır:
- •uint: 0
- •bool: false
- •adres: adres(0)
İkincisi, değerleri varsayılan olarak belirlemek ve kullanıcı sistemle etkileşime girdiğinde bunları güncellemekten daha ucuzdur, ki bu gaz açısından verimli değildir. Değişken başlatma olmadan, optimizasyon ortalama %4 gaz tasarrufu sağlar.
Solidity Derleyici Optimizasyonunu Destekleyin
Solidity, derlenen kodu optimize etmek için kolayca değiştirilebilen ayarlara sahip derleyiciler içerir. Optimize derleme, kodu optimize etmek ve çalıştırmak için daha az gaz gerektiren daha ucuz biçimlere dönüştürmek için yüzlerce kez çalıştırılır.
Derleyiciler, dağıtım ve çalışma zamanı maliyetleri arasında uygun bir denge sağlamak için ayarlanabilir. Çalıştırma komutlarını kullanarak çalıştırılacak sözleşmelerin tahmini sayısını tanımlama:
- •Sözleşmeyi uygularken düşük gaz fiyatları açısından daha yüksek seviyeler daha uygundur
- •Sözleşme dağıtımında gaz maliyetlerini azaltmak için sayıların az olması en uygunudur.
Optimize flags plus the value of run=200, derleyicilere incrementCount işlevlerini 200 kez çalıştırırken gaz tasarrufu için kodu optimize etmelerini söyler. Bu tür ayarları uygulamanın benzersiz gereksinimlerine göre sınıflandırın.
Bonus Solidity Gaz Optimizasyonu: Montaj
Solidity'de akıllı sözleşmeler yazarken, bunlar EVM opkodlarının bir dizisi olan bayt kodlarına derlenir. Assembly ile, opkodlarla daha uyumlu seviyelerde çalışan kodları kolayca yazabilirsiniz ve bazı durumlarda, opkodları manuel olarak optimize etme yeteneği, Solidity bayt koduna göre bir avantaj sağlar.
Bu kadar düşük seviyede kod yazmak en kolay iş olmasa da, opkodları manuel olarak optimize edebilme avantajı vardır ve bu nedenle genellikle Solidity bayt koduna kıyasla daha iyidir. Bu optimizasyon seviyesi, sözleşmenin yürütülmesinde daha fazla verimlilik ve etkinlik sağlar.
İki fonksiyonun iki sayıyı topladığı basit durumlarda bile, düz solidity ve assembly sürümleri arasında bazı farklılıklar olacaktır, ancak assembly sürümleri daha ucuzdur.
Base gibi L2'lerde projelerin uygulanması, kullanıcıların protokolleri kullanma maliyetlerinin daha düşük olacağı anlamına gelir, ancak gaz optimizasyon tekniklerini uygulamak geliştiricilerin görevidir. Bu ipuçları, işlem maliyetlerini önemli ölçüde azaltabilir, ölçeklenebilirlik sağlayabilir ve genel olarak sözleşmenin verimliliğini artırabilir.
Assembly, gaz kullanarak akıllı sözleşmelerin yürütülmesini optimize etmek için kullanılabilir, ancak Assembly sürümlerinin güvenli olmayan kodların oluşturulmasına neden olabileceği durumlar olabilir. Akıllı sözleşmelerin dağıtılmadan önce sözleşmelerin incelenmesinde akıllı sözleşme güvenlik uzmanlarının görevlendirilmesi konusunda sağlam öneriler bulunmaktadır.


