1. Anasayfa
  2. Solidity

Solidity Akıllı Sözleşme CRUD İşlevleri Nasıl Kodlanır?

Solidity Akıllı Sözleşme CRUD İşlevleri Nasıl Kodlanır?
Solidity Akıllı Sözleşme CRUD İşlevleri
0

Solidity Akıllı Sözleşme CRUD İşlevleri

Solidity Akıllı Sözleşme CRUD İşlevleri Nasıl Kodlanır?Akıllı sözleşme geliştirme ve Web3 ekonomisi hala emekleme aşamasındadır ve küresel olarak blockchain geliştiricilerine yüksek talep vardır.

Yakın tarihli bir LinkedIn raporuna göre, Bitcoin, blockchain ve diğer dijital varlıkla ilgili roller gibi terimleri içeren iş ilanları 2021’de Amerika Birleşik Devletleri’nde bir önceki yıla göre yüzde 395 arttı. Yüzde 98’lik bir artışla bu, tüm sektörü dört kat geride bırakarak tarihteki en hızlı büyüyen sektör oldu.

Blockchain geliştirmenin, altı haneli hayalinizdeki işi size bırakma şansı daha yüksek. En havalı kısım, çoğu blok zinciri işinin uzaktan (mekandan bağımsız) olmasıdır, bu nedenle konumlar hakkında endişelenmenize gerek yoktur.

Ama bu alana nasıl atlayıp bu alandan nasıl yararlanırsınız? Teknolojiyle bir şeyler inşa etmeyi öğrenerek.

Web3 geliştirme konusunda sizi hızlandıracak kişisel bir eğitmen arıyorsanız, gelin konuşalım.

Bunu söyledikten sonra, hadi bu eğitime geçelim…

Solidity Akıllı Sözleşme CRUD İşlevleri Nasıl Kodlanır?

Neden Solidity’de CRUD İşlevlerinde Ustalaşmalısınız?

Blok zincirinden kayıt oluşturma, okuma, güncelleme ve silme konusunda uzmanlaşmak, anlamanız gereken bir beceridir. Evet, öğrenmek üzere olduğunuz tekniği kullanarak blok zincirinden (bir dereceye kadar) bir şeyler silebilirsiniz.

İçerik odaklı bir sistemi etkili bir şekilde oluşturmak için CRUD becerilerine ihtiyaç vardır ve blok zinciri, kayıtları değişmez bir şekilde depolamak için bir veritabanı görevi gördüğünden, bilgelik, teknolojiyle nasıl çalışacağınızı anlamanızı gerektirir.

Yine, bir şirket veya bir müşteri için bir blok zinciri projesi üzerinde çalışacaksanız, yine de bazı gereksiz kayıtları kaldırmanız gerekebilir, bu yüzden Solidity CRUD becerilerinizi şimdi ACE yapmalısınız.

Ya bir web3 blog projesi üzerinde çalışıyorsanız ve çok kötü yorumlar için bir silme düğmesi olması gerektiğini biliyorsanız? Bu durumda işlevselliği silmeniz gerekecektir.

Blockchain geliştirmenin derinliklerine daldıkça, iyi bir CRUD bilgisinin kaçınılmaz hale geleceğini görüyorsunuz.

Bu arada, bir blok zinciri ağından bir kaydı silmek, normal bir veritabanından silmekten biraz farklıdır. Kayıt ağda bulunmaya devam edecek ancak web3 uygulamanızdan kaldırılacaktır.

Aşağıdaki tam örnek, bunu nasıl başaracağınızı adım adım gösterecektir.

CRUD İşlevleri Örneği

Bu benim oluşturduğum ve test ettiğim akıllı bir sözleşmedir; nasıl çalıştığını görmek için bir remix düzenleyicide açıp kendiniz çalıştırabilirsiniz.

Ama önce öğreticiyi bitirin; aşağıda her bir işlevi özel olarak açıklayan önemli bilgiler bulunmaktadır.

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

contract Blog {
    address public owner;
    uint256 public activePostCounter = 0;
    uint256 public inactivePostCounter = 0;
    uint256 private postCounter = 0;

    mapping(uint256 => address) public delPostOf;
    mapping(uint256 => address) public authorOf;
    mapping(address => uint256) public postsOf;

    enum Deactivated { NO, YES }

    struct PostStruct {
        uint256 postId;
        string title;
        string description;
        address author;
        Deactivated deleted;
        uint256 created;
        uint256 updated;
    }

    PostStruct[] activePosts;
    PostStruct[] inactivePosts;

    event Action (
        uint256 postId,
        string actionType,
        Deactivated deleted,
        address indexed executor,
        uint256 created
    );

    modifier ownerOnly(){
        require(msg.sender == owner, "Owner reserved only");
        _;
    }

    constructor() {
        owner = msg.sender;
    }

    function createPost(
        string memory title,
        string memory description
    ) external returns (bool) {
        require(bytes(title).length > 0, "Title cannot be empty");
        require(bytes(description).length > 0, "Description cannot be empty");

        postCounter++;
        authorOf[postCounter] = msg.sender;
        postsOf[msg.sender]++;
        activePostCounter++;

        activePosts.push(
            PostStruct(
                postCounter,
                title,
                description,
                msg.sender,
                Deactivated.NO,
                block.timestamp,
                block.timestamp
            )
        );

        emit Action (
            postCounter,
            "POST CREATED",
            Deactivated.NO,
            msg.sender,
            block.timestamp
        );

        return true;
    }

    function updatePost(
        uint256 postId,
        string memory title,
        string memory description
    ) external returns (bool) {
        require(authorOf[postId] == msg.sender, "Unauthorized entity");
        require(bytes(title).length > 0, "Title cannot be empty");
        require(bytes(description).length > 0, "Description cannot be empty");

        for(uint i = 0; i < activePosts.length; i++) {
            if(activePosts[i].postId == postId) {
                activePosts[i].title = title;
                activePosts[i].description = description;
                activePosts[i].updated = block.timestamp;
            }
        }

        emit Action (
            postId,
            "POST UPDATED",
            Deactivated.NO,
            msg.sender,
            block.timestamp
        );

        return true;
    }

    function showPost(
        uint256 postId
    ) external view returns (PostStruct memory) {
        PostStruct memory post;
        for(uint i = 0; i < activePosts.length; i++) {
            if(activePosts[i].postId == postId) {
                post = activePosts[i];
            }
        }
        return post;
    }

    function getPosts() external view returns (PostStruct[] memory) {
        return activePosts;
    }

    function getDeletedPost() ownerOnly external view returns (PostStruct[] memory) {
        return inactivePosts;
    }

    function deletePost(uint256 postId) external returns (bool) {
        require(authorOf[postId] == msg.sender, "Unauthorized entity");

        for(uint i = 0; i < activePosts.length; i++) {
            if(activePosts[i].postId == postId) {
                activePosts[i].deleted = Deactivated.YES;
                activePosts[i].updated = block.timestamp;
                inactivePosts.push(activePosts[i]);
                delPostOf[postId] = authorOf[postId];
                delete activePosts[i];
                delete authorOf[postId];
            }
        }

        postsOf[msg.sender]--;
        inactivePostCounter++;
        activePostCounter--;

        emit Action (
            postId,
            "POST DELETED",
            Deactivated.YES,
            msg.sender,
            block.timestamp
        );

        return true;
    }
    
    function restorDeletedPost(
        uint256 postId, 
        address author
    ) ownerOnly external returns (bool) {
        require(delPostOf[postId] == author, "Unmatched Author");

        for(uint i = 0; i < inactivePosts.length; i++) {
            if(inactivePosts[i].postId == postId) {
                inactivePosts[i].deleted = Deactivated.NO;
                inactivePosts[i].updated = block.timestamp;

                activePosts.push(inactivePosts[i]);
                delete inactivePosts[i];
                authorOf[postId] = delPostOf[postId];
                delete delPostOf[postId];
            }
        }

        postsOf[author]++;
        inactivePostCounter--;
        activePostCounter++;

        emit Action (
            postId,
            "POST RESTORED",
            Deactivated.NO,
            msg.sender,
            block.timestamp
        );

        return true;
    }
}

Pekala, bu akıllı sözleşmeyi adım adım inceleyelim; yeni başlayan biriyseniz, endişelenmeyin; Basitliği göstermek için bu akıllı sözleşme örneğini yazdım.

Adım 1: Akıllı sözleşme yapısı

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Blog {
  // code goes here...
}

Bu tipik bir akıllı sözleşme yapısıdır; onu nesne yönelimli programlamada bir sınıf olarak kabul edin, çünkü gerçekte birdir.

SPDX, akıllı sözleşmenin lisans türünü belirtmek için kullanılır. Pragma, akıllı sözleşme için kullanılacak sağlamlık derleyicisinin sürümünü ifade eder. Son olarak, akıllı sözleşmenin adı Blog’dur.

Dosya adının her zaman sınıf adına karşılık gelmesi gerektiğine dikkat etmek önemlidir; bu, tutarlılığı sağlayacak ve kodunuzdaki gereksiz hataları önleyecektir.

Adım 2: Sözleşme Değişkenlerini Tanımlama

address public owner;
uint256 public activePostCounter = 0;
uint256 public inactivePostCounter = 0;
uint256 private postCounter = 0;

Burada iki tür değişkenimiz var: address ve uint256. Bir adres, bir kullanıcının hesabını temsil ederken uint256, 0 ile 256–1 arasında değişen işaretsiz bir tamsayıyı temsil eder.

Sahibi, konuşlandırıcının hesabını tutar ve activePostCounter bir dizi kullanılabilir gönderiyi tutar. inactivePostCounter, kurtarılması gerekmesi durumunda silinen gönderiyi takip eder. postCounter, akıllı sözleşmedeki toplam gönderi sayısını tutar, ancak özeldir.

Adım 3: Eşlemeleri Tanımlama

mapping(uint256 => address) public delPostOf;
mapping(uint256 => address) public authorOf;
mapping(address => uint256) public postsOf;

authorOf(), bir postId kabul eden ve gönderi yazarının adresini döndüren eşlenmiş bir değişkendir. postsOf() bir yazarın gönderilerini takip ederken, delPostOf() her yazar için bir geri dönüşüm kutusu görevi görür.

Adım 4: Enum Tanımlama

enum Deactivated { NO, YES }

Bu, bir gönderinin silinip silinmediğini belirtmek için kullanılır. Enum, alfabetik bir değeri sıfırla başlayan işaretsiz tam sayılara dönüştürür. Örneğin, HAYIR ve EVET değerleri sırasıyla 0 ve 1 olur.

Adım 5: Yapının Tanımlanması

struct PostStruct {
    uint256 postId;
    string title;
    string description;
    address author;
    Deactivated deleted; // We are using the enum here
    uint256 created;
    uint256 updated;
}

PostStruct[] activePosts;
PostStruct[] inactivePosts;

Yapılar, iki veya daha fazla veri türünden oluşan karmaşık veri yapılarını tanımlamak için kullanılır.

Bir gönderinin kimliği, başlığı, açıklaması, yazarı, silinmiş anahtarı, oluşturulma zamanı ve güncelleme zamanı olması gerektiğini yukarıdaki PostStruct‘ta belirtmiştik.

Sonra iki dizi yaptık: biri aktif gönderiler için, diğeri aktif olmayan gönderiler veya silinmiş gönderiler için. Bu yöntem veri kaybını önler, ancak tek bir dizi de kullanabilir ve yalnızca silinen anahtarı açıp kapatabilirsiniz.

Ancak, bu başka bir sorunu gündeme getiriyor: aktif gönderileri göstermeden önce hepsini ön uç uygulamanızda okumanız gerekecek. Seni o yolculuktan kurtarmak istiyorum.

Adım 6: Bir Olay Tanımlama

event Action (
    uint256 postId,
    string actionType,
    Deactivated deleted,
    address indexed executor,
    uint256 created
);

Sırasıyla oluşturulan, güncellenen, silinen ve geri yüklenen işlevler hakkında bazı hayati bilgileri yaymak için dinamik bir olay tanımladık.

Adım 7 : Değiştiriciyi tanımlama

modifier ownerOnly(){
    require(msg.sender == owner, "Owner reserved only");
    _;
}

Değiştirici, derleme zamanında başka bir işlevin davranışını değiştiren bir işlevdir. Bir işlevi yürütmek için bir ön koşul olduğunu söyleyebiliriz.

Yukarıdaki değiştiricide, bu değiştiricinin ekleneceği işlevin arayanın akıllı sözleşmenin sahibi veya dağıtıcısı olması gerektiğini belirttik.

Adım 8: Yapıcıyı Tanımlama

constructor() {
    owner = msg.sender;
}

OOP bilginize dayanarak, bir sınıf başlatıldığında çalıştırılan her zaman ilk işlev bir kurucudur. OOP inşaatı akıllı sözleşmelerle karşılıklıdır.

Bu akıllı sözleşme dağıtıldığında çalıştırılacak ilk işlev yapıcıdır ve bunun sahibini akıllı sözleşmeyi dağıtan yapması gerektiğini belirttik.

Adım 9 : createPost() işlevi

function createPost(
    string memory title,
    string memory description
) external returns (bool) {
    // Checks for empty string
    require(bytes(title).length > 0, "Title cannot be empty");
    require(bytes(description).length > 0, "Description cannot be empty");

    // Performs computations
    postCounter++;
    authorOf[postCounter] = msg.sender;
    postsOf[msg.sender]++;
    activePostCounter++;

    // Adds post to array
    activePosts.push(
        PostStruct(
            postCounter,
            title,
            description,
            msg.sender,
            Deactivated.NO,
            block.timestamp,
            block.timestamp
        )
    );
  
    // Emits a created event
    emit Action (
        postCounter,
        "POST CREATED",
        Deactivated.NO,
        msg.sender,
        block.timestamp
    );
    
    // Returns success
    return true;
}

Bu işlev, oluşturma sonrası işlemini beş adımda gerçekleştirir.

İlk olarak, akıllı sözleşmeye yalnızca boş bir dize değil, gerçek bilgiler gönderip göndermediğinizi kontrol eder.

İkinci olarak, yazarı gönderi sahibi yapmak da dahil olmak üzere blog ve yazar için gönderi sayılarını artırmak gibi bazı hesaplamalar gerçekleştirir.

Üçüncüsü, daha önce tanımlanan PostStruct‘u kullanarak gönderiyi activePost‘lara ekler.

Dördüncüsü, EVM’de oturumu kapatan bir “POST CREATED” olayı yayar, bu, bir işlemde yakalanan bilgileri zenginleştirmek için gereklidir.

Son olarak, tüm işlevin başarıyla çalıştığını gösteren gerçek bir boole anahtarı döndürdük.

Adım 10: updatePost() işlevi

function updatePost(
    uint256 postId,
    string memory title,
    string memory description
) external returns (bool) {
    // Checks for empty string
    require(authorOf[postId] == msg.sender, "Unauthorized entity");
    require(bytes(title).length > 0, "Title cannot be empty");
    require(bytes(description).length > 0, "Description cannot be empty");

    // Changes post record
    for(uint i = 0; i < activePosts.length; i++) {
        if(activePosts[i].postId == postId) {
            activePosts[i].title = title;
            activePosts[i].description = description;
            activePosts[i].updated = block.timestamp;
        }
    }
    
    // Emits a updated event
    emit Action (
        postId,
        "POST UPDATED",
        Deactivated.NO,
        msg.sender,
        block.timestamp
    );
  
    // Returns success
    return true;
}

Bu işlev, bir createPost() işlevi gibi çalışır. Aradaki fark, boş bir dizeyi kontrol ederken updatePost() işlevinin, işlevi güncelleyen kişinin gönderi sahibi (yazar) olmasını sağlamasıdır.

Ardından, kimliğe göre belirli gönderiyi hedefler ve kaydı günceller.

Adım 11: showPost() işlevi

function showPost(
    uint256 postId
) external view returns (PostStruct memory) {
    PostStruct memory post;
    for(uint i = 0; i < activePosts.length; i++) {
        if(activePosts[i].postId == postId) {
            post = activePosts[i];
        }
    }
    return post;
}

Bu, activePost dizisinde tekrar tekrar bir eşleşme arayarak gönderimize döner.

Adım 12: getPosts() işlevi

function getPosts() external view returns (PostStruct[] memory) {
    return activePosts;
}

Mevcut tüm aktif blog gönderilerini döndürür.

Adım 13: getDeletedPost() işlevi

function getDeletedPost() 
  ownerOnly external view returns (PostStruct[] memory) {
    return inactivePosts;
}

Bu, silinen tüm gönderileri döndürür ve yalnızca blogun sahibi tarafından erişilebilir.

Adım 14: deletePost() işlevi

function deletePost(uint256 postId) external returns (bool) {
    // check if post belong to user
    require(authorOf[postId] == msg.sender, "Unauthorized entity");
    
    // find and delete post
    for(uint i = 0; i < activePosts.length; i++) {
        if(activePosts[i].postId == postId) {
            activePosts[i].deleted = Deactivated.YES;
            activePosts[i].updated = block.timestamp;
            inactivePosts.push(activePosts[i]);
            delPostOf[postId] = authorOf[postId];
            delete activePosts[i];
            delete authorOf[postId];
        }
    }

    // Recallibrate counters
    postsOf[msg.sender]--;
    inactivePostCounter++;
    activePostCounter--;

    // Emits event
    emit Action (
        postId,
        "POST DELETED",
        Deactivated.YES,
        msg.sender,
        block.timestamp
    );
  
    // Returns success
    return true;
}

Yukarıdaki fonksiyon dört adımda elde edilmiştir.

İlk olarak, silenin gönderinin sahibi olduğunu doğruladık, ardından gönderiyi aradık, sildi ve true boole değeri döndüren bir “POST DELETED” olayı yayınladık.

Lütfen silme davranışının normal bir veritabanındaki gibi yapılmadığını unutmayın, bunun yerine iki dizi belirledik; activePosts ve inactivePosts. Bir gönderiyi sildiğimizde, inactivePosts dizisine taşınacak ve gönderi yazarının isteği üzerine yalnızca blog sahibi onu geri yükleyebilir.

Adım 15: Geri Yükleme Sonrası İşlevi

function restorDeletedPost(
    uint256 postId, 
    address author
) ownerOnly external returns (bool) {
    // checks if post exists in users recycle bin
    require(delPostOf[postId] == author, "Unmatched Author");

    // Finds and restore the post to the author
    for(uint i = 0; i < inactivePosts.length; i++) {
        if(inactivePosts[i].postId == postId) {
            inactivePosts[i].deleted = Deactivated.NO;
            inactivePosts[i].updated = block.timestamp;
            activePosts.push(inactivePosts[i]);
            delete inactivePosts[i];
            authorOf[postId] = delPostOf[postId];
            delete delPostOf[postId];
        }
    }

    // Recallibrates counter to reflect restored post
    postsOf[author]++;
    inactivePostCounter--;
    activePostCounter++;

    // Emits a restoration event
    emit Action (
        postId,
        "POST RESTORED",
        Deactivated.NO,
        msg.sender,
        block.timestamp
    );

    // resturns success
    return true;
}

Bir gönderi geri yüklendiğinde, inactivePosts dizisinden activePosts dizisine taşınır.

Silme kalıbınızı benimkinden biraz farklı tasarlayabileceğinizi belirtmekte fayda var. Yukarıda oluşturduğumuz enum Devre dışı bırakılmış yapısından yararlanmaya karar verebilir ve yalnızca silinmiş durumu EVET veya HAYIR olarak değiştirerek silebilirsiniz.

Solidity Akıllı Sözleşme CRUD İşlevleri Sonuç Bağlamı

Bu eğitimde sizinle yolculuk yapmak çok keyifliydi, umarım Solidity akıllı sözleşme CRUD işlevlerinin nasıl yazılacağına dair değerli bilgiler edinmişsinizdir.

Akıllı sözleşme geliştirme 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.

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!

Bir sonraki eğitimde görüşmek dileğiyle, o zamana kadar iyi eğlenceler!

Hasan YILDIZ, Girişimci. Doktora Öğrencisi. Yazmayan YAZILIMCI. Veri Şeysi. Eğitmen...

Yazarın Profili
İlginizi Çekebilir

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