1. Anasayfa
  2. 100 Günde Solidity

🧵 #100GündeSolidity 031 : Fallback

🧵 #100GündeSolidity 031 : Fallback
Fallback Fonksiyonu
0

Fallback Fonksiyonu

Merhaba!

Bugün #100GündeSolidity serisinin 31. e-bülteninde “Fallback” konusunu ele alacağız. Solidity dilinde, fallback fonksiyonu, Ether doğrudan bir sözleşmeye gönderildiğinde veya belirli bir fonksiyon mevcut olmadığında çağrılır. Bu özel fonksiyonun davranışını anlamak ve doğru şekilde kullanmak, bir sözleşmenin güvenliğini ve doğru çalışmasını sağlamak için önemlidir.

Bu bültenin amacı, Solidity’de fallback fonksiyonunun ne olduğunu, nasıl kullanılacağını ve hangi durumlarda çağrılacağını anlamak için bir giriş sağlamaktır. Ayrıca fallback fonksiyonlarının çağrı limitleri, Ether transferleri, güvenlik endişeleri ve alternatif yaklaşımlar gibi konulara da değineceğiz.

Hazırsanız, fallback fonksiyonlarına dalış yapmaya başlayalım!

Fallback Fonksiyonu: Solidity’de fallback fonksiyonu nedir ve ne işe yarar? Bu fonksiyon, hangi durumlarda çağrılır?

Solidity’de, fallback fonksiyonu, bir sözleşmeye Ether doğrudan gönderildiğinde veya sözleşmede belirli bir fonksiyon mevcut olmadığında çağrılır. Fallback fonksiyonu, belirli bir fonksiyon adı olmadan çağrıldığı için, tüm fonksiyonlar arasında en son seçenek olarak çalışır ve aynı zamanda en önemli fonksiyonlardan biridir.

Fallback fonksiyonu, sözleşmenin Ether veya diğer varlıkların doğrudan transferi için bir kapı görevi görür. Ayrıca, sözleşmenin beklenmedik bir durumda nasıl davranacağını da belirleyebilir. Örneğin, belirli bir fonksiyon adı olmadan sözleşmeye bir mesaj gönderildiğinde veya yanlış bir parametre ile bir fonksiyon çağrıldığında ne yapacağını belirleyebilir.

Örneğin, aşağıdaki gibi bir fallback fonksiyonu, sözleşmeye Ether gönderildiğinde çağrılır ve sözleşmedeki hesabın bakiyesini artırır:

function() external payable {
    // sözleşmedeki hesabın bakiyesini artır
    balance[msg.sender] += msg.value;
}

Burada, payable anahtar kelimesi, fonksiyonun Ether alabilen bir fonksiyon olduğunu belirtir.

Genellikle, sözleşmelerde özel bir fallback fonksiyonu oluşturmak iyi bir uygulamadır. Böylece, Ether transferleri veya fonksiyon çağrıları beklenmedik şekilde çalıştığında sözleşmenin istenmeyen davranışlar göstermesinin önüne geçilebilir.

Çağrı Limitleri: Fallback fonksiyonunun çağrı limitleri nelerdir? Neden bu limitler önemlidir?

Fallback fonksiyonları, Solidity’de çağrı limitlerine tabidir. Bu limitler, fallback fonksiyonunun çağrıldığı koşullara göre değişebilir.

Eğer fallback fonksiyonu, transfer veya send fonksiyonu ile çağrılıyorsa, çağrı limiti 2300 gas’tır. Bu limit, fallback fonksiyonunun sadece 2300 gas kullanarak çalışabileceği anlamına gelir. Bu nedenle, fallback fonksiyonları, çok fazla işlem yapmadığından emin olmak için genellikle çok basit hale getirilirler. Aksi takdirde, transfer işlemi tamamlanamaz ve işlem geri alınır.

Bu limitlerin önemi, sözleşmelerin istenmeyen veya beklenmeyen şekillerde gas tüketmesini önlemektir. Sözleşmenin çağrı limitlerine uymaması durumunda, işlemin tamamlanamaması veya gas ücretlerinin artması gibi sorunlarla karşılaşılabilir.

Bu nedenle, fallback fonksiyonları mümkün olduğunca basit tutulmalı ve fazla gas tüketen işlemlerden kaçınılmalıdır. Bu, sözleşmelerin güvenliğini ve doğru çalışmasını sağlamaya yardımcı olur.

Ether Transferleri: Fallback fonksiyonu, Ether doğrudan bir sözleşmeye gönderildiğinde veya receive() fonksiyonu mevcut olmadığında nasıl davranır?

Fallback fonksiyonu, Ether doğrudan bir sözleşmeye gönderildiğinde veya receive() fonksiyonu mevcut olmadığında çağrılır. Bu durumda, fallback fonksiyonu, Ether transferinin işlenmesi için kullanılır.

Eğer sözleşmenin fallback fonksiyonu, payable anahtar kelimesi ile etiketlenmemişse veya sözleşmenin hesabı Ether kabul etmek için ayarlanmamışsa, Ether transferi başarısız olacaktır. Bu durumda, gönderen hesap, gönderdiği Ether’i geri alacaktır.

Öte yandan, fallback fonksiyonu, payable anahtar kelimesi ile etiketlenmişse, Ether transferi işlenir ve sözleşmenin hesabı artırılır. Aşağıdaki örnek, fallback fonksiyonunun payable anahtar kelimesi ile etiketlendiği bir sözleşme için bir örnek sunmaktadır:

function() external payable {
    // sözleşmenin hesabını artır
    balance[msg.sender] += msg.value;
}

Bu sözleşme, Ether transferleri alabilir ve gönderen hesaptan alınan Ether miktarını balance adlı bir değişkende saklar.

Bununla birlikte, Solidity 0.8.0 sürümü ile birlikte, receive() fonksiyonu da tanıtıldı. receive() fonksiyonu, fallback fonksiyonunun yerini alır ve Ether transferleri için kullanılır. receive() fonksiyonu, payable anahtar kelimesi ile etiketlenir ve aşağıdaki gibi tanımlanır:

receive() external payable {
    // sözleşmenin hesabını artır
    balance[msg.sender] += msg.value;
}

Bu örnekte, receive() fonksiyonu, Ether transferleri için kullanılır ve fallback fonksiyonunun yerini alır. Sözleşme, Ether transferleri alabilir ve gönderen hesaptan alınan Ether miktarını balance adlı bir değişkende saklar.

Güvenlik Endişeleri: Fallback fonksiyonları, kötü amaçlı saldırıların hedefi olabilir mi? Bu endişeleri nasıl ele alabiliriz?

Evet, fallback fonksiyonları kötü amaçlı saldırıların hedefi olabilir. Bu nedenle, güvenlik endişeleriyle karşı karşıya kalabiliriz.

En yaygın güvenlik endişeleri, yürütülebilir kodun kötü amaçlı bir amaçla sözleşme üzerinden yürütülmesidir. Örneğin, sözleşmenin fallback fonksiyonu, kötü amaçlı bir saldırgan tarafından kontrol edilebilir ve sözleşmenin kontrolünü ele geçirmek için kullanılabilir. Ayrıca, fallback fonksiyonu, belirli bir Ether transferini işlemek için kullanılabilir ve sözleşme sahibinin beklenmedik bir şekilde Ether kaybetmesine neden olabilir.

Bu endişeleri ele almak için, Solidity programcıları, sözleşmenin fallback fonksiyonu veya receive() fonksiyonu tarafından işlenen Ether miktarını sınırlayan işlem miktarı limitlerine dikkat etmelidir. Ayrıca, kodlarınızda açıkça belirtmediğiniz sürece, tüm girişleri ve Ether transferlerini doğrulamalısınız.

Ayrıca, OpenZeppelin ve ConsenSys Diligence gibi güvenlik denetim şirketleri, sözleşme kodları için güvenlik denetimleri sunarak, programcıların fallback fonksiyonlarından kaynaklanabilecek güvenlik açıklarını tespit etmelerine yardımcı olabilirler. Bunlar, programcıların kodlarının güvenliğini artırmalarına ve fallback fonksiyonlarının kötüye kullanılmasını önlemelerine yardımcı olabilir.

Alternatif Yaklaşımlar: Fallback fonksiyonlarının yerine kullanabileceğimiz başka yaklaşımlar var mı? Bu yaklaşımlar nelerdir ve ne zaman kullanılabilirler?

Evet, fallback fonksiyonlarının yerine kullanabileceğimiz alternatif yaklaşımlar vardır. Bu yaklaşımlar arasında şunlar bulunur:

  1. receive() Fonksiyonu: Solidity 0.6.0’dan bu yana, receive() fonksiyonu, doğrudan Ether transferlerini işlemek için fallback fonksiyonu yerine kullanılabilir. Bu fonksiyon, sadece Ether transferleri için kullanılır ve gas limiti 2300’dür.
  2. İsimlendirilmiş Fonksiyonlar: İsimlendirilmiş fonksiyonlar, fallback fonksiyonlarının yerini alabilir ve önceden belirlenmiş bir fonksiyonun çağrılması durumunda çalıştırılır. Bu yaklaşım, sözleşme sahibinin, Ether transferlerini belirli bir fonksiyonla işlemek istediği durumlarda kullanılabilir.
  3. Modifier’lar: Modifier’lar, bir işlevin çağrılması öncesinde koşulların kontrol edilmesini sağlayan bir işlevdir. Bu yaklaşım, sözleşme sahibinin, işlevin yürütülmesi öncesinde belirli koşulların karşılanmasını zorunlu kılmak istediği durumlarda kullanılabilir.
  4. Event’ler: Event’ler, bir sözleşmede meydana gelen olayların kaydedilmesini sağlayan bir mekanizmadır. Event’ler, sözleşmenin durumunu ve işlemlerin geçmişini takip etmek için kullanılabilir.

Bu alternatif yaklaşımlar, sözleşme sahiplerine, Ether transferleri veya diğer olaylar için özel olarak tasarlanmış fonksiyonları kullanma seçeneği sunar. Bunlar, fallback fonksiyonlarının olası güvenlik açıklarını önlemeye yardımcı olabilir. Ancak, hangi yaklaşımın kullanılacağı, sözleşmenin özelliklerine ve ihtiyaçlarına bağlıdır.

Örnek Akıllı Sözleşme İNCELEMESİ

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Fallback {
    event Log(string func, uint gas);

    // Fallback function must be declared as external.
    fallback() external payable {
        // send / transfer (forwards 2300 gas to this fallback function)
        // call (forwards all of the gas)
        emit Log("fallback", gasleft());
    }

    // Receive is a variant of fallback that is triggered when msg.data is empty
    receive() external payable {
        emit Log("receive", gasleft());
    }

    // Helper function to check the balance of this contract
    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

contract SendToFallback {
    function transferToFallback(address payable _to) public payable {
        _to.transfer(msg.value);
    }

    function callFallback(address payable _to) public payable {
        (bool sent, ) = _to.call{value: msg.value}("");
        require(sent, "Failed to send Ether");
    }
}

Bu akıllı sözleşme, fallback fonksiyonlarının ve receive() fonksiyonlarının nasıl kullanılabileceğini göstermek için örnek bir kod parçasıdır. Sözleşme iki bölümden oluşur: Fallback ve SendToFallback.

Fallback bölümü, fallback ve receive fonksiyonlarının nasıl çalıştığını göstermek için tasarlanmıştır. Bu bölümdeki fallback fonksiyonu, Ether doğrudan sözleşmeye gönderildiğinde veya geçersiz bir fonksiyon çağrıldığında tetiklenir. Fonksiyon, bir olay kaydeder ve işlevin çalıştırıldığı sırada ne kadar gaz kaldığını gösteren gasleft() fonksiyonunu kullanır. Receive fonksiyonu da benzer şekilde çalışır, ancak sadece msg.data boş olduğunda tetiklenir.

SendToFallback bölümü, başka bir sözleşmeye Ether göndermek için iki fonksiyon içerir. İlk fonksiyon, transferToFallback, Ether’i doğrudan bir sözleşmeye transfer etmek için kullanılır. İkinci fonksiyon, callFallback, bir sözleşmenin fallback fonksiyonunu çağırmak için kullanılır.

Bu akıllı sözleşme, fallback fonksiyonlarının ve receive() fonksiyonlarının kullanımını gösterir ve aynı zamanda Ether’in doğrudan bir sözleşmeye nasıl gönderilebileceğini gösterir. Ancak, bu sadece örnek bir kod parçasıdır ve gerçek bir uygulamada kullanılmamalıdır. Gerçek bir uygulamada, güvenlik endişelerini ele almak için daha fazla önlem alınmalıdır.

Alternatif Akıllı Sözleşme Örneği İncelemesi

pragma solidity ^0.8.17;

// TestFallbackInputOutput -> FallbackInputOutput -> Counter
contract FallbackInputOutput {
    address immutable target;

    constructor(address _target) {
        target = _target;
    }

    fallback(bytes calldata data) external payable returns (bytes memory) {
        (bool ok, bytes memory res) = target.call{value: msg.value}(data);
        require(ok, "call failed");
        return res;
    }
}

contract Counter {
    uint public count;

    function get() external view returns (uint) {
        return count;
    }

    function inc() external returns (uint) {
        count += 1;
        return count;
    }
}

contract TestFallbackInputOutput {
    event Log(bytes res);

    function test(address _fallback, bytes calldata data) external {
        (bool ok, bytes memory res) = _fallback.call(data);
        require(ok, "call failed");
        emit Log(res);
    }

    function getTestData() external pure returns (bytes memory, bytes memory) {
        return (abi.encodeCall(Counter.get, ()), abi.encodeCall(Counter.inc, ()));
    }
}

Bu akıllı sözleşme örneği, FallbackInputOutput adlı bir sözleşme ile Counter adlı bir başka sözleşme arasında bir arayüz sağlar. FallbackInputOutput sözleşmesi, hedef sözleşmenin fallback fonksiyonunu arar ve özellikle gönderilen verileri hedef sözleşmeye aktarır.

Counter sözleşmesi, bir sayacın basit bir örneğidir ve get() ve inc() adlı iki işlevi içerir. FallbackInputOutput sözleşmesi, Counter sözleşmesine bir arayüz sağlar ve hedef sözleşmenin fallback fonksiyonuna yönlendirilen tüm çağrıları yakalar.

TestFallbackInputOutput adlı bir sözleşme de mevcuttur. Bu sözleşme, FallbackInputOutput sözleşmesi ile etkileşimde bulunmak için kullanılabilir. test() fonksiyonu, FallbackInputOutput sözleşmesine bir çağrı yapar ve geri dönen verileri kaydeder. getTestData() fonksiyonu, Counter sözleşmesinin get() ve inc() fonksiyonlarını çağırmak için kullanılan verileri döndürür.

Örnek Akıllı Sözleşmeleri Karşılaştıralım

ki akıllı sözleşmeyi karşılaştırmak için örnek olarak Fallback ve FallbackInputOutput sözleşmelerini ele alabiliriz. İki sözleşme de fallback fonksiyonlarını kullanıyorlar ancak amaçları ve işlevleri açısından farklılık gösteriyorlar.

Fallback sözleşmesi, basit bir şekilde Ether transferleri için bir fallback fonksiyonu sağlar. Sözleşmeye Ether doğrudan gönderildiğinde veya receive() fonksiyonu mevcut olmadığında bu fallback fonksiyonu çalışır ve bir log kaydı oluşturur. Amacı, sözleşmeye gönderilen Ether’in kaydedilmesidir. Bu sözleşme, Ether transferi için güvenli bir yöntem sağlar, ancak herhangi bir işlevsellik sağlamaz.

FallbackInputOutput sözleşmesi ise, geri arama fonksiyonunu kullanarak farklı amaçlar için kullanılabilir. Bu sözleşme, hedef sözleşmedeki herhangi bir işlevi çağırmak için kullanılabilir ve çağrı sonucunu döndürür. FallbackInputOutput, bir aracı gibi davranarak hedef sözleşmeyi çağıran ve sonucunu döndüren bir arayüz sağlar. Bu sözleşme, özellikle diğer sözleşmelerin hedef sözleşmelerle iletişim kurmasına olanak tanır. Ancak, bu sözleşmenin kullanımı, işlevleri ve parametreleri doğru bir şekilde yönetilmediğinde, güvenlik riskleri doğurabilir.

Bu iki sözleşmenin karşılaştırıldığında, Fallback sözleşmesi basit bir amaçla oluşturulurken, FallbackInputOutput sözleşmesi daha geniş bir kullanım için tasarlanmıştır. FallbackInputOutput sözleşmesi, diğer sözleşmelerle iletişim kurma ve işlevleri çağırma işlevi için bir arayüz sağlar. Ancak, bu kullanımı doğru yönetmek için ek güvenlik önlemleri alınması gerekebilir. Öte yandan, Fallback sözleşmesi basit bir amaçla oluşturulduğu için, ek güvenlik önlemleri gerektirmez.

Sonuç Bağlamı

Sonuç olarak, fallback fonksiyonları Solidity programlama dilinde oldukça önemlidir ve özellikle Ether transferleri için kullanılmaktadır. Ancak, güvenlik endişeleri nedeniyle dikkatli bir şekilde kullanılmalı ve gerektiğinde alternatif yaklaşımlara başvurulmalıdır.

Bu nedenle, Solidity öğrenmek ve daha iyi bir programcı olmak isteyen herkesi #100DaysOfSolidity serisine katılmaya ve LinkedIN’de yayınlanan “Solidity Öğren” e-bültenine abone olmaya davet ediyoruz. Bu seri, Solidity ve akıllı sözleşme geliştirme hakkında kapsamlı bilgiler sunmaktadır ve her seviyeden geliştiricilerin ihtiyaçlarını karşılamak için tasarlanmıştır. Ayrıca, #100DaysOfSolidity hashtagını takip ederek toplulukla etkileşime geçebilir ve diğer geliştiricilerle tecrübelerinizi paylaşabilirsiniz.

Solidity Programlama Dili Öğrenme yolculuğunuz hakkında daha iyi rehberlik almak için Solidity nedir? Ethereum Akıllı Sözleşmelerinin Dili Rehberi içeriğ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şlayacağım diyenler için Blockchain ​​Developer Olmak İçin Yol Haritası içeriğine de muhakkak bakın.

Gelin aklınızdaki soruları SUPERPEER sohbetinde 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

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