1. Anasayfa
  2. 100 Günde Solidity

🧵 #100GündeSolidity 050 : Iterable Mapping

🧵 #100GündeSolidity 050 : Iterable Mapping
Iterable Mapping
0

Iterable Mapping Nedir ve Nasıl Kullanılır?

Merhaba, bu e-bültenimizde Solidity programlama dili ile çalışanlar için oldukça faydalı olan “Iterable Mapping” kavramını ele alacağız. Iterable Mapping, Ethereum blockchainindeki akıllı sözleşmelerde kullanılan bir veri yapısıdır. Bu veri yapısı, daha önceki versiyonlarda bulunmayan bir özellik olup, Solidity programlama dilinin 0.6.0 sürümü ile birlikte sunulmuştur. Iterable Mapping, sözleşmelerdeki sözde döngülerin önlenmesine ve kodun daha verimli hale getirilmesine yardımcı olur. Bu e-bültenimizde Iterable Mapping’in ne olduğunu, nasıl kullanıldığını, avantajlarını, örneklerini ve daha fazlasını öğreneceğiz.

Iterable Mapping Nedir?

Iterable Mapping, Ethereum blockchaininde çalışan akıllı sözleşmelerde kullanılan bir veri yapısıdır. Bu veri yapısı, bir harita (mapping) ile birlikte kullanıldığında, haritanın anahtarlarına iterasyon yapılmasını sağlar. Yani, haritanın tüm anahtarlarını veya tüm değerlerini döngü ile gezinmek mümkün hale gelir.

Öncesinde Solidity’de, haritaların anahtarlarına iterasyon yapmak mümkün değildi. Ancak Iterable Mapping sayesinde, haritanın tüm anahtarlarına erişmek mümkün hale gelmiştir. Bu sayede, programcılar sözde döngülerden kaçınarak kodlarını daha verimli ve okunaklı hale getirebilirler. Ayrıca, Iterable Mapping ile birlikte, haritanın içindeki verilere erişmek ve değiştirmek daha da kolaylaşır.

Iterable Mapping Nasıl Kullanılır?

Iterable Mapping kullanmak oldukça basittir. İlk olarak, Solidity programlama dilinin 0.6.0 sürümü veya daha üst sürümleri kullanılmalıdır. Daha sonra, bir harita (mapping) oluşturulmalıdır. Bu haritanın anahtarlarına erişmek istediğimizde, “for” döngüsü kullanırız. Aşağıdaki örnek kodda, bir “Student” yapılandırmasını (struct) kullanarak, “students” adında bir harita oluşturulmuştur.

pragma solidity ^0.6.0;

contract IterableMappingExample {
    struct Student {
        string name;
        uint age;
    }
    mapping(uint => Student) students;
    uint[] studentIds;

    function addStudent(uint id, string memory name, uint age) public {
        students[id] = Student(name, age);
        studentIds.push(id);
    }

    function getStudents() public view returns (string[] memory, uint[] memory) {
        string[] memory names = new string[](studentIds.length);
        uint[] memory ages = new uint[](studentIds.length);

        for (uint i = 0; i < studentIds.length; i++) {
            Student storage student = students[studentIds[i]];
            names[i] = student.name;
            ages[i] = student.age;
        }

        return (names, ages);
    }
}

Yukarıdaki örnekte, “addStudent” fonksiyonu, “students” haritasına yeni öğrenciler ekler ve “studentIds” dizisine öğrenci kimliklerini ekler. “getStudents” fonksiyonu, “students” haritasının tüm anahtarlarına erişmek için “for” döngüsünü kullanır ve öğrencilerin isimlerini ve yaşlarını döndürür.

Bu örnekte, “for” döngüsünü kullanarak haritanın tüm anahtarlarına erişildi. Bu, Iterable Mapping sayesinde mümkün hale gelmiştir.

Iterable Mapping’in Avantajları Nelerdir?

Iterable Mapping, Solidity programlama dili için birçok avantaj sağlar. İşte Iterable Mapping’in bazı avantajları:

  1. Sözde döngülerin önlenmesi: Solidity’de, haritaların anahtarlarına erişmek için genellikle sözde döngüler kullanılır. Ancak, bu yöntem, gas kullanımı açısından oldukça maliyetlidir. Iterable Mapping sayesinde, sözde döngülerin kullanımı azaltılır ve gas maliyetleri düşürülür.
  2. Kodun daha verimli hale getirilmesi: Iterable Mapping sayesinde, haritanın tüm anahtarlarına veya tüm değerlerine erişmek oldukça kolaylaşır. Bu da kodun daha okunaklı ve anlaşılır hale gelmesine yardımcı olur.
  3. Çoklu değişikliklerin kolaylaştırılması: Iterable Mapping sayesinde, haritanın içindeki verilere erişmek ve değiştirmek daha da kolaylaşır. Bu sayede, birden fazla veri değişikliği yapmak için ayrı ayrı döngüler kullanmak yerine, tek bir döngü kullanarak tüm değişiklikler yapılabilir.
  4. Harita boyutunun bilinmemesi durumunda bile kullanılabilir: Iterable Mapping, haritanın boyutunu bilmemize gerek olmadığı için, boyutu değişken olan haritalarda da kullanılabilir.
  5. Daha az kod yazma: Iterable Mapping, kodun daha az yazılmasını sağlar. Çünkü, haritanın tüm anahtarlarına veya tüm değerlerine erişmek için ayrı ayrı döngüler kullanmak yerine, tek bir döngü kullanarak tüm işlemleri yapabiliriz.
  6. Kodun daha az hata içermesi: Iterable Mapping, kodun daha az hata içermesine yardımcı olur. Çünkü, sözde döngülerin kullanımı azaltılır ve bu da kod hatalarını azaltır.

Bu avantajlar sayesinde, Iterable Mapping, Solidity programlama dilinde oldukça faydalı bir veri yapısıdır.

Iterable Mapping ile Sözde Döngülerin Önlenmesi

Solidity programlama dilinde, haritaların anahtarlarına erişmek için genellikle sözde döngüler kullanılır. Ancak, sözde döngülerin kullanımı, gas kullanımı açısından oldukça maliyetlidir. Iterable Mapping, sözde döngülerin kullanımını azaltarak, gas maliyetlerini düşürür.

Sözde döngüler, Solidity programlama dilinde sıkça kullanılan bir döngü türüdür. Sözde döngüler, haritaların anahtarlarını tutan bir dizi kullanarak, harita boyunca döngü oluştururlar. Ancak, harita boyutu ne kadar büyükse, gas maliyetleri de o kadar yüksek olur. Bu nedenle, sözde döngülerin kullanımı, gas kullanımı açısından oldukça maliyetlidir.

Iterable Mapping, haritaların tüm anahtarlarına erişmek için sözde döngülerin kullanımını azaltır. Iterable Mapping sayesinde, haritanın tüm anahtarlarına erişmek için “for” döngüsü kullanabiliriz. Bu döngü, harita boyunca tek tek dolaşır ve her bir anahtar için istenen işlem yapılır. Bu sayede, sözde döngülerin kullanımı azaltılır ve gas maliyetleri düşürülür.

İşte bir örnek:

pragma solidity ^0.6.0;

contract MapExample {
    mapping(uint => string) myMap;

    function addElement(uint key, string memory value) public {
        myMap[key] = value;
    }

    function usePseudoLoop() public view returns (string[] memory) {
        string[] memory values = new string[](getSize());

        for (uint i = 0; i < getSize(); i++) {
            values[i] = myMap[i];
        }

        return values;
    }

    function useIterableMapping() public view returns (string[] memory) {
        string[] memory values = new string[](getSize());

        for (uint i = 0; i < getSize(); i++) {
            values[i] = myMap.get(i);
        }

        return values;
    }

    function getSize() public view returns (uint) {
        return 10;
    }
}

Yukarıdaki örnekte, “usePseudoLoop” fonksiyonu, haritanın boyunca dolaşarak tüm anahtarları alır ve “values” dizisine ekler. Ancak, “useIterableMapping” fonksiyonu, Iterable Mapping kullanarak tüm anahtarları alır ve “values” dizisine ekler. Bu sayede, sözde döngülerin kullanımı azaltılır ve gas maliyetleri düşürülür.

Iterable Mapping ile Çoklu Değişikliklerin Kolaylaştırılması

Iterable Mapping, haritalarda birden fazla değişiklik yapmayı kolaylaştırır. Haritaların tüm anahtarlarına erişmek için kullanılan “for” döngüsü sayesinde, tüm anahtarların değerlerine erişmek ve bunları değiştirmek çok daha kolay hale gelir.

Ayrıca, Iterable Mapping sayesinde, birden fazla değişikliği birleştirmek de daha kolay hale gelir. Haritanın tüm anahtarlarına erişmek ve birden fazla değişiklik yapmak için tek bir “for” döngüsü kullanarak, birden fazla değişikliği kolayca birleştirebiliriz.

Örnek olarak aşağıdaki Solidity kodunu inceleyebilirsiniz:

pragma solidity ^0.8.0;

contract MapExample {
    mapping(uint => string) myMap;

    function addElement(uint key, string memory value) public {
        myMap[key] = value;
    }

    function changeValues(string[] memory newValues) public {
        require(newValues.length == getSize(), "Invalid size");
        
        for (uint i = 0; i < getSize(); i++) {
            myMap[i] = newValues[i];
        }
    }

    function getSize() public pure returns (uint) {
        return 10;
    }
}

Yukarıdaki örnekte, “changeValues” fonksiyonu, haritanın tüm anahtarlarına erişerek, her bir anahtarın değerini değiştirir. Bu sayede, birden fazla değişikliği kolayca birleştirebiliriz. Ayrıca, “require” ifadesi ile de, yeni değerlerin doğru boyutta olduğunu kontrol ederiz.

Bu örnekte, Iterable Mapping kullanımı, haritanın tüm anahtarlarına erişerek birden fazla değişikliği kolayca gerçekleştirmemize olanak sağlar.

Iterable Mapping’in Limitleri ve Kullanım Alanları

Iterable Mapping, Solidity dilinde oldukça kullanışlı bir veri yapısıdır ve birçok avantajı bulunmaktadır. Ancak, kullanım alanlarına ve limitlerine de dikkat etmek gerekmektedir.

Iterable Mapping’in en önemli limiti, gas tüketimidir. Iterable Mapping, haritaları daha verimli hale getirmek için ekstra bir kodlama katmanı eklediği için, bu veri yapısını kullanmak gas maliyetini artırabilir. Bu nedenle, özellikle büyük boyutlu haritalar için Iterable Mapping kullanmak daha pahalı olabilir.

Bu nedenle, Iterable Mapping özellikle, birden çok değişkenin depolanması gerektiği durumlarda kullanılması daha uygun olabilir. Örneğin, token sahiplikleri, oy hakları, sıralama vb. durumlarda kullanılabilir.

Ayrıca, Iterable Mapping, Solidity’deki diğer veri yapılarıyla da birlikte kullanılabilir. Örneğin, Iterable Mapping, Solidity’deki struct veri yapısıyla birleştirilerek, haritalara karmaşık veriler eklemek için kullanılabilir. Iterable Mapping, bu veri yapısını, Solidity’deki diğer veri yapılarıyla birlikte kullanarak, daha esnek ve güçlü bir veri depolama çözümü sunar.

Sonuç olarak, Iterable Mapping, Solidity dilinde kullanışlı bir veri yapısıdır. Ancak, kullanım alanlarına ve limitlerine dikkat etmek gerekmektedir. Iterable Mapping, birden fazla değişkenin depolanması gerektiği durumlarda kullanılabileceği gibi, diğer veri yapılarıyla birlikte kullanılarak daha karmaşık verilerin depolanması için de kullanılabilir.

Iterable Mapping Örnekleri ve Kod Parçaları

Iterable Mapping, Solidity’de oldukça kullanışlı bir veri yapısıdır ve birçok farklı kullanım alanı vardır. Aşağıda, Iterable Mapping’in örnekleri ve kod parçaları yer almaktadır.

  1. Token sahipliği depolama:
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;

function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
}

function transfer(address recipient, uint256 amount) public returns (bool) {
    _transfer(_msgSender(), recipient, amount);
    return true;
}

function _transfer(address sender, address recipient, uint256 amount) internal {
    require(sender != address(0), "ERC20: transfer from the zero address");
    require(recipient != address(0), "ERC20: transfer to the zero address");

    _balances[sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(sender, recipient, amount);
}

Yukarıdaki örnekte, ERC20 standartlarına uygun bir token sahipliği depolama sistemi gösterilmektedir. “mapping” anahtar kelimesiyle tanımlanan _balances ve _allowances haritaları, her bir kullanıcının token sahipliği ve izinleri tutulur.

  1. Sıralama depolama:
mapping(uint256 => address) private _accounts;
mapping(address => uint256) private _balances;

function addAccount(address account) public {
    uint256 newIndex = getSize();
    _accounts[newIndex] = account;
    _balances[account] = 0;
}

function removeAccount(address account) public {
    uint256 index = getIndex(account);
    delete _accounts[index];
    delete _balances[account];
}

function getSize() public view returns (uint256) {
    uint256 size = 0;
    for (uint256 i = 0; i < _accounts.length; i++) {
        if (_accounts[i] != address(0)) {
            size++;
        }
    }
    return size;
}

function getIndex(address account) public view returns (uint256) {
    for (uint256 i = 0; i < _accounts.length; i++) {
        if (_accounts[i] == account) {
            return i;
        }
    }
    revert("Account not found");
}

Yukarıdaki örnekte, sıralama depolama sistemi gösterilmektedir. _accounts ve _balances haritaları, sıralama ve bakiye bilgilerini depolar. getSize ve getIndex fonksiyonları, haritadaki değerleri almak için kullanılır.

  1. Oy depolama:
mapping(address => bool) private _hasVoted;
mapping(address => uint256) private _voteCount;

function vote() public {
    require(!_hasVoted[_msgSender()], "You have already voted");
    _hasVoted[_msgSender()] = true;
    _voteCount[_msgSender()] += 1;
}

function getVoteCount(address voter) public view returns (uint256) {
    return _voteCount[voter];
}

Yukarıdaki örnekte, oy depolama sistemi gösterilmektedir. _hasVoted ve _voteCount haritaları, kullanıcının oy kullandığı bilgileri depolar.

Bu örneklerde, Iterable Mapping’in farklı kullanım alanlarına örnekler verilmiştir. İlk örnekte, token sahipliği depolama işlemi için haritalar kullanılmıştır. İkinci örnekte, sıralama depolama işlemi için haritalar kullanılmıştır. Üçüncü örnekte ise, oy depolama işlemi için haritalar kullanılmıştır. Bu örnekler, Iterable Mapping’in Solidity’de çeşitli kullanım alanlarına sahip olduğunu göstermektedir.

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

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

library IterableMapping {
    // Iterable mapping from address to uint;
    struct Map {
        address[] keys;
        mapping(address => uint) values;
        mapping(address => uint) indexOf;
        mapping(address => bool) inserted;
    }

    function get(Map storage map, address key) public view returns (uint) {
        return map.values[key];
    }

    function getKeyAtIndex(Map storage map, uint index) public view returns (address) {
        return map.keys[index];
    }

    function size(Map storage map) public view returns (uint) {
        return map.keys.length;
    }

    function set(Map storage map, address key, uint val) public {
        if (map.inserted[key]) {
            map.values[key] = val;
        } else {
            map.inserted[key] = true;
            map.values[key] = val;
            map.indexOf[key] = map.keys.length;
            map.keys.push(key);
        }
    }

    function remove(Map storage map, address key) public {
        if (!map.inserted[key]) {
            return;
        }

        delete map.inserted[key];
        delete map.values[key];

        uint index = map.indexOf[key];
        uint lastIndex = map.keys.length - 1;
        address lastKey = map.keys[lastIndex];

        map.indexOf[lastKey] = index;
        delete map.indexOf[key];

        map.keys[index] = lastKey;
        map.keys.pop();
    }
}

contract TestIterableMap {
    using IterableMapping for IterableMapping.Map;

    IterableMapping.Map private map;

    function testIterableMap() public {
        map.set(address(0), 0);
        map.set(address(1), 100);
        map.set(address(2), 200); // insert
        map.set(address(2), 200); // update
        map.set(address(3), 300);

        for (uint i = 0; i < map.size(); i++) {
            address key = map.getKeyAtIndex(i);

            assert(map.get(key) == i * 100);
        }

        map.remove(address(1));

        // keys = [address(0), address(3), address(2)]
        assert(map.size() == 3);
        assert(map.getKeyAtIndex(0) == address(0));
        assert(map.getKeyAtIndex(1) == address(3));
        assert(map.getKeyAtIndex(2) == address(2));
    }
}

Bu akıllı sözleşme, Iterable Mapping kütüphanesini kullanarak bir örnek uygulama sunmaktadır. Öncelikle, kütüphane bir harita yapısı tanımlar. Bu harita yapısı, bir anahtar-değer çiftlerini depolar ve bu çiftlere erişim sağlar.

Harita yapısı, üç adet yardımcı harita yapısı kullanır:

  • keys: Depolanan anahtarların listesini tutar.
  • values: Anahtarların karşılık gelen değerlerini tutar.
  • indexOf: Anahtarların depolama dizisindeki indekslerini tutar.
  • inserted: Anahtarların haritada depolanıp depolanmadığını tutar.

Kütüphane, haritayı erişmek ve düzenlemek için beş adet fonksiyon sağlar:

  • get: Verilen anahtar için değeri döndürür.
  • getKeyAtIndex: Verilen dizin için anahtarı döndürür.
  • size: Haritadaki anahtarların sayısını döndürür.
  • set: Verilen anahtar için değeri ayarlar. Eğer anahtar zaten varsa, değeri günceller.
  • remove: Verilen anahtarı haritadan siler.

Akıllı sözleşme, IterableMapping kütüphanesini kullanarak bir TestIterableMap sözleşmesi oluşturur. Bu sözleşme, haritayı test etmek için bazı işlemler yapar. Önce dört anahtar-değer çifti eklenir, bir tanesi güncellenir. Sonra, tüm anahtarlar üzerinde dönen bir döngü kullanarak haritanın doğru şekilde depolama ve erişim işlemlerini gerçekleştirdiğinden emin olunur. Son olarak, bir anahtar silinir ve haritanın doğru şekilde yeniden düzenlendiğinden emin olunur.

Bu örnek, Iterable Mapping kütüphanesinin nasıl kullanılacağına dair bir örnek sunar ve harita yapısı kullanarak basit bir depolama örneği gösterir.

Iterable Mapping ile İlgili İpuçları ve Püf Noktaları

Iterable Mapping kullanırken dikkat etmeniz gereken bazı ipuçları ve püf noktaları şunlardır:

  1. Iterable Mapping kullanmadan önce, geleneksel mapping kullanımı hakkında temel bir anlayışa sahip olmanız önerilir. Iterable Mapping, geleneksel mapping yapılarını genişletir, bu nedenle bu yapıların temellerini anlamak önemlidir.
  2. Iterable Mapping yapısını kullanırken, ilgili kütüphaneyi çağırmayı ve yapının bir örneğini oluşturmayı unutmayın.
  3. Iterable Mapping yapısı kullanırken, fonksiyonlar için doğru erişim belirteçlerini kullanmak önemlidir. public fonksiyonlar, harici çağrıları mümkün kılar ve view belirteci, fonksiyonların herhangi bir değişiklik yapmadan okunmasını sağlar.
  4. Iterable Mapping yapısını kullanmadan önce, sözleşmenizdeki gas limitlerini kontrol edin. Iterable Mapping, sözleşmenin büyüklüğüne ve karmaşıklığına bağlı olarak gas tüketebilir, bu nedenle özellikle büyük ve karmaşık sözleşmelerde gas limitlerinin yeterli olduğundan emin olun.
  5. Iterable Mapping yapısı, sözleşmelerinizdeki birden fazla veri öğesini takip etmenizi kolaylaştırır. Bununla birlikte, Iterable Mapping kullanmadan önce, verilerinizi iyi organize ettiğinizden emin olun ve gereksiz verileri takip etmek yerine, yalnızca ihtiyacınız olan verileri saklayın.
  6. Iterable Mapping yapısı, sözleşmenizdeki değişiklikleri takip etmek ve geçmiş verilere erişmek için faydalıdır. Bu nedenle, sözleşmenizdeki belirli bir veri öğesinin geçmiş değerlerini izlemek için Iterable Mapping yapısını kullanabilirsiniz.

Sonuç Bağlamı

Bu e-bültenimizde Iterable Mapping kavramını ele aldık. Iterable Mapping, Solidity dilinde bir veri yapısıdır ve sözleşmelerde daha etkili bir şekilde verileri yönetmemizi sağlar. Bu veri yapısı, döngüleri önleyerek gas tasarrufu sağlar ve çoklu değişiklikleri kolaylaştırır. Iterable Mapping aynı zamanda, bir veri yapısı olarak bazı sınırlamalara sahiptir ve sadece belirli kullanım alanları için uygun olabilir.

Akıllı sözleşme örneğiyle birlikte Iterable Mapping’in nasıl kullanılacağı ve nasıl uygulanacağı hakkında ayrıntılı bilgi verdik. Ayrıca Iterable Mapping’in avantajlarını ve sınırlamalarını da ele aldık. İpuçları ve püf noktaları bölümünde ise Iterable Mapping kullanırken dikkat edilmesi gereken bazı önemli noktalara değindik.

Iterable Mapping, Solidity programlama dilinde oldukça yararlı bir veri yapısıdır ve özellikle sözleşme geliştiricileri tarafından yaygın bir şekilde kullanılır. Iterable Mapping’in fonksiyonlarına hakim olmak ve veri yapısını etkili bir şekilde kullanmak, Solidity dilinde verimli ve güvenli sözleşmeler yazmamızı sağlar.

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
İlginizi Çekebilir

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