Solidity 10 — ERC-20 Token Standardı Nedir? ERC-20 Token Nasıl Yapılır?

Engin UNAL
5 min readNov 29, 2022

ERC-20 Token standardı anlatımı ve devamında kod örneğiyle kendi token’ımızı kodlayacağımız bir yazıyla devam ediyoruz.

Blockchain projeleri sürekli gelişmekte ve değişkmekte olan, standartları ihtiyaca göre güncellenen ve yeniliklere açık projelerdir. Merkezi olmayan projelerde yeniliklerin hayata geçirilmesi geliştiricilerin, validatörlerin veya kullanıcıların önerileri üzerinden ilerlemektedir.

Ethereum ekosisteminde yeniliklerin veya değişiklik isteklerinin önerilmesi süreci EIP’ler ile sağlanır. EIP, Ethereum Improvement Proposals ( ~ Ethereum İyileştirme Önerileri ) kelimelerinin kısaltılmışıdır. Örneğin platform temel mimarisi, api, kontrat, network veya diğer konularda EIP hazırlanarak öneri sunulabilir. Devamında öneriler tartışılır ve kabul görürse finalde standartlaşır. eips.ethereum.org adresinden EIP hazırlama kuralları, standartlaşmış EIP’ler ve halihazırdaki öneriler incelenebilir.

Bu kısa özetten sonra konumuz olan EIP-20 veya ERC-20 token standardına geçelim. ERC ise uygulama ve kontrat konularıyla ilgili EIP kategorisi için kullanılan alt başlıktır. ERC-20 dediğimizde EIP-20 önerisinin kontrat, token, URI, library vb. standartlarla ilgili olduğu anlaşılır.

EIP-20, Fabian Vogelsteller ve Vitalik Buterin’in 2015 yılında ERC kategorisinde önerdikleri bir token arayüz standardıdır. Bu standart ile ilgili detaya https://eips.ethereum.org/EIPS/eip-20 adresinden ulaşılabilir. ERC-20 token standardı, akıllı kontratlar kullanarak token oluşturma ve transfer işlemlerinin yönetilebilmesi için ortak bir arabirim/interface kuralları koyar. Böylece blockchain dışından da erişilebilen(örneğin cüzdan) özelleştirilmiş ve harcanabilir varlık oluşturma yolu açılmıştır. Devamında ekosistemde token patlaması yaşanmış, harcanabilir varlıklar konusunda ilerlemeler ve tartışmalar sonrasında alınan yol ile harcanamaz varlık yani NFT’ye giden sürece önemli katkıları olmuştur. İleriki yazılarda imkan olursa buna da değineceğim.

Şimdi ERC-20 token hangi standartları şart koşar? Bunları nasıl sağlayabiliriz? Ve kendimize minimun gereksinimleri sağlayan token yapmak istesek nasıl yapabiliriz? Sorularına sırayla cevaplarla devam edelim.

ERC-20 Token Standardı

ERC-20 token standardını incelediğimizde geliştirmek istediğimiz akıllı kontrat içerisinde en az aşağıdaki fonksiyon ve tanımların olması gerektiği görülmektedir. Eğer kodlayacağımız kontrat içerisinde aşağıdaki gereksinimler tam olarak sağlanamaz ise veya isimler aynı değilse token’ımız ERC-20 standardına uymayacaktır.

//fonksiyonlar
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)

//eventler
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)

Yukarıdaki tanımlar kontratınız içerisinde mutlaka olmalıdır. Dikkat çekmek istediğim name ve symbol tanımlarının zorunlu olmaması. EVM tarafında veya validatörlerde bunun önemi yoktur. Aynı isme sahip token’lar oluşturmak mümkündür. Örneğin ABC isimli bir token olsun aynı isimde bir token daha yapılabilir. Güvenli olmayan bir alım satım işleminde orjinal ABC yerine sahtesine ödeme yapma mümkün olabilir. Bu nedenle name ve symbol değil kontrat adresi kontrol edilir. Yukarıdaki fonksiyon tanımları standart içerisindeki mutlaka olması gereken tanımlardır. Aşağıda ise standartta tanımlı fakat opsiyonel olarak eklenebilen fonksiyonlar verilmiştir.

function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)

ERC-20 içerisindeki fonksiyonların açıklamaları:

  • name() : Token’a verilen ismi döndürür. Örnek: Istanbul Token.
  • symbol() : Verilen kısa ismi döndürür. Örnek: IST.
  • decimals() : Ondalık hane sayısını döndürür. Ethereum’da minimum birim Wei’dir. 1 eth = 10¹⁸ wei’dir. Ondalık işlemler için özel bir tip bulunmaz. İşlemler wei’e çevrilerek yapılır. Örneğin 2.5 eth = 2.5 * 10¹⁸ olacaktır. ERC-20 token için de ondalıklı yapı kullanılmak isteniyorsa decimals tanımı yapılarak bu sağlanabilir. Genellikle 10¹⁸ kullanılır veya isteğe göre değiştirilebilir.
  • totalSupply() : Toplamdaki token arzıdır.
  • balanceOf(address _owner) : _owner ile belirtilen hesaptaki bakiye bilgisini dönmektedir.
  • transfer(address _to, uint256 _value) : Çağıran hesaptan belirtilen _to adresine _value kadar token’ı gönderen fonksiyondur. Bu işlem sonucunda Transfer event’i fırlatılmalıdır. Hesapta yeterki kadar token yoksa hata fırlatmalıdır.
  • transferFrom(address _from, address _to, uint256 _value) : _from adresinden _to adresine _value kadar token’ı transfer eder. transfer fonksiyonundaki mekanizmaya benzerdir.
  • approve(address _spender, uint256 _value) : Belirtilen _spender adresine sahip hesabın toplamda _value değeri kadar çekme işlemi(withdraw) yapabilmesini tanımlamak için kullanılır.
  • allowance(address _owner, address _spender) : _owner tarafından _spender adresine verilmiş çekme işlemi izni kalan miktarını döner.

Genel mekanizmayı gördüğümüze göre artık kodlama ve uygulamaya geçebiliriz. Öncelikle temel özelliklerde bir token yapalım.

Kendi Token’ımızı Yapalım

Geliştireceğimiz token sembolü ve adı GIST:Guzel Istanbul Token olsun. Token kontrat kodu aşağıdaki gibi olabilir.

Yukarıdaki kontratı yayınladığınızda artık ERC-20 standardına sahip bir token olan GIST token’ı test ortamında olsa da yayınladınız.

Artık bu token kontratı ile on-chain veya off-chain iletişime geçip bakiye kontrolü, ödünç verme ve transfer gibi işlemleri gerçekleştirebilirsiniz.

Görüldüğü üzere karmaşık işlemler içeren bir yapı değil. Karmaşık gelebilecek tek fonksiyon transferFrom ve onun işleyişi olabilir. Aşağıda onunla ilgili yeterli açıklamayı vermeye çalıştım.

Bir hesaptan(_from) başka bir hesaba(_to) istenilen miktarda(_value) token transferi yapmak için transferFrom kullanılır. Token’ı gönderen hesap token’a sahip olmak zorunda değildir. Peki birinin token’ını nasıl başka birine transfer edebiliyoruz? Bunun için allowance mekanizması kullanılır. Token sahibi, approve fonksiyonu yardımıyla istediği hesaba kendi token’ından kullanma yetkisi verebilir. approve fonksiyonu iki parametre alır. Birincisi yetki verilecek hesap bilgisi diğeri ise ne kadar token için yetki verileceği. Bu yetkilendirme sonrası yetkiyi alan hesap artık kendisinin olmayan token’lardan kendisine izin verilen kadarını başka hesaplara transfer edebilir.

İşte bu transfer işlemi için de transferFrom fonksiyonu kullanılır. Neden böyle birşey var? Aslında bu yetenek sayesinde Defi ve staking konularında oldukça hızlı gelişmeler yaşandı. Şöyle düşünebiliriz. Hesabınızdaki token’ları transfer etmeden bir Defi uygulaması hesabına veya staking hesabına approve ile yetki verebilir bu sayede token’larınız yerinde kalırken gelir elde edebileceğiniz modeller kullanabilirsiniz.

ERC-20 token geliştirmek için her defasında sıfırdan kodlama yapmak yerine hazır şablonları da kullanabilirsiniz. Bunun için seçenekler çeşitli fakat ben en çok tercih edileni OpenZeppelin ile devam edeceğim. Şimdi ERC-20 token geliştirmenin daha kolay yöntemi olan OpenZeppelin hazır kontratlarıyla devam edelim.

OpenZeppelin İle ERC-20 Token Üretimi

OpenZeppelin, kripto siber güvenlik ve hizmetleri konusunda uzmanlaşmış bir şirket olmakla beraber güvenli akıllı kontratlar ve ortak kullanılan kontratların hazır hallerini alıp kullanabileceğimiz kütüphaneleri ve kod örnekleri bulunmaktadır. Token kontrat geliştiriciler için de örnek ERC-20 kod örnekleri bulunmaktadır. https://www.openzeppelin.com/contracts adresinden ERC20 başlığı altındaki wizard yardımı ile manuel olarak yazdığımız token olan GIST için openzeppelin kütüphanesini kullanalım.

Remix ide ile açıp derleyelim ve devamında yayınlayalım.

Openzeppelin tarafından hazırlanmış ve test edilmiş ERC20 kontratından miras alarak kendi token kontratlarımızı çok kolay türetebildik.

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

import "@openzeppelin/contracts@4.8.0/token/ERC20/ERC20.sol";

contract GuzelIstanbulToken is ERC20 {
constructor() ERC20("Guzel Istanbul Token", "GIST") {
_mint(msg.sender, 100 * 10 ** decimals());
}
}

Buna ek olarak arz miktarını değiştirebileceğimiz mint ve burn özelliklerini de kolayca ekleyebiliriz. Aynı şekilde sık kullanılan fonksiyonlar için de hazırlanmış kütüphaneler bulunmaktadır.

Openzeppelin sitesindeki dokümanlar kısmını incelemenizi ve ERC-20 veya diğer kontrat örneklerini de uygulamanızı önerebilirim.

Teşekkürler.

Serideki diğer yazılar:

Temel Bilgiler

İlk Akıllı Kontrat ve Remix

Tipler

Contract ve Function

Interface ve Library

Veri Yönetimi

Logs ve Events

Ödeme İşlemleri

Akıllı Kontrat Çağrıları

Engin Ünal

--

--