1. Anasayfa
  2. 100 Günde Solidity

🧵 #100GündeSolidity 033 : Delegatecall

🧵 #100GündeSolidity 033 : Delegatecall
Delegatecall
0

Delegatecall Nedir ve Nasıl Çalışır? – İki Kontrat Arasında Veri ve Fonksiyon Paylaşımı

Solidity dilinde, bir kontratın başka bir kontratı çağırması için farklı yöntemler vardır. Delegatecall, bu yöntemlerden biridir ve daha düşük seviyeli bir işlevdir. Bu işlev, bir kontrattan diğerine fonksiyon çağırmak için kullanılabilir ve çağrılan kontratın kodu, çağıran kontratın depolama alanı, msg.sender ve msg.value bilgileriyle birlikte çalıştırılır. Bu, iki kontrat arasında veri ve fonksiyon paylaşımı sağlar ve Solidity dilindeki kontratlar arasındaki iletişimde oldukça yaygın bir kullanıma sahiptir. Ancak, delegatecall kullanırken güvenlik riskleri de dikkate alınmalıdır. Bu nedenle, bu yazıda delegatecall işlevini daha ayrıntılı olarak inceleyeceğiz, çalışma prensiplerini açıklayacağız ve kullanımı sırasında dikkat edilmesi gereken güvenlik riskleri hakkında bilgi vereceğiz.

Solidity dilinde fonksiyon çağrıları, başka programlama dillerinde olduğu gibi fonksiyonların çağrılması işlemidir. Ancak, Solidity dilinde farklı fonksiyon çağrı yöntemleri mevcuttur.

  1. Direkt Fonksiyon Çağrısı: Bu yöntem, fonksiyonun çağrıldığı kontrat içinde doğrudan çağrılmasını ifade eder. Örneğin:
pragma solidity ^0.8.0;

contract ContractA {
    uint public a = 1;
    function add(uint _b) public {
        a += _b;
    }
}

contract ContractB {
    ContractA public contractA = new ContractA();
    function doSomething() public {
        contractA.add(5);
    }
}

Yukarıdaki örnekte, ContractB’deki doSomething fonksiyonu, ContractA’daki add fonksiyonunu doğrudan çağırır.

  1. Call Yöntemi: Solidity dilindeki call yöntemi, diğer kontratlara veri veya fonksiyon çağırmak için kullanılır. Bu yöntem, çağrılan fonksiyonun veya verinin tipine bağlı olarak geri dönüş değerleri alabilir veya almayabilir. Örneğin:
pragma solidity ^0.8.0;

contract ContractA {
    uint public a = 1;
    function add(uint _b) public {
        a += _b;
    }
}

contract ContractB {
    ContractA public contractA = new ContractA();
    function doSomething() public {
        bool success = address(contractA).call(abi.encodeWithSignature("add(uint256)", 5));
        require(success, "Call failed");
    }
}

Yukarıdaki örnekte, ContractB’deki doSomething fonksiyonu, ContractA’daki add fonksiyonunu call yöntemiyle çağırır.

  1. Delegatecall Yöntemi: Delegatecall yöntemi, başka bir kontrata fonksiyon çağırmak için kullanılır ve çağrılan fonksiyon, çağıran kontratın depolama alanı, msg.sender ve msg.value bilgileriyle birlikte çalıştırılır. Bu, çağıran kontrat ve çağrılan kontrat arasında bir tür veri ve fonksiyon paylaşımı sağlar. Örneğin:
pragma solidity ^0.8.0;

contract ContractA {
    uint public a = 1;
    function add(uint _b) public {
        a += _b;
    }
}

contract ContractB {
    ContractA public contractA = new ContractA();
    function doSomething() public {
        bool success = address(contractA).delegatecall(abi.encodeWithSignature("add(uint256)", 5));
        require(success, "Delegatecall failed");
    }
}

Yukarıdaki örnekte, ContractB’deki doSomething fonksiyonu, ContractA’daki add fonksiyonunu delegatecall yöntemiyle çağırır.

Bu örnekler, Solidity dilindeki farklı fonksiyon çağrı yöntemlerini açıklamaktadır. Her yöntemin farklı kullanım senaryolar

ı vardır ve hangi yöntemin kullanılması gerektiği, kullanım senaryosuna göre değişebilir.

Direkt fonksiyon çağrısı, fonksiyonun aynı kontratta olduğu durumlarda kullanılır ve genellikle en basit yöntemdir.

Call yöntemi, diğer kontratlara veri veya fonksiyon çağırmak için kullanılır ve geri dönüş değerleri alabilir veya almayabilir. Bu yöntem, başka bir kontrata erişmek için en yaygın kullanılan yöntemdir.

Delegatecall yöntemi ise, çağıran kontratın depolama alanı, msg.sender ve msg.value bilgileriyle birlikte başka bir kontrata fonksiyon çağırmak için kullanılır. Bu yöntem, çağıran ve çağrılan kontrat arasında bir tür veri ve fonksiyon paylaşımı sağlar ve genellikle bir kütüphane kontratından fonksiyon çağırmak için kullanılır.

Hangi yöntemin kullanılacağı, özellikle bir kontratın diğer bir kontrata erişim gerektirdiği durumlarda, kullanım senaryosuna ve ihtiyaca bağlıdır.

Delegatecall Nedir ve Nasıl Kullanılır?

Delegatecall, Solidity dilindeki bir fonksiyon çağrı yöntemidir ve bir kontratın başka bir kontrata depolama alanı, msg.sender ve msg.value bilgileri ile birlikte fonksiyon çağırmasını sağlar.

Delegatecall, genellikle kütüphane kontratları gibi, birçok kontrat tarafından kullanılan ve farklı depolama alanlarını kullanarak işlevselliğini sağlayan bir fonksiyonu çağırmak için kullanılır. Bu yöntem sayesinde, çağıran ve çağrılan kontrat arasında bir tür veri ve fonksiyon paylaşımı gerçekleştirilir.

Delegatecall, call yöntemi gibi geri dönüş değerleri alabilir veya almayabilir. Ancak, delegasyon yapılan fonksiyonun kaynak kontratının depolama alanına erişim izni verildiği için, çağıran kontratın depolama alanı değiştirilebilir. Bu nedenle, delegatecall yöntemi kullanılırken, çağıran kontratın depolama alanını etkileyen bir fonksiyon çağırmak, dikkatli bir şekilde düşünülmesi gereken bir konudur.

Delegatecall yönteminin kullanım örneklerinden biri, örneğin bir kütüphane kontratının içindeki fonksiyonu çağırmak için kullanılır. Bu sayede, bir kütüphane fonksiyonu farklı kontratlar tarafından kullanılabilir ve aynı fonksiyonun farklı depolama alanları üzerinde çalışması sağlanır. Aşağıdaki örnekte, bir kütüphane kontratının içindeki add fonksiyonu, farklı kontratlar tarafından delegatecall yöntemi kullanılarak çağrılabilir:

pragma solidity ^0.8.0;

contract Library {
    uint public value;

    function add(uint _value) public {
        value += _value;
    }
}

contract Caller {
    address public libraryAddress;
    uint public value;

    function setValue(address _libraryAddress, uint _value) public {
        libraryAddress = _libraryAddress;
        value = _value;

        (bool success, bytes memory result) = libraryAddress.delegatecall(
            abi.encodeWithSignature("add(uint256)", value)
        );

        require(success, "Library function call failed.");
    }
}

Yukarıdaki örnekte, Caller kontratı, Library kontratındaki add fonksiyonunu delegatecall yöntemi kullanarak çağırır. Delegatecall yönteminin kullanımı için, çağrılan fonksiyonun adı ve argümanları abi.encodeWithSignature() yöntemiyle kodlanarak delegatecall fonksiyonuna aktarılır.

Delegatecall yöntemi, Solidity dilinde güçlü bir araçtır ve doğru kullanıldığında çok faydalı olabilir. Ancak, dikkatli bir şekilde kullanılması ve diğer fonksiyon çağrı yöntemlerinin özelliklerinin anlaşılması önemlidir.

Delegatecall Güvenlik Riskleri ve Önlemleri

Delegatecall yöntemi, Solidity dilinde kullanılan güçlü bir araçtır, ancak yanlış kullanıldığında güvenlik riskleri oluşturabilir. Bu nedenle, delegatecall yöntemi kullanırken, belirli önlemler alınması gerekmektedir.

  1. Güvenilir Kontratlar Kullanın: Delegatecall yöntemi, çağrılan kontratın depolama alanına erişim izni verdiği için, güvenilir olmayan kontratlara delegatecall yapmak, çağıran kontratın depolama alanına erişim sağlayabilir. Bu nedenle, güvenilirliği doğrulanmış kontratlar kullanılması önemlidir.
  2. Fonksiyon Adını Doğrulayın: Delegatecall yöntemi, çağrılan fonksiyonun adını kod içinde yazarak çağırmak yerine, kodu dinamik olarak oluşturmak için abi.encodeWithSignature() kullanır. Bu nedenle, fonksiyon adının doğru olduğundan emin olmak için fonksiyon adını doğrulamak önemlidir.
  3. Güvenli Bir Geri Dönüş Kontrolü Yapın: Delegatecall yöntemi, çağrılan fonksiyonun geri dönüş değerini dikkate almaz, bu nedenle geri dönüş değerini kontrol etmek için ayrı bir kontrol mekanizması kullanmak önemlidir.
  4. İzin Verilen Fonksiyonları Sınırlandırın: Delegatecall yöntemi, çağrılan fonksiyonun kaynak kontratının depolama alanına erişim izni verdiği için, çağıran kontratın depolama alanını değiştirmemesi için izin verilen fonksiyonların sınırlandırılması önemlidir.
  5. Test ve Denetleme: Delegatecall yöntemi, dikkatli bir şekilde kullanıldığında çok faydalı bir araçtır, ancak güvenliği sağlamak için kodun test edilmesi ve denetlenmesi gereklidir.

Delegatecall yöntemi, doğru kullanıldığında Solidity dilinde çok faydalı bir araçtır. Ancak, kullanıcıların dikkatli olması ve güvenliği sağlamak için belirli önlemler almaları gerekmektedir.

Delegatecall ile Fonksiyon Çağırma Örneği

Delegatecall yöntemi, Solidity dilindeki diğer fonksiyon çağırma yöntemlerine göre daha karmaşık bir yapıya sahiptir. Ancak, bir örnek üzerinden adım adım nasıl kullanıldığını anlayabiliriz.

Aşağıdaki örnekte, bir “Receiver” adlı kontratın “setValue” fonksiyonu, “Caller” adlı başka bir kontratın “setValues” fonksiyonu aracılığıyla çağrılacaktır. Bu çağrı, delegatecall yöntemi kullanılarak yapılacaktır.

pragma solidity ^0.8.0;

contract Receiver {
    uint public value;
    
    function setValue(uint _value) public {
        value = _value;
    }
}

contract Caller {
    function setValues(address _contract, uint _value) public {
        (bool success,) = _contract.delegatecall(abi.encodeWithSignature("setValue(uint256)", _value));
        require(success);
    }
}

Bu örnekte, “Receiver” kontratı bir “uint” değerinde “value” adlı bir değişken içermektedir. “setValue” fonksiyonu, bu “value” değişkenine gelen “uint” değerini atamak için kullanılmaktadır.

“Caller” kontratı ise, “setValues” fonksiyonu aracılığıyla, “Receiver” kontratının “setValue” fonksiyonunu çağırmaktadır. Bu çağrı, delegatecall yöntemi kullanılarak yapılacaktır.

“setValues” fonksiyonu, çağrılan kontratın adresini (_contract) ve gönderilecek değeri (_value) alır. Daha sonra, abi.encodeWithSignature() fonksiyonu kullanılarak, çağrılacak fonksiyonun adı ve gönderilecek parametreler kod içinde oluşturulur.

Son olarak, delegatecall yöntemi kullanılarak, “setValue” fonksiyonu “Receiver” kontratında çağrılır. Bu çağrının başarılı olması için “bool” türünde bir dönüş değeri (_success) ve bir hata mesajı (_error) oluşturulur. “require” ifadesi kullanılarak, çağrının başarılı olduğundan emin olunur.

Bu örnekte, delegatecall yöntemi kullanılarak, “Caller” kontratı, “Receiver” kontratının depolama alanına erişim sağlayarak, “setValue” fonksiyonunu çağırabilir. Ancak, bu işlem, güvenlik açısından bazı riskler taşımaktadır ve önlemler alınması gerekmektedir.

Delegatecall Alternatifleri ve Uygun Kullanım Yöntemleri

Delegatecall, Solidity dilindeki diğer fonksiyon çağırma yöntemlerine göre daha karmaşık bir yapıya sahiptir ve güvenlik açısından bazı riskler taşımaktadır. Bu nedenle, uygun kullanım yöntemleri ve alternatifleri hakkında bilgi sahibi olmak önemlidir.

İşte delegatecall’in alternatifleri ve uygun kullanım yöntemleri:

  1. Call: Call yöntemi, Solidity dilindeki en temel fonksiyon çağırma yöntemidir. Bu yöntem, hedef fonksiyonun imzasını ve parametrelerini açıkça belirtir ve hedef fonksiyonun çalışmasını sağlar. Call yöntemi, delegatecall yöntemine göre daha az risk taşıdığından, özellikle diğer kontratların çalıştırılması gerektiğinde tercih edilir.
  2. Send: Send yöntemi, belirtilen tutarda ether gönderir ve hedef kontratın fallback fonksiyonunu çağırır. Bu yöntem, gas sınırlaması nedeniyle sadece küçük tutarlarda ether gönderebilir ve gönderilen etherin hedef kontratta nasıl kullanılacağına dair bir kontrol sağlamaz.
  3. Transfer: Transfer yöntemi, send yöntemine benzer şekilde, belirtilen tutarda ether gönderir. Ancak, gas sınırlaması nedeniyle sadece küçük tutarlarda ether gönderilebilir. Ayrıca, transfer yöntemi, gönderilen etherin hedef kontratta nasıl kullanılacağına dair bir kontrol sağlar.
  4. Libraries: Solidity dilindeki kütüphaneler, birden fazla kontrat tarafından paylaşılan fonksiyonları içeren ve kontratların gas maliyetlerini düşüren özel kontratlardır. Bu yöntem, delegatecall yönteminden daha az risk taşır ve kodun daha modüler olmasını sağlar.
  5. Interaktif Kontratlar: Interaktif kontratlar, Solidity dilindeki diğer kontratların gas maliyetlerini düşürmek için kullanılan özel bir yapıdır. Bu yöntem, Solidity dilindeki bir fonksiyonun diğer bir kontratta çalıştırılmasını sağlar ve hedef kontratın depolama alanına erişim sağlamaz.

Uygun kullanım yöntemleri:

  1. Delegatecall, yalnızca güvenlik riskleri iyi anlaşıldıktan sonra kullanılmalıdır.
  2. Delegatecall’in kullanımı, kontratların arasındaki güvenliği arttırmak için kullanılabilir.
  3. Delegatecall, diğer fonksiyon çağırma yöntemlerinin kullanımından önce iyi bir alternatif olarak düşünülmelidir.
  4. Delegatecall, sadece çok spesifik bir senaryoda kullanılmalıdır ve diğer alternatifler dikkate alınmalıdır.

Sonuç Bağlamı

Delegatecall, Solidity dilindeki diğer fonksiyon çağırma yöntemlerine göre daha karmaşık bir yapıya sahip olsa da, uygun kullanım yöntemleri ile güvenli bir şekilde kullanılabilir. Delegatecall, diğer kontratlardaki fonksiyonlara erişim sağlamak için kullanılabilir ve Solidity dilindeki kütüphaneler ve interaktif kontratlar gibi alternatifleri de mevcuttur.

Ancak, delegatecall’in güvenlik riskleri vardır ve kullanımı özenli bir şekilde yapılmalıdır. İyi bir anlayış ve dikkatli bir planlama ile, delegatecall’in kullanımı diğer alternatiflere göre avantaj sağlayabilir.

Bu nedenle, Solidity dilindeki fonksiyon çağırma yöntemleri hakkında geniş bir bilgi sahibi olmak ve her senaryoda doğru yöntemi kullanmak önemlidir.

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