Solidity 2 — İlk Akıllı Kontrat ve Remix IDE

Engin UNAL
6 min readSep 19, 2022

Solidity kodlamaya ilk adımlar…

Önceki yazımda Ethereum, Smart Contract ve Solidity dünyasına girişte bilinmesi gereken temel kavramları özetlemiştim. Yazıya erişim için link. Solidity dili ile kodlama için bu yazıda Remix IDE kullanacağız. Kullanımı kolay ve pratik olan bu IDE için https://remix.ethereum.org/ adresine giderek doğrudan açılan ekranda akıllı kontrat geliştirmeye başlayabilirsiniz.

Neden ilk olarak Remix ile başladık? Dediğim gibi kullanımı çok kolay ve pratik, bir çok gerekli özellik bir tıklama uzaklıkta ve ön tanımlı geliyor. Tanımlar ve paket yüklemeler gibi işlerle vakit harcamaya gerek kalmıyor ve hem editör hem de geliştirme, test ve yayınlama ortamını sunması avantajı var.

Sonraki yazılarda daha detaylı değinme imkanım olabilir mesela Visual Studio Code gidi editör kullanıp Hardhat, Truffle veya diğer geliştirme ortamlarını da kullanabiliriz. Ama önceliğimiz Solidity Smart Contract geliştirme konusunu anlamak olduğundan Remix ile devam edelim.

Aşağıdaki gibi gelecek ilk ekranda contracts, scripts, tests klasörleri mevcut.

  • contracts : Yazacağımız kontrat dosyalarını buraya koyacağız. Standart olarak bu klasörde üç adet örnek kontrat dosyası mevcut.
  • scripts : Akıllı kontrat yayınlamak için kullanılır. Şimdilik kullanmayacağız.
  • tests : Test dosyalarını burada tutacağız. Bunu da test yazana kadar kullanmayacağız.

Akıllı kontrat yazarak başlayalım. Bunun üzerinden açıklamalarla devam edeceğiz. Örnek kontrat kaydedilmesi istenen bir sayıyı kaydedecek ve sorgulandığında da geri dönecek. Kontrat dosyamızın adı “01-Start.sol” olacak bunu da contracts klasörüne kaydedeceğiz.

Yukarıda verilen kod örneğini satır satır inceleyelim.

  • // SPDX-License-Identifier: MIT : Her solidity kaynak kod dosyası lisans belirteci olarak SPDX lisans tanımlama satırını içermelidir. Kod dosyamızdaki birinci satırdaki SPDX tanımı ile bu dosyanın MIT lisansı altında korunduğu bilgisi verilmiştir. SPDX, Software Package Data Exchange kelimelerinin kısaltılmışıdır. Uluslararası açık bir standardı temsil eder. Detay için linki inceleyebilirsiniz.
  • pragma solidity ^0.8.0 : Pragma tanımları, compiler tarafına gönderilecek bazı özelliklerin veya yapılması istenen kontrollerin tanımlandığı yapılardır. Burada versiyon tanımı yapılan pragma kullanılmıştır. Yapılmak istenen, versiyon aralığına uygun olmayan bir compiler’ın kullanılmasının engellenmesidir. Koddaki örnekte 0.8.0 öncesi compiler versiyonları ve 0.9.0 ve sonrası compiler versiyonlarının derleme yapmaması istenmiştir. pragma solidity 0.8.0; verseydik sadece 0.8.0 versiyonlu compiler derleme yapabilecekti. Veya pragma solidity >=0.8.0 <0.9.0; verseydik 0.8.0 dahil 0.9.0'a kadar olan compiler versiyonları derleme yapabilecekti. Bunun gibi compiler versiyonu seçimi bu satırda yapılır.
  • contract : Akıllı kontrat kodlarının ve verisinin tanımlandığı yapıyı ifade eder. Geliştireceğimiz kontrat içinde kullanacağımız fonksiyonları bu yapı içine yazarız. Aynı şekilde kontrat tarafından kullanılan ve sunulan verinin(state) tutulacağı yapıdır. Object Oriented dillerdeki class tanımlarına benzer.
  • State ve Fonksiyonlar : Örnek kodlamadaki storedNumber bir durum değişkeni(state variable) olarak adlandırılır. Temel görevi veriyi saklamaktır. Bu veri Start ismini verdiğim kontrat içerisinde ve Ethereum blockchain üzerinde kayıtlıdır. setNumber ve getNumber isimli fonksiyonların görevi storedNumber değişkeninin değerini değiştirmek ve değerini okumaktır. Fonksiyonlar, kontrat içindeki çalıştırılabilir kod bölümleridir. State değişkeni değiştirme veya okuma, hesaplama işlemleri vb. tüm çalışma zamanı işlemleri fonksiyonlar aracılığı ile yapılır. Detayına yazının devamında değineceğim.

Yukarıda örneğini verdiğim akıllı kontrat ile ilgili kısa açıklamaların devamında kodumuzu remix uygulamasına ekleyelim ve çalıştıralım.

01-Start.sol akıllı kontrat dosyasını oluşturup mevcut kodları buna kopyaladık.

Solidity Compiler sayfasından derleme işlemini yapalım.

01-Start.sol için Compile işlemi.

Deploy & Run Transactions sayfasından lokaldeki Ethereum VM simulatörü olarak kullancağımız Remix VM(London) ortamına Deploy işlemini gerçekleştirelim.

Öğrenme sürecinde güvenlik tanımları, gas ücreti ödeme vb. işlerle uğraşmamak için lokalde EVM simulatörüne kontrat yayınlamayı tercih edeceğim. Remix bu konuda işleri oldukça kolaylaştırıyor. Sonraki konularda imkan olursa test ortamlarına da canlı sisteme yayın yapar gibi yayınlama nasıl yapılıyor konusuna da girebiliriz.

Deploy ekranından seçili kontrat için Deploy ile yayınlamayı gerçekleştiriyoruz.

EVM simulatörüne yayınlama işlemi.

Bu işlemin sonrasındaki aşağıdaki ekrandaki gibi yayınlanmış kontrat bilgilerine ulaşabilir ve bu kontrat ile etkileşime geçebiliriz.

Yayınlanan akıllı kontrat.

Örneğimizde 0xd9145CCE52D386f254917e481eB44e9943F39138 adresine yayınladığımız kontrat ile etkileşime girip setNumber metodunu 15 değerini göndererek çağıralım.

Akıllı kontrat etkileşimi. setNumber(15)

Sağ taraftaki ekrandan incelenebileceği gibi setNumber(15) işlemi başarıyla çalıştı ve test için kullandığımız hesaptan gas ücreti kesilerek öncesinde 100 ether olan hesap bakiyemiz 99.999999999999830621 ether olarak değişti. Yukarıda belirttiğim gibi yapılan işlemlere ücret ödememek için geliştirme işlemlerinde simulatör veya test sistemlerini kullanacağız. setNumber (15) işleminde storedNumber değişkenimizi 15 olarak değiştirdik, kontrol için getNumber metodunu çağıralım, beklentimiz 15 değerini dönmesi.

getNumber metodu storedNumber değişkeninin değerini döner. Dönen değer 15 yani kaydetme işlemi başarılı olmuş ve state değişmiş. Format olarak 0: dönüş değerinin indeksini verir, uint256: kullanılan veri tipi, 15: dönen değer.

Not: Remix IDE Deploy ekranında kontrat ile etkileşim kurulan metodlar listelenirken pure veya view gibi state değiştirmeyen işlemleri yapan metodların etkileşim düğmeleri mavi, state değiştiren metodlar için turuncu, ödeme yapılan metodlar için ise kırmızı renktedir.

getNumber metodu çağrımı yapmıştık şimdi detayını inceleyelim.

getNumber metodu etkileşim çıktısı.

Görüldüğü üzere test hesabı olarak kullandığım ve içinde başlangıçta 100 ether olan 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 adresli hesap, 0xd9145CCE52D386f254917e481eB44e9943F39138 adresli Start isimli kontratı çağırmış ve dönüş olarak uint 15 değeri gelmiş. Hesap bakiyesi değişmemiş bunun nedeni ise state değişikliği yapılmadığı sürece ve okuma amaçlı çağrımlarda gas ödenmemesidir.

Son olarak Start isimli kontrat bilgilerimizi inceleyelim. Solidity Compiler sayfasında “Compilation Details” düğmesiyle kontrat derleme detaylarına erişebiliriz.

Derlendiğinde elde edilen bytecode ve opcode verilerini içeren yapı:

{  
"functionDebugData": {},
"generatedSources": [],
"linkReferences": {},
"object": "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80633fb5c1cb1461003b578063f2c9ecd814610057575b600080fd5b6100556004803603810190610050919061009d565b610075565b005b61005f61007f565b60405161006c91906100d9565b60405180910390f35b8060008190555050565b60008054905090565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220e2f17b816524778d234ced8373229fd950e7891d35f84dd3339b12285c6a40af64736f6c63430008070033", "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x150 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x3FB5C1CB EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0xF2C9ECD8 EQ PUSH2 0x57 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x55 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x50 SWAP2 SWAP1 PUSH2 0x9D JUMP JUMPDEST PUSH2 0x75 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x5F PUSH2 0x7F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x6C SWAP2 SWAP1 PUSH2 0xD9 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST DUP1 PUSH1 0x0 DUP2 SWAP1 SSTORE POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x97 DUP2 PUSH2 0x103 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB3 JUMPI PUSH2 0xB2 PUSH2 0xFE JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0xC1 DUP5 DUP3 DUP6 ADD PUSH2 0x88 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0xD3 DUP2 PUSH2 0xF4 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0xEE PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0xCA JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x10C DUP2 PUSH2 0xF4 JUMP JUMPDEST DUP2 EQ PUSH2 0x117 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xE2 CALL PUSH28 0x816524778D234CED8373229FD950E7891D35F84DD3339B12285C6A40 0xAF PUSH5 0x736F6C6343 STOP ADDMOD SMOD STOP CALLER ",
"sourceMap": "62:240:0:-:0;;;;;;;;;;;;;;;;;;;" }

Bu yapı içindeki object alanı önceki yazıda belirttiğim hex bytecode verisini içerir. opcodes alanında ise bunun açık opcode verisi bulunur.

Akıllı kontrat ile iletişimde kullanılacak ABI verisi:

[
{
"inputs": [],
"name": "getNumber",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newNumber",
"type": "uint256"
}
],
"name": "setNumber",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

Bu yazıda Remix IDE ile akıllı kontrat yazımı konusunda temel bilgiler vermeye çalıştım, görüldüğü üzere Remix ile kontrat yazıp bunu çalıştırmak oldukça kolay. Devam eden yazılarda Solidity dili ve nasıl kodlanacağı ile ilgili detay vererek devam edeceğim.

Serinin diğer yazılarının linkleri:

Solidity 1 — Temel Bilgiler

Engin Ünal

--

--