1. Anasayfa
  2. 100 Günde Solidity

🧵 100GündeSolidity 054 : Önceden Hesaplanmış Sözleşme Adresleri Oluşturma

🧵 100GündeSolidity 054 : Önceden Hesaplanmış Sözleşme Adresleri Oluşturma
Önceden Hesaplanmış Sözleşme Adresleri Oluşturma
0

Önceden Hesaplanmış Sözleşme Adresleri Oluşturma

Solidity, akıllı sözleşmelerin yazılması için en çok kullanılan dillerden biridir ve Ethereum’un ana dili olarak kabul edilir. Solidity, Ethereum sanal makinesi (EVM) üzerinde çalışır ve akıllı sözleşmelerin yazımı ve yürütülmesi için gerekli olan tüm araçları sağlar.

Solidity’de “create” yöntemi ile yeni sözleşmeler oluşturabiliriz. Ancak bu yöntemle oluşturulan sözleşmelerin adresleri, sözleşme oluşturulduğu anda belirlenir. Bu nedenle, sözleşmelerin gelecekteki bir tarihte oluşturulması gereken durumlarda sorunlar ortaya çıkabilir. Bu sorunu çözmek için, Solidity’de “create2” yöntemi kullanılarak önceden hesaplanmış sözleşme adresleri oluşturulabilir. Bu yöntem sayesinde, sözleşmelerin gelecekteki bir tarihte önceden belirlenmiş bir adrese oluşturulması mümkündür. Bu e-bültenimizde, Solidity’de “create2” yöntemi ile önceden hesaplanmış sözleşme adresleri oluşturmanın nasıl yapıldığına ve bu yöntemin avantajlarına ve dezavantajlarına değineceğiz.

Create2 Nedir?

Create2, Solidity’de bir sözleşme oluşturma yöntemidir ve sözleşmelerin önceden belirlenmiş bir adrese oluşturulmasına izin verir. Bu yöntem, sözleşmenin adresini oluşturmak için önceden belirlenmiş bir hesaplama kullanır. Create2 yöntemi, özellikle sözleşmelerin gelecekte oluşturulması gerektiği durumlarda oldukça faydalıdır.

Create2 yöntemi, “CREATE2” opcode’u ile çağrılır. Bu opcode, yeni bir sözleşme oluşturmak için bir adres hesaplar ve belirtilen bytecode’u kullanarak sözleşmeyi oluşturur. Create2, önceden belirlenmiş bir adrese yeni bir sözleşme oluşturmak için kullanılan bir yöntemdir. Bu yöntem, belirli bir nonce, belirli bir kontrat kodu ve belirli bir önceden belirlenmiş adres kullanarak sözleşmenin adresini önceden hesaplar.

Create2 Ne Zaman Kullanılır?

Create2, özellikle sözleşmelerin gelecekte belirli bir adrese oluşturulması gerektiği durumlarda kullanışlıdır. Örneğin, bazı uygulamalarda, bir sözleşme oluşturulmadan önce başka bir işlem gerçekleştirilmesi gerekebilir. Bu durumda, sözleşmenin oluşturulması, işlemin tamamlanmasını takiben belirli bir adrese yapılmalıdır. Create2, bu tür senaryolarda kullanılabilecek ideal bir yöntemdir.

Ayrıca, Create2, smart contract’ların depolama boyutunu azaltmak için de kullanılabilir. Örneğin, bir dApp’in birçok farklı kullanıcısı varsa ve her bir kullanıcı için ayrı bir sözleşme oluşturmak yerine, her bir kullanıcı için ayrı bir depolama alanı kullanarak aynı sözleşmeyi kullanmak isteyebilirsiniz. Bu durumda, Create2 yöntemi kullanarak aynı sözleşmenin her bir kullanıcının adresinde önceden hesaplanmış bir kopyasını oluşturabilirsiniz. Bu sayede, her bir kullanıcı için ayrı bir sözleşme oluşturmanıza gerek kalmaz ve depolama alanınızda önemli ölçüde tasarruf edebilirsiniz.

Create2 İle Önceden Hesaplanmış Sözleşme Adresleri

Create2 ile önceden hesaplanmış sözleşme adresleri oluşturmak için, sözleşmenin adresini hesaplamak için kullanılacak bir önceden belirlenmiş algoritma kullanmanız gerekir. Bu algoritma, sözleşmenin oluşturulacağı adresi önceden belirler ve sözleşme oluşturulduğunda bu adrese kaydeder.

Create2 yöntemi, sözleşmenin oluşturulacağı adrese “salt” adı verilen bir parametre ekleyerek kullanılır. Bu “salt” parametresi, sözleşmenin adresinin önceden hesaplanmasını değiştirerek, farklı “salt” parametreleri kullanarak farklı adresler oluşturulmasını sağlar.

Örneğin, aşağıdaki Solidity kodu, Create2 yöntemi ile önceden hesaplanmış bir sözleşme adresi oluşturur:

pragma solidity ^0.8.0;

contract PrecomputedContractAddress {
    function create2(bytes32 _salt, bytes memory _bytecode) public returns (address) {
        bytes32 _data = keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            _salt,
            keccak256(_bytecode)
        ));
        address _contractAddress;
        assembly {
            _contractAddress := create2(0, add(_bytecode, 0x20), mload(_bytecode), _data)
            if iszero(extcodesize(_contractAddress)) {
                revert(0, 0)
            }
        }
        return _contractAddress;
    }
}

Bu kod, Create2 yöntemi ile bir sözleşme oluştururken kullanılan tipik bir algoritmayı gösterir. _salt parametresi, sözleşmenin adresini önceden hesaplamak için kullanılan bir parametredir. _bytecode parametresi, sözleşmenin bytecode’unu içerir.

Create2 yöntemi, _salt parametresini değiştirerek farklı sözleşme adresleri oluşturabilirsiniz. Bu nedenle, _salt parametresinin güvenli bir şekilde seçilmesi önemlidir.

Create2 Yöntemiyle Sözleşme Oluşturma Adımları

Create2 yöntemiyle bir sözleşme oluşturmak için aşağıdaki adımları izleyebilirsiniz:

  1. _bytecode olarak bilinen sözleşmenin bytecode’unu hazırlayın.
  2. _salt olarak bilinen bir değer seçin. Bu, sözleşmenin adresinin hesaplanması için kullanılacak parametredir.
  3. _data olarak bilinen bir değer hesaplayın. Bu değer, _bytecode, _salt ve sözleşme oluşturma işlemi hakkındaki diğer bilgilerin birleştirilmesiyle hesaplanır. _data değeri, sözleşmenin oluşturulacağı adresi hesaplamak için kullanılır.
  4. _contractAddress olarak bilinen bir değişken tanımlayın ve _bytecode ve _data değerlerini kullanarak sözleşmeyi oluşturun.
  5. _contractAddress değişkeni, oluşturulan sözleşmenin adresini içerecektir.

Aşağıdaki örnek Solidity kodu, Create2 yöntemi ile sözleşme oluşturma adımlarını gösterir:

pragma solidity ^0.8.0;

contract MyContract {
    function create2(bytes32 _salt, bytes memory _bytecode) public returns (address) {
        bytes32 _data = keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            _salt,
            keccak256(_bytecode)
        ));
        address _contractAddress;
        assembly {
            _contractAddress := create2(0, add(_bytecode, 0x20), mload(_bytecode), _data)
            if iszero(extcodesize(_contractAddress)) {
                revert(0, 0)
            }
        }
        return _contractAddress;
    }
}

Bu örnek kodda, _salt ve _bytecode parametreleri create2 fonksiyonuna aktarılır ve _data değeri hesaplanır. _contractAddress değişkeni, oluşturulan sözleşmenin adresini içerecektir.

Create2’nin Avantajları ve Dezavantajları

Create2 yöntemi, bir sözleşmenin adresinin önceden hesaplanabilmesi nedeniyle bazı avantajlar ve dezavantajlar sunar. Bunlar şunlardır:

Avantajları:

  • Daha hızlı işlem yapabilme: Create2 ile, bir sözleşmenin adresi önceden hesaplanabilir ve işlemler daha hızlı bir şekilde gerçekleştirilebilir. Bu, Ethereum ağının yoğunluğu arttığında bile işlemlerin hızlı bir şekilde gerçekleştirilebileceği anlamına gelir.
  • Daha az gas kullanımı: Create2 ile, bir sözleşme önceden hesaplanabildiğinden, daha az gas kullanılabilir. Bu, daha ucuz işlemler anlamına gelir.
  • Daha esnek adresleme: Create2 yöntemi, adresleme yöntemi olarak sha3 kullanır ve bu, önceden belirlenmiş örüntüleri takip etmek zorunda olmamak anlamına gelir. Bu, daha esnek bir sözleşme adresleme imkanı sağlar.

Dezavantajları:

  • Güvenlik riski: Create2 yöntemi, bir saldırganın önceden hesaplanmış bir adresle işlem yapmasını mümkün kılarak güvenlik riski oluşturabilir. Saldırgan, önceden hesaplanmış bir adrese erişebilirse, önceden belirlenmiş özelliklere sahip bir sözleşme oluşturarak gas ücretlerini manipüle edebilir.
  • Kod karmaşıklığı: Create2 yöntemi, kod karmaşıklığını artırır. Create2 yöntemiyle bir sözleşme oluşturmak, ek kodlama gerektirir ve bu, sözleşmenin bakımını zorlaştırabilir.

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

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

contract Factory {
    // Returns the address of the newly deployed contract
    function deploy(
        address _owner,
        uint _foo,
        bytes32 _salt
    ) public payable returns (address) {
        // This syntax is a newer way to invoke create2 without assembly, you just need to pass salt
        // https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2
        return address(new TestContract{salt: _salt}(_owner, _foo));
    }
}

// This is the older way of doing it using assembly
contract FactoryAssembly {
    event Deployed(address addr, uint salt);

    // 1. Get bytecode of contract to be deployed
    // NOTE: _owner and _foo are arguments of the TestContract's constructor
    function getBytecode(address _owner, uint _foo) public pure returns (bytes memory) {
        bytes memory bytecode = type(TestContract).creationCode;

        return abi.encodePacked(bytecode, abi.encode(_owner, _foo));
    }

    // 2. Compute the address of the contract to be deployed
    // NOTE: _salt is a random number used to create an address
    function getAddress(
        bytes memory bytecode,
        uint _salt
    ) public view returns (address) {
        bytes32 hash = keccak256(
            abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode))
        );

        // NOTE: cast last 20 bytes of hash to address
        return address(uint160(uint(hash)));
    }

    // 3. Deploy the contract
    // NOTE:
    // Check the event log Deployed which contains the address of the deployed TestContract.
    // The address in the log should equal the address computed from above.
    function deploy(bytes memory bytecode, uint _salt) public payable {
        address addr;

        /*
        NOTE: How to call create2

        create2(v, p, n, s)
        create new contract with code at memory p to p + n
        and send v wei
        and return the new address
        where new address = first 20 bytes of keccak256(0xff + address(this) + s + keccak256(mem[p…(p+n)))
              s = big-endian 256-bit value
        */
        assembly {
            addr := create2(
                callvalue(), // wei sent with current call
                // Actual code starts after skipping the first 32 bytes
                add(bytecode, 0x20),
                mload(bytecode), // Load the size of code contained in the first 32 bytes
                _salt // Salt from function arguments
            )

            if iszero(extcodesize(addr)) {
                revert(0, 0)
            }
        }

        emit Deployed(addr, _salt);
    }
}

contract TestContract {
    address public owner;
    uint public foo;

    constructor(address _owner, uint _foo) payable {
        owner = _owner;
        foo = _foo;
    }

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

Bu akıllı sözleşme, Create2 kullanarak bir kontratın oluşturulmasına örnek olarak yazılmıştır. Kod, Factory adlı bir kontratla başlıyor ve bu kontrat, deploy() adlı bir fonksiyon içeriyor. Bu fonksiyon, bir TestContract kontratı oluşturur ve bu kontratın adresini döndürür.

FactoryAssembly adlı bir başka kontrat, aynı işlevi yerine getirir, ancak bu kez, kontratın oluşturulması için daha eski bir yöntemi kullanır, yani Create2‘nin birlikte kullanıldığı assembly bloğunu kullanır.

TestContract kontratı, basit bir kontrattır. Konstruktöründe owner ve foo adlı iki değişken alır ve fonksiyon, bu değişkenleri saklar ve getBalance() adlı bir fonksiyonu içerir, bu fonksiyon kontratın bakiyesini döndürür.

Özetle, bu akıllı sözleşme, Create2 yöntemini kullanarak bir kontrat oluşturma işleminin nasıl gerçekleştirilebileceğini göstermektedir. Factory ve FactoryAssembly adlı kontratlar, kontratların oluşturulmasında farklı yöntemleri kullanırken, TestContract adlı kontrat, basit bir kontrat örneği olarak kullanılmaktadır.

Güncellemeler ve Gelecek Geliştirmeler

Create2 yöntemi, Ethereum topluluğunda oldukça yeni bir teknoloji olmasına rağmen, hızla yayılıyor ve özellikle DeFi ve NFT projeleri için çok faydalı olabiliyor. Ethereum’un gelecekteki geliştirmelerinde de bu yöntemin kullanımının artacağına kesin gözüyle bakılıyor.

Örneğin, Ethereum’un iki büyük ölçeklenebilirlik çözümü olan Polygon ve Optimism, Create2 yöntemini kullanan uygulamaları destekleyerek, bu yöntemin daha da popülerleşmesine katkıda bulunuyorlar.

Ayrıca, Ethereum 2.0’nin hedeflerinden biri, sözleşmelerin daha verimli bir şekilde yürütülmesine olanak tanıyacak olan eWASM motorunu kullanmaktır. Bu da, Create2 yönteminin daha hızlı ve daha verimli hale gelmesine yol açabilir.

Sonuç olarak, Create2 yöntemi, Ethereum’un geliştirme ekosistemi için önemli bir yenilik olarak kabul ediliyor ve gelecekte daha da yaygınlaşması bekleniyor.

SONUÇ BAĞLAMI

Bu e-bültende, Solidity programlama dilinde kullanılan Create2 yöntemine odaklandık. Bu yöntem, önceden hesaplanmış sözleşme adresleri oluşturma işlemini mümkün kılarak, belirli senaryolarda daha verimli bir şekilde sözleşme oluşturma işlemini gerçekleştirir. Ayrıca, Create2 yöntemiyle ilgili örnek bir akıllı sözleşmeyi inceledik ve yöntemin avantajları ve dezavantajları hakkında bilgi sahibi olduk.

Solidity, Ethereum ve diğer blockchain teknolojilerinin gelişmesiyle birlikte, Create2 yöntemi de geliştirilmeye devam ediyor. Gelecekte, bu yöntem daha da geliştirilerek, daha fazla senaryoda kullanılabilir hale gelebilir.

Sonuç olarak, Create2 yöntemi Solidity geliştiricilerinin işlerini kolaylaştıran ve daha verimli hale getiren bir araçtır. Bu nedenle, Solidity programlama dili hakkında bilgi sahibi olan herkesin Create2 yöntemini öğrenmesi ve kullanması ö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