Değer türleri(value types), her zaman bir değer döndüren değişkenlerin türleridir. Bunlar boolean, sayı(integer), adres(address), kontrat(contracts) vb türlerde karşımıza çıkmaktadır. Resmi dökümanda çok kapsamlı ve uzun şekilde anlatıldığı için parçalara bölünmüş şekilde birkaç yazıda akıllı sözleşme türlerini açıklayıp ardından örnekleyeceğim.
bool	değerler true	ya da false	değerlerini alabilmektedir. [ayr. bkz.] Bir şartın doğru ya da yanlış olduğunu belirtmek için bool	değerler kullanılmaktadır.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract BoolValues {
    //Ödeme yapılıp yapılmadığı iki  farklı değer alacağı için (true-false) bool türüyle tanımladık.
    bool odemeYapildiMi;
}
- !➝ mantıksal olumsuzlama. Doğru ise yanlış, yanlış ise doğru döner.
- &&➝ mantıksal "ve" bağlacı. İki değerin de "doğru" olması ile "doğru" döner
- ||➝ mantıksal "ya da" bağlacı. İki değerden biri "doğru" ise doğru döner
- ==➝ iki değer birbirine eşit mi? Eşitse "doğru" döner
- !=(iki değer birbirine eşit değilse "doğru" döner)
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract BoolValues {
    //iki bool değerin hangi operatorlerle sorgunlandıgını inceleyelim
    function ikiBoolEsitMi(bool x, bool y) pure public returns(bool){
        return x == y;
    }
    
    //x bool değeri true ise doğru olduğunu dönecektir.
    function DogruMu(bool x) pure public returns(bool){
        return x;
    }
    /*x bool değeri true ise doğru olduğu için doğru değil şartı yanlış olacaktır. Bu ! işareti ile sağlanır*/
    function DogruDegilMi(bool x) pure public returns(bool){
        return !x;
    }
int	ve uint, imzalı(signed) ve imzalanmamış(unsigned) iki sayı değerini belirtir. [ayr. bkz.] Sayı doğrusunun hem artı hem eksi tarafının olduğunu düşünecek olursak int	değerleri +, - ve 0 değerlerini alabilirken uint yalnızca 0 ve + değerleri alabilir.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract OrnekSozlesme {
    //Pozitif ve 0 değerler tanımlanabilir.
    uint imzasizDegerler = 0;
    uint imzasizDegerler1 = 88;
    //-88 imzalı bir sayı olduğu için hata dönecektir.
    uint imzasizDegerler2 = -88;
    //Tüm tam sayı değerleri tanımlanabilir.
    int tumTamsayiDegerleri = 2;
    int tumTamsayiDegerleri1 = -888;
    int tumTamsayiDegerleri2 = 0;
    //Değerler tam sayı olmadığı için hata dönecektir.
    uint imzasizDegerler3 = 98.8;
    int tumTamsayiDegerleri4 = 88.8
int8, uint8, int,uint, int256	ve uint256	çeşitli uzunluklarda olabilmektedir. int ve uint için bir uzunluk sınırlaması yokken int8, uint8, int256ve uint256 için belirli bir uzunluk sınırı vardır.
//Doğru değer int8 yeniSayi1 = 88; //Hatalı değer int8 yeniSayi1 = 888;
Operatörler:
- Karlışatırma operatörleri: <=,<,==,!=,>=,>(booldeğer dönecektir)
- Bit operatörleri: &,|,^(bitwise exclusive or),~(bitwise negation)
- Kaydırma operatörleri: <<(sola kaydırma operatörü),>>(sağa kaydırma operatörü)
- Aritmetik operatörler: +,-, unary-(yalnızca signed sayılar için),*,/,%(modül),**(üs alma operatörü)
contract SayiOperatorleri{
    int256 sayi1 = 2;
    //Sayi1 değerinin 4 üssü alınır. (sayi1 üzeri 4)
    int booldeger1 = sayi1 ** 4;
}
Herhangi bir programlama dilinde proje geliştirirken kodunuzda yer yer bazı şartlar belirtmeniz gerekir. Örnek olarak, karne notunu girmesini beklediğiniz kişinin not aralığı 0 ile 100 arasında olsun. Bu durumda kişi 105 ya da -5 değerini girememelidir. Bu ve benzeri durumları karşılaştırma operatörleri kullanarak sorgulamanız gerekir.
Bilgisayar programlamasında, bit düzeyinde bir işlem, bir bit dizisi, bir bit sayı dizisi veya bir ikili sayı (bir bit dizisi olarak kabul edilir) üzerinde, kendi bitlerinin düzeyinde çalışır. [ayr. bkz.]
Bit operasyonları, Solidity dilinde de kullanılmaktadır.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract BitOperatorleri{
    //Fonksiyon aracılığıyla şart kontrolü yapıyoruz.
    function kontrolFonksiyonu(int x, int y) pure public returns(bool){
        //Bir sayının değilinin değili yine kendisi olacağında x == y şartında bool değer true dönecektir.
        //~(~x) = x
        return ~(~int256(x)) == int256(y);
    }
Kaydırma operatörleri, sağa kaydırma(right shift) ve sola kaydırma(left shift) olarak ikiye ayrılır. Kaydırma işlemlerinde işlemin uygulandığı bitler sağa ya da sola doğru kaydırılır.
Bir bit bloğu üzerinde sağa kaydırma işlemi uyguladığımız zaman o blok üzerindeki tüm bitler bir sağ pozisyona geçerler. En sağdaki bit kaybolur, en soldan bir adet 0 eklenir. [ayr. bkz.]
'x' harfine 1'lik sağa kaydırma işlemi uygulandığında her bit değeri bir sağa doğru kaydırılır. Yeni bir binary değeri elde edilir.
//Bu kod Solidity için geçerli değildir. Mantığın anlatılması için örneklenmiştir. char x = 'x'; // 01111000 char y = x >> 1; // 00111100
Bir bit bloğu üzerinde sola kaydırma işlemi uyguladığımız zaman o blok üzerindeki tüm bitler bir sol pozisyona geçerler. En soldaki bit kaybolur, en sağdan bir adet 0 eklenir. [ayr. bkz.]
//Bu kod Solidity için geçerli değildir. Mantığın anlatılması için örneklenmiştir. char x = 'x'; //01111000 char y = x << 1; // 11110000
Solidity için kaydırma operatörlerinin nasıl kullanıldığını gösteren örnek kod;
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract ShiftOperatorleri{
    //Shift operatörleri.
    function soldanShiftOperasyonuUygula(uint256 x, uint256 y) pure public returns(uint256){
        //x << y
        //İşemin sonucu -->  x * 2 ** y (x çarpı 2 üzeri y)
        return x << y;
    }
    function sagdanShiftOperasyonuUygula(uint256 x, uint256 y) pure public returns(uint256){
        //x >> y
        //İşemin sonucu -->  x / 2 ** y (x bölü 2 üzeri y)
        return x >> y;
    }
    //HATALI KULLANIM! --> Bir kaydırma operasyonu unsigned(uint) değerler kullanılmadığında hata fırlatır.
    function sagdanShiftOperasyonuUygula(int x, int y) pure public returns(int){
        //x >> y
        //İşemin sonucu -->  x / 2 ** y (x bölü 2 üzeri y)
        return x >> y;
    
- x << ybir matematiksel tanım olan- x * 2**y'a eşittir..
- x >> yise benzer şekilde matematiksel tanım olan- x / 2**y'a eşittir ve sayıyı negatif sonsuza yuvarlamaya yarar.
Modulo, bir sayının diğer bir sayıya bölümünden kalanı verir ve %işareti ile gösterilir. İki sayı pozitif olduğunda bölümden kalan bildiğimiz işlemler dahilinde uygulanır. Örneğin, 16 % 4 işleminin sonucu bölme sonrasında kalanın sonucunu yani 0'ı verir. 5 % 4(5 mod 4) işlemi de 1 sonucunu verir.
- int256(16) % int256(4) == int256(0)
- int256(5) % int256(4) == int256(1)
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract ModulOperatorleri{
    function modulIslemiYap(int256 x, int256 y) pure public returns(bool){ 
       //Modül işlemi sonucunda kalan yani sonuç 0 ise doğru dönecektir.
       if(int256(x) % int256(y) == int256(0)){
           return true;
       }
       return false;
    }
}
Bir sayının pozitif diğerinin negatif olduğu durumlarda modül alma işlemi değişkenlik gösterir. Solidity dili için inceleyecek olursak, a % b	için işlem sonucu a % b == -(-a % b) olacaktır.
- int256(-5) % int256(2) == int256(-1)
- int256(5) % int256(-2) == int256(1)
- int256(-5) % int256(-2) == int256(-1)
Üs alma işlemi yalnızca pozitif sayılar(unsigned) için geçerlidir. Üs alma sonucunda ise sonuç tabanın türündeki değerde yani uint	olacaktır.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract UsAlma{
    function usAlmaIslemiYap(uint256 x, uint256 y) pure public returns(uint256){ 
       return x ** y;
    }
}
- Üs alma işlemi yalnızca uintdeğerler için geçerlidir.
- x üzeri 3 matematiksel ifade olarak x ** 3 'e eşittir.
- 0 üssü 0(0**0), Ethereum Sanal Makinesinde sonucunu 1 olarak verir.
address, 20 byte uzunluğundaki Ethereum adresidir. address payable	ise adressden farklı olarak gönderim ve transfer gibi bazı ek özelliklere sahiptir. payableözelliğine sahip olmayan bir address Ethereum transferinden etkilenmez ancak address payable bir Ethereum adresi, işlem sonucunda ETH transfer edebilir. Bu özelliğin payablea bağlı olmasının sebebiyse her akıllı kontrat adresinin ETH transferine ihtiyaç duymamasındandır.
Örneğin, bir akıllı sözleşme yazdığımızı düşünelim. Bu sözleşmenin test sorularını başarılı cevaplayan öğrencilere ödül olarak bir miktar ETH vereceğini düşünelim. Burada her öğrencinin sahip olduğu adresin payable	olması gerekir ki ETH ödülünü alabilsin.
Adresler, balance,	transfer	, code	, codehash	gibi bazı taraflara sahiptir.
- balance, bir adreste bulunan ETH miktarını gösteren değerdir,
- transfer(uint amount), adrese transfer edilecek Wei miktarı işleminin yapıldığı fonksiyondur,
- <address>.codehash(- bytes32), Ethereum Sanal Makinesinde bir hesabı tanımlayan Keccak-256 karma kodunun değeridir
- <address>.code, kullanıldığı adresin Ethereum Sanal Makinesi bytecode değerini- bytes memorytüründe verir.
- <address payable>.send(uint256 amount) returns (bool),- payableözelliğine sahip bir adrese(hesaba) para gönderme işlemi yapabildiğimiz ve ardından- booltüründe dönüt alabildiğimiz fonksiyondur.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/**
 * @title ParaIslemiSozlesmesi
 */
contract ParaIslemiSozlesmesi {
    function hesabimdanParaTransferEt() public payable {
        address payable gonderilecekHesapAdresi =     payable(0xadasd); //test adresi
        gonderilecekHesapAdresi.transfer(200000000);
    }
Eğer transfer	fonksiyonları gönderimi yapacak hesapta yeterli miktarda ETH olmadan çağrılırsa hata dönecektir. Benzer olarak send	fonksiyonu ise hata mesajı yerine bool	türünde false	değeri dönecektir.
Send fonksiyonu kullanırken bazı konulara dikkat etmek gerekir. Gönderim yapacak hesabın yeterli miktarda işlem için gerekli olan asgari miktarın belirtilip belirtilmediği gibi durumların kontrol edilmesi son derece önemlidir.
- call,- delegatecalland- staticcall,- bytes memorydeğerini alarak- boolve- bytestüründe değer ya da değerler döndüren fonksiyonlardır.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/**
 * @title OrnekCallFonksiyonu
 */
contract OrnekCallFonksiyonu{
    function callFonksiyonuCagir() public returns(bool success, bytes memory returnData) {
        bytes memory payload = abi.encodeWithSignature("register(string)", "Isminiz");
        return address(0xadasd).call(payload);
    }
Sağlanan gaz değerini {gas: 12321312}	değişkeni ile ayarlayabilirsiniz.
address(nameReg).call{gas: 1000000}(abi.encodeWithSignature("register(string)", "MyName"));
Benzer olarak değeri de değişterebilirsiniz.
address(nameReg).call{gas: 1000000, value: 1 ether}(abi.encodeWithSignature("register(string)", "MyName"));
- delegatecallfonksiyonu da benzer olarak kullanılır. Farkıysa diğer sözleşmelerde depolanan kütüphane kodlarını kullanmasıdır.
- staticcallfonksiyonu,- callfonksiyonundan farklı olarak bir durum değişikliği yaşandığında işlemi geri çevirir.
- staticcall,- delegatecallve- callfonksiyonları Solidity dilinin tür güvenliğini tehdit eden düşük seviyeli fonksiyonlardır(low-level-functions) ve kullanılması zorda kalmadıkça tercih edilmemelidir.
gas	değişkeni call,staticcallve delegatecall	fonksyionlarında mevcuttur. Ancak value değişkeni yalnızca call	fonksiyonunda geçerlidir.


Sözleşme türleri, değişmezler(literals), listeler(enums), fonksiyon türleri(function types), referans türleri(reference types) ve dizilerin(arrays) de dahil olduğu diğer türleri bir sonraki yazımızda açıklayacağım. Görüşmek üzere!


 
     
     
     
     
     
     
     
     
     
    
Yorumunu Bırak
Yorumlar
0 Yorum yokHenüz yorum yapılmamış. İlk yorum yapan sen ol.