1. Anasayfa
  2. Akıllı Sözleşme

Solidity Gaz Optimizasyonu

Solidity EXTREME gaz optimizasyon yöntemleri

Solidity Gaz Optimizasyonu
Solidity Gaz Optimizasyonu
0

Solidity Gaz Optimizasyonu

Gaz optimizasyonu Akıllı Sözleşme Geliştirmenin en hassas detaylarından bir tanesidir. Şöyle ki, sadece bununla ilgilenen, bu alanda uzmanlaşan Solidity Geliştiricileri var, sayıları da artmalı.

Bu makalede, akıllı sözleşme çağrılarınız ve konuşlandırmanızda gazı optimize etmek için bilinen nitelikli teknikleri göstereceğiz.

  • Hangi yöntemin yararlı, hangi yöntemin yararsız olduğunu göreceğiz.
  • Her yöntemi kullanarak ne kadar gaz tasarrufu yapabileceğinizi göreceğiz.
  • Bir katman listesi kullanarak tüm yöntemleri sıralayacağız. (A = mükemmel, D= yararsız/zararlı)

Mümkün oldukça detaylı biçimde aktaracağız.

Hadi Başlayalım!

▶ 1. Dağıtım optimizasyonu ve Çağrı optimizasyonu

İlk başta, bir dAPP’de gazı optimize etmenin 2 yolu olduğunu bilmelisiniz .

1. Dağıtım maliyetlerini optimize etme

Bir akıllı sözleşme dağıtma maliyetini optimize edebilirsiniz.

Maliyet : 21000 gas (işlem oluşturmak için) + 32000 gas (sözleşme oluşturmak için) + YAPICI YÜRÜTME + DAĞITILAN BAYTLAR * 78.125

Solidity Gaz Optimizasyonu

Yani bir akıllı sözleşmeyi devreye almak için en az 53000 gas harcarsınız.

Gaz maliyetlerini en aza indirmek için, bir akıllı sözleşmenin boyutunu ve yapıcının maliyetini en aza indirmeniz gerekir.

2. Her işlev çağrısını optimize edin.

Akıllı sözleşmenizdeki her işlevi çağırmanın maliyetini de optimize edebilirsiniz.

Maliyet, 21000 gas (işlem oluşturmak için) + işlev yürütme maliyetine eşittir.

Dolayısıyla amaç, işlev yürütme maliyetini azaltmak olacaktır.

Bu 2 optimizasyon yönteminin aynı olmadığını unutmayın!!

Çoğu zaman, daha büyük bir Solidity kodu dağıtabilirsiniz (böylece daha yüksek dağıtım gaz maliyetiyle), ancak her işlev çağrısı için daha optimize edilmiş olursunuz. (Yani daha düşük arama gazı maliyetiyle)

Hangi optimizasyon türünü seçmeniz gerekiyorsa, kullanmanız gerekir.

Dağıtım yalnızca bir kez yapıldığından ve kullanıcı deneyimi geliştirileceğinden, her işlev çağrısını optimize etmenizi şiddetle tavsiye ederim. (akıllı sözleşme boyutunuz 24Kb sınırını aşmadığı sürece)

▶ 2. Sıralama Gazı optimizasyon yöntemleri

Bir katman listesi kullanarak tüm gaz optimizasyon yöntemlerini sıralayacağız. (Çünkü 21000 gaslık işlemde 2 gas tasarruf etmek ile 10000 gas tasarruf etmek arasında fark vardır .)

  • Katman A: Bu kuralları bilmiyorsanız, GERÇEK bir solidity geliştiricisi değilsiniz.
  • Katman B: Temel, tüm geliştiriciler tarafından bilinmelidir.
  • Katman C: bazen yararlı olabilir, geliştiriciler tarafından da bilinmelidir.
  • Katman D: Yararsız/zararlı, kullanmayın (ne yaptığınızı bilmiyorsanız). Ya zamanınız ya da akıllı sözleşmenin güvenliği konusunda özgürsünüz.

▶ Katman A: olmazsa olmaz

A seviyesinde, şaşırtıcı bir şekilde , sizi gazdan kurtarmak için herhangi bir “kolay” ipucu ve işaret YOKTUR, bunun yerine…

★ A1 : Her bir EVM işlem kodunun ne kadara mal olduğunu bilmek.

İşte en maliyetli gas operasyon kodlarından 6 tanesi (en çok kullanılanlar arasında akıllı sözleşmeler):

  • CREATE/CREATE2 -> Bir akıllı sözleşme dağıtır. ( 32000 gaz)
  • SSTORE -> Depoda bir değer depolar. ( Slota girilmemişse 20000 gas, aksi halde 2900 gas.)
  • EXTCODESIZE -> Bir akıllı sözleşme kodunun bayt cinsinden boyutunu alın. ( Daha önce girilmemişse 2600 , yoksa 100 gaz)
  • BALANCE (address(this).balance), EXTCODESIZE ile aynı.
  • SLOAD -> Depolamadaki bir değere erişin. ( Aksi takdirde 100 gazdan önce erişilmezse 2100 gaz )
  • LOG4 -> 4 konu ile bir etkinlik oluşturun. ( 1875 gazı)

Esasen bu rakamlar tahmindir. Bazıları duruma göre değişiklik gösterebilir.

Her işlem kodunun ne kadara mal olduğunu açıklayan en iyi web sitesi evm.codes , çok iyi açıklanmış.

Bunu bilirseniz, Solidity programlama dilini daha iyi anlarsınız ve her bir kod satırının size maliyetinden çok daha “daha iyi” bir sezgiye sahip olursunuz.

A2 Değiştiriciyi görüntüleyin

Bu oldukça açık, ancak yine de bazı “geliştiriciler” görüyorum, gerekli işlevleri görünüm olarak işaretlemeyin…

function getBalance() external view {
    return balance;
}

Depoya yazmıyorsanız akıllı sözleşmeyi aradığınızda gas maliyetlerinizi kolayca 0’a düşürebilirsiniz. (Üstelik yanıt için 5-20 saniye beklemeniz gerekmez)

A3 Solidity Programlama Dilini Anlayın

Daha genel olarak, Solidity Dilinin nasıl çalıştığını anlamanız gerekir, gaz tasarrufu gibi özel alanlar birçok eğitimde anlatılmadığı için bu alanda insan gücüne ihtiyaç var, bu gibi alanları keşfederek içeriye dalın.

Solidity Dili ÇOK kolaydır, öğrenilecek çok sınırlı sayıda şey vardır. (Şimdilik) Yaklaşık 1-2 yıl içinde solidity dilinin neredeyse tamamını öğrenmek mümkün iken 100 yılda bile C++’da tam olarak ustalaşamazsınız.

A4, bilgisayar bilimlerinde/algoritmalarda iyi olur.

Farklı algoritmaların nasıl çalıştığını, nasıl optimize edilebileceğini ve “karmaşıklığın” ne olduğunu bilmeniz gerekir.

Bu konuda Solidity Programlama Diline Giriş kitabımın önsözünde de belirttiğim ve sevilen bir detayı sizinle paylaşayım. Bilgisayar Bilimlerinin temelini öğrenmek için David J. Malan tarafından oluşturulan Harvard Üniversitesi CS50 kodlu Bilgisayar Bilimine Giriş dersini izlemenizi tavsiye edebilirim. Eğer İngilizce bilginizin yeterliliği konusunda handikapınız varsa “kodluyoruz” ekibinin emekleri ile David J. Malan ‘ın da soru-cevap oturumlarına dahil olduğu dilimize kazandırılmış haline erişmelisiniz.

▶ Katman B : Yararlı

Bu ipuçları ve püf noktaları size iyi miktarda gaz tasarrufu sağlayabilir ve mümkün olduğunca uygulanmalıdır.

not_optimized() işlevi bayt kodunda optimized() işlevinden önce yer aldığından,
optimize() işlevini çağırmak, aynı kodla (22 gaz daha fazla) not_optimized() işlevinden daha pahalıdır, bu nedenle optimized() işlevine yapılan her çağrıda 22 gas çıkarılabilir…

B1 Harmanlama işlemleri (Tasarruf edilen gaz: 21000 gaz * toplu işlemler)
Blok zincirinde tek başına bir işlem göndermek çok fazla gaza mal olur (kesin olarak 21000 gaz), bu nedenle kullanıcılarınız için toplu işlem yapmanın bir yolunu bulabilirseniz, bu size iyi miktarda gaz tasarrufu sağlayabilir.

★ Depolama yuvasının B2 değişiklik siparişleri (konuşlandırma sırasında 20 000 gaz tasarrufu)
Ethereum deposu 32 baytlık yuvalardan oluşur, sorun yazmanın pahalı olmasıdır. (“soğuk” yazı kullanılarak 20000 gaza kadar)

Diyelim ki 3 değişkeniniz var:

uint128 a; //Slot 0 (16 bytes)
uint256 b; //Slot 1 (32 bytes)
uint128 c; //Slot 2 (16 bytes)

3 farklı depolama yuvası kullanırlar:

uint256 b; //Slot 0 (32 bytes)
uint128 a; //Slot 1 (16 bytes)
uint128 c; //Slot 1 (16 bytes)

Ancak 3 yuvayı iyi hizalarsak 1 yuvadan tasarruf edebiliriz. (a ve c değişkeni aynı yuvada olacaktır)

Bu nedenle dağıtımda 1 daha az kullanılan yuvadır. (Böylece 20 000 gaz tasarrufu sağlanır)

Dahası, c değişkenine erişmek istiyorsanız, ancak b değişkenine zaten erişilmişse. Sıcak bir erişim olarak sayılacak (halihazırda erişilen bir depolama yuvasına erişim), bu nedenle size oldukça önemli olan 2900 gaz yerine 1000’e mal olacak.

Solidity Programlama Dilinde Depolama konusunu anlamadı iseniz mutlaka okumanız gereken “Solidity Eğitimi Depolama Hakkında Her Şey” içeriğini mutlaka göz atın!

B3 Optimize Ediciyi Kullanın (Tasarruf edilen gaz: konuşlandırma ve arama sırasında %10–50)
Solidity yerleşik optimize ediciyi kullanabilirsiniz.

Bu, herhangi bir yeni kavram öğrenmeden çok fazla benzin tasarrufu yapmanın çok basit bir yoludur. “Optimizasyonu etkinleştir” onay kutusunu işaretlemeniz gerekir.

Solidity yerleşik optimize ediciyi

1’e yakın bir değer, gaz maliyetini optimize eder, ancak maksimuma (2³²-1) yakın bir değer, işlev çağrılarını optimize eder.

Çoğu durumda varsayılan değeri (200) kullanabilirsiniz.

B4 array yerine mapping kullanır (değer başına 5000 gaz tasarrufu)

mapping genellikle array ‘den daha ucuzdur, ancak bunları yineleyemezsiniz.

  • not_optimised() fonksiyonu gas kullanımı: 48409 gas
  • optimised() fonksiyonu gas kullanımı: 43400 gas

B5: Assert yerine require kullanın

Assert, test etme amaçları dışında KULLANILMAMALIDIR. (çünkü iddia başarısız olduğunda, require aksine gaz iadesi YAPILMAZ)

B6: Kendi kendini yok etme özelliğini kullanın (24000 gaza kadar tasarruf edin)
selfdestruct() işlevi, akıllı sözleşmeyi yok eder ve 24000 gazı iade eder.

Başka bir akıllı sözleşmeyi devreye almak gibi daha karmaşık bir işlemde, bir miktar gazdan tasarruf etmek için akıllı sözleşmede selfdestruct() işlevini çağırabilirsiniz.

B7: Daha az harici arama yapın (tasarruf edilen miktar: değişken)
Sadece zorunlu olduğunuzda başka bir sözleşmeye çağrı yapın.

B8: Ölü kodu arayın (açılırken değişken miktarda gaz tasarrufu sağlar)
Bazen, geliştiriciler aşağıdaki gibi gereksiz kodları kaldırmayı unutur:

require(a == 0)
if (a == 0) {
  return true;
} else {
  return false
}

Bu, bazı geliştiricilerin işe yaramaz parçaları çıkarmayı unutabileceğini gösteren bir döküm örneğidir.

B9: sabit değişkenler kullanır (konuşlandırmada 15000 gaz tasarrufu sağlar)
Mümkün olduğunda depolama değişkenleri için sabit kullanır.

  • not_optimised ile gaz kullanımı : 116800 gas
  • optimised ile gaz kullanımı : 101013 gas

B10: olaylarda veri depolama (işlev çağrısında 20 000’e kadar gaz tasarrufu)
Zincirdeki verilere sağlam bir şekilde erişmeniz gerekmiyorsa, olayları kullanarak saklayabilirsiniz.

pragma solidity ^0.8.7;
contract Test {
address store; 
    event Store(uint256 indexed key,address indexed data);
    function optimised() external {
       emit Store(1,0xaaC5322e4***5631C2AeBc0);
    }
function not_optimised() external {
       store = 0xaaC5322e***C5631C2AeBc0;
    }
}
  • not_optimised() ile gaz kullanımı : 43353 gas
  • optimised() ile gaz kullanımı: 22747 gas

▶ Katman C : Neden olmasın ama hayatınızı değiştirmeyecek

Bu ipuçları size makul miktarda gaz tasarrufu sağlayabilir ve size hiçbir maliyeti yoktur.

C1 Solidity Dilinde statik boyutlu tip kullanın (yaklaşık 50 gaz tasarrufu)
Statik boyut türleri (bool, uint256, bytes5 gibi), dinamik boyut türünden (dize veya bayt gibi) daha ucuzdur.

  • not_optimised() ile gaz kullanımı: 21255 gas
  • optimised() ile gaz kullanımı: 21227 gas

C2 Soğuk erişime karşı sıcak erişim (70 tasarruf edilen gaz)

Aynı depolama değişkenine 2 kez erişmeyin.

  • not_optimised() işlevi gaz kullanımı: 23412 gaz
  • optimize edilmiş() işlevi gaz kullanımı: 23347 gaz

Halihazırda soğuk erişimi optimize eden EVM sayesinde fazla tasarruf etmeyin.

C3: memory yerine calldata kullanma (çağrı başına 450 gaz tasarrufu)

  • not_optimised() işlevi gaz kullanımı: 22442 gas
  • optimised() işlevi gaz kullanımı: 21994 gas

C4: İndekslenmiş olayları kullanın (konu başına fonksiyon çağrısında 62 gaz tasarruf)

Her etkinliği aşağıdaki gibi dizine eklenmiş olarak işaretleyebilirsiniz:

İndekslenmiş olay, olayların daha kolay aranmasını sağlar.

contract Test {
    event Testa(address a,address b);
    event Testa2(address indexed a,address indexed b);
    
    function not_optimised() external {
        emit Testa(0x..., 0x...);
    }
    function optimised() external {
        emit Testa2(0... ,0...);
    }
}

Burada optimizeised() işlevi not_optimised() işlevinden 135 daha az gaz kullanır.

C5: Çağrıların sırasını değiştirme (çağrı başına 20–2000 gaz tasarrufu)
Önemli notta belirtildiği gibi:

Her sözleşmeye akıllı sözleşme diyebilirsiniz, msg.data‘da işlevin imzasını sağlarsınız. (keccak256 hash fonksiyonunun ilk 4 baytı).

İlk olarak EVM, hangi işlevin yürütüleceğini görmek için bu imzayı “değiştirecek“.

switch(msg.data[0:4]) { // imzayla karşılaştır
    case 0x01234567: go to functionA;
    case 0x11111111: go to functionB; // 22 daha fazla gaz maliyeti..
    case 0x4913aaaa: go to functionC; // 22+22 daha fazla gaz maliyeti..
    ...
}

Bir miktar gas (22 gas) kullanan imza hesaplamasına kıyasla, imzanın ilk sırada olmasını sağlayarak (adını değiştirerek) en çok çağrılan işlevi switch() öğesinin ilk sırasına yerleştirmeniz gerekir.

C6: i = i+1 yerine i++ kullanır (her aramada 62 gaz tasarrufu sağlanır)
Bu kulağa şaka gibi geliyor ama işe yarıyor gibi görünüyor. :)

  • not_optimised() işlevi gaz kullanımı: 21401 gas
  • optimised() işlevi gaz kullanımı: 21339 gas

C7: Depolamada uintXX yerine uint256 kullanın (çağrı başına 55 gaz tasarrufu)
EVM, depolamaya veri yazmak/erişmek için 32 bayt (256 bit yuva) kullanır, uint256‘dan daha küçük türler kullanarak, EVM’nin dönüştürmeyi sağlamak için ek işlemler gerçekleştirmesi gerekir.

Veri depolamak için uint8 yerine uint256 kullanmak daha iyidir.

  • not_optimised() işlevi gaz kullanımı: 43353gas
  • optimised() işlevi gaz kullanımı: 43298 gas

C8: Özel bir hata oluşturun (çağrı başına 24 gas tasarrufu)

Solidity‘de özel bir hata oluşturabilir ve aşağıdaki gibi onunla geri dönebilirsiniz.

  • not_optimised() işlevi gaz kullanımı: 21476 gaz
  • optimised() işlevi gaz kullanımı: 21474 gaz

C9: Bir tuple (a, b) = (b, a) kullanarak 2 değişkeni değiş tokuş etmek (her aramada 5 gaz tasarrufu sağlar)

  • not_optimised() işlevi gaz kullanımı: 21241 gaz
  • optimised() işlevi gaz kullanımı: 21236 gaz

▶ Katman D : Yararsız/Zararlı

Orada gaz uçlarını optimize etmek işe yaramaz, az miktarda gaz tasarrufu için zaman kaybetmeyin, zaten 21000 gaz işlemi tarafından gölgelenecektir.

D1: kontrolsüz kullanım (tasarruf edilen gaz: 150/çalışma)
Solidity 0.8.0’dan beri + * / — gibi işlemler taşma/taşma varsa her seferinde kontrol edilir.

Ancak bir taşma/dökme (overflow/underflow) olup olmadığını doğrulamak için biraz gaza mal olur.

Tek bir işlev çağrısında (döngüler için olduğu gibi) çok fazla işlem yapmadığınız sürece, denetlenmemiş kullanmamalısınız.

  • not_optimised() işlevi gaz kullanımı: 21419 gaz
  • optimised() işlevi gaz kullanımı: 21253 gaz

D2: bayt kodunu kendiniz değiştirerek ve optimize ederek

Bunu yapmak için iyi bir nedeniniz yoksa bunu yapmayın, bazı işlevler tanımlanmamış bir davranış ve güvenlik sorunları ile sonuçlanabilir.

Bunun yerine optimize ediciyi kullanın veya çok katı bir test politikası uygulayın.

D3: Hataları Sil dize mesajları (karakter başına konuşlandırma maliyetinde yaklaşık 78.125 gaz tasarrufu)
Bunu yapmayın, kodun hatalarını ayıklamak sizin ve kullanıcılar için daha zor olabilir.

Örneğin, birisi şunları değiştirebilir:

require(account != address(0), "ERC20: mint to the zero address");
require(account != address(0));

D4: Düşük seviyeli montaj kullanan (gaz tasarrufu: değişken)

Ne yaptığınızı bilmiyorsanız, solidity assembly yapmayın. Marjinal tasarruf edilen gaz miktarı için sözleşmenizde bir güvenlik açığı olması için çok daha fazla şansınız olacak.

D5: Genel yerine harici kullanım
Şaşırtıcı bir şekilde, harici ve genel işlevler arasında herhangi bir fark yoktur.

  • not_optimised() işlevi gaz kullanımı: 21379 gaz
  • optimised() işlevi gaz kullanımı: 21401 gaz (-22 = 21379)

D6: Çarpma yerine sola kaydırmayı kullanın >> (150 benzin tasarrufu)
Bir ikili veriyi n kez sola kaydırmak, verinin 2^n ile çarpılmasına neden olur. İşte bir örnek:

00000001 = 1 dec
00000010 = 2 dec
00000100 = 4 dec
00001000 = 8 dec
  • not_optimised() işlevi gaz kullanımı: 21615 gaz
  • optimised() işlevi gaz kullanımı: 21436 gaz

Kazanımlar fena değil ama >> operatörü taşma olup olmadığını kontrol etmiyor.

D7: Meta veri karmasını silin (dağıtımda 3000–5000 gas)

Her akıllı sözleşme bayt kodunun sonuna bir “karma” eklenir.
Bu, akıllı sözleşmenin tüm meta verilerinin özetidir. (ABI, yorumlar, kod… dahil)

Meta veri karması 32 bayt uzunluğunda olduğundan, size bir sürü benzin tasarrufu sağlayabilir.
Ama bunu yapmak oldukça zor çünkü bunu elle yapmanız gerekiyor.

D8 Her işleve ödenecek ilave (çağrı başına 24 gaz tasarrufu)

Bir işleve ödenebilir ekleyerek, msg.value üzerindeki doğrulamayı kaldırın. Bu nedenle bir miktar gaz tasarrufu sağlanır.

pragma solidity ^0.8.7;
contract Test {
address store; 
    function optimised() external payable {
    }
function not_optimised() external {
    }
}
  • not_optimised() işlevi gaz kullanımı: 21186 gaz
  • optimised() işlevi gaz kullanımı: 21184 gaz

Zararlı değil ama çok da kullanışlı değil.

D9: önemli işi zincir dışında yapmak

Zincir dışı yaptığınız işlere dikkat edin.

Örneğin, web sitesi ön ucunda zincir dışı güvenlik doğrulaması yapamazsınız, bu çok tehlikelidir, çünkü herhangi biri tarayıcıdaki JS kodunu değiştirebilir ve akıllı sözleşmeye kötü girdi gönderebilir.

GÜVENLİK DOĞRULAMASINI HER ZAMAN ZİNCİR ÜZERİNDE YAPIN.

▶ Sonuç Bağlamı

Solidity ile ilgili gaz optimizasyon tekniklerinin önemli bir kısmına değinmiş olduk. Nasıl çalıştıklarını zaten biliyorsanız ve göz ardı edilemeyecek miktarda gaz tasarrufu sağlayabilirsiniz.

Sadece biraz gaz tasarrufu için çok zaman harcama tuzağına düşmeyin, zaman optimizasyonunu hayatınıza da uygulamanız gerekiyor :)

Bu makale TrustChain ve EVMcodes sitelerinde ki veri ve içeriklerden derlenmiştir.

Solidity Programlama Dili Nedir?

Solidity Programlama Dili yolculuğunuz hakkında daha iyi rehberlik almak için Solidity nedir? Ethereum Akıllı Sözleşmelerinin Dili Rehberi içeirğimize göz atın. Dilerseniz Yeni Başlayanlar için Solidity – Akıllı Sözleşme Geliştirme Hızlandırılmış Kursuna katılın.

Çalışmaya nereden başlayacğaım diyenler için Blockchain ​​Developer Olmak İçin Yol Haritası içeriğine de muhakkak bakın.

Gelin aklınızdaki soruları SUPERPEER sobetinde cevaplayalım.

Bu makaleyi okuduğunuz için teşekkürler! Bana destek olmak isterseniz;

Beni TwitterLinkedin ve YouTube‘da takip edin.

Kısa bir yorum bırakmayı UNUTMAYIN!

solidity101 - Solidity, 2015 yılında Christian Reitwiessner liderliğinde piyasaya sürülen, büyük harf kullanımına göre ikinci en büyük kripto para piyasası olan Ethereum tarafından oluşturulan yepyeni bir programlama dilidir.

Yazarın Profili
İlginizi Çekebilir

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir