ERC-223 Jeton Standardı
Son düzenleme: @Utkubahar(opens in a new tab), 11 Haziran 2024
Giriş
ERC-223 nedir?
ERC-223, ERC-20 standardına benzer şekilde, değiştirilebilir jetonlara yönelik bir standarttır. Temel fark, ERC-223'ün yalnızca jeton API'sini değil aynı zamanda jetonları göndericiden alıcıya transfer etme mantığını da tanımlamasıdır. Jeton transferlerinin alıcının tarafında işlenmesini sağlayan bir iletişim modeline sahiptir.
ERC-20'den farkları
ERC-223, ERC-20'nin bazı sınırlamalarını ele alır ve jeton sözleşmesi ile jetonları alabilecek sözleşme arasında yeni bir etkileşim yöntemi sunar. ERC-223 ile mümkün olup ERC-20 ile mümkün olmayan birkaç şey şunlardır:
- Alıcı tarafında jeton transferi işlemlerinin yönetimi: Alıcılar, ERC-223 jetonlarının yatırıldığını tespit edebilirler.
- Yanlış gönderilmiş jetonların reddedilmesi: Bir kullanıcının ERC-223 jetonlarını jeton alması beklenmeyen bir sözleşmeye göndermesi halinde sözleşme, işlemi reddedebilir ve bu da jeton kaybını önler.
- Transferlerde meta veri: ERC-223 jetonları, jeton işlemlerine rastgele bilgi eklenmesini sağlayan meta veriler içerebilir.
Ön Koşullar
Gövde
ERC-223, akıllı sözleşmeler içindeki jetonlar için bir API uygulayan bir jeton standardıdır. Ayrıca, ERC-223 jetonlarını alması gereken sözleşmeler için bir API belirtir. ERC-223 Alıcı API'sini desteklemeyen sözleşmeler ERC-223 jetonlarlarını alamaz ve bu da kullanıcı hatalarını önler.
Aşağıdaki yöntem ve olayları uyguluyan bir akıllı sözleşme, ERC-223 uyumlu bir jeton sözleşmesi olarak adlandırılabilir. Dağıtıldıktan sonra, Ethereum üzerinde oluşturulan jetonları takip etmekten sorumlu olacaktır.
Sözleşmenin yalnızca bu işlevlere sahip olması gerekmez ve bir geliştirici, bu sözleşmeye farklı jeton standartlarına ait herhangi bir özelliği ekleyebilir. Örneğin, approve
ve transferFrom
fonksiyonları ERC-223 standardının bir parçası olmasa da, gerekli durumlarda bu fonksiyonlar uygulanabilir.
EIP-223'den(opens in a new tab):
Yöntemler
ERC-223 jetonu şu yöntemleri uygulamalıdır:
1function name() public view returns (string)2function symbol() public view returns (string)3function decimals() public view returns (uint8)4function totalSupply() public view returns (uint256)5function balanceOf(address _owner) public view returns (uint256 balance)6function transfer(address _to, uint256 _value) public returns (bool success)7function transfer(address _to, uint256 _value, bytes calldata _data) public returns (bool success)Kopyala
ERC-223 jetonlarını alması gereken bir sözleşme, şu yöntemi uygulamalıdır:
1function tokenReceived(address _from, uint _value, bytes calldata _data)Kopyala
ERC-223 jetonlarının tokenReceived(..)
fonksiyonunu uygulamayan bir sözleşmeye gönderilmesi halinde transfer başarısız olmalı ve jetonlar gönderenin bakiyesinden çıkarılmamalıdır.
Olaylar
1event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data)Kopyala
Örnekler
ERC-223 jetonu API'si ERC-20'ye benzer olduğundan, kullanıcı arayüzü geliştirme açısından herhangi bir fark yoktur. Burada tek istisna, ERC-223 jetonlarının bu standart için opsiyonel olan approve
+ transferFrom
fonksiyonlarına sahip olamamasıdır.
Solidity örnekleri
Aşağıdaki örnek, temel bir ERC-223 jeton sözleşmesinin nasıl çalıştığını gösterir:
1pragma solidity ^0.8.19;2abstract contract IERC223Recipient {3 function tokenReceived(address _from, uint _value, bytes memory _data) public virtual;4}5contract VeryBasicERC223Token {6 event Transfer(address indexed from, address indexed to, uint value, bytes data);7 string private _name;8 string private _symbol;9 uint8 private _decimals;10 uint256 private _totalSupply;11 mapping(address => uint256) private balances;12 function name() public view returns (string memory) { return _name; }13 function symbol() public view returns (string memory) {return _symbol; }14 function decimals() public view returns (uint8) { return _decimals; }15 function totalSupply() public view returns (uint256) { return _totalSupply; }16 function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; }17 function isContract(address account) internal view returns (bool) {18 uint256 size;19 assembly { size := extcodesize(account) }20 return size > 0;21 }22 function transfer(address _to, uint _value, bytes calldata _data) public returns (bool success){23 balances[msg.sender] = balances[msg.sender] - _value;24 balances[_to] = balances[_to] + _value;25 if(isContract(_to)) {26 IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data);27 }28 emit Transfer(msg.sender, _to, _value, _data);29 return true;30 }31 function transfer(address _to, uint _value) public returns (bool success){32 bytes memory _empty = hex"00000000";33 balances[msg.sender] = balances[msg.sender] - _value;34 balances[_to] = balances[_to] + _value;35 if(isContract(_to)) {36 IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty);37 }38 emit Transfer(msg.sender, _to, _value, _empty);39 return true;40 }41}Tümünü gösterKopyala
Şimdi tokenA jetonunun bir ERC-223 jetonu olduğunu varsayarak tokenA
depozitolarını kabul eden başka bir sözleşme istiyoruz. Sözleşme yalnızca tokenA'yı kabul etmeli ve diğer jetonları reddetmelidir. Sözleşme tokenA'yı aldığında, bir Deposit()
olayı yaymalı ve dahili 'deposits' değişkeninin değerini artırmalıdır.
İşte kod:
1contract RecipientContract is IERC223Recipient {2 event Deposit(address whoSentTheTokens);3 uint256 deposits = 0;4 address tokenA; // The only token that we want to accept.5 function tokenReceived(address _from, uint _value, bytes memory _data) public override6 {7 // It is important to understand that within this function8 // msg.sender is the address of a token that is being received,9 // msg.value is always 0 as the token contract does not own or send Ether in most cases,10 // _from is the sender of the token transfer,11 // _value is the amount of tokens that was deposited.12 require(msg.sender == tokenA);13 deposits += _value;14 emit Deposit(_from);15 }16}Tümünü gösterKopyala
Sıkça sorulan sorular
Eğer sözleşmeye bir miktar tokenB gönderirsek ne olur?
İşlem başarısız olur ve ve jeton transferi gerçekleşmez. Jetonlar göndericinin adresine iade edilir.
Bu sözleşmeye nasıl para yatırabiliriz?
RecipientContract
adresini belirterek ERC-223 jetonun transfer(address,uint256)
veya transfer(address,uint256,bytes)
fonksiyonunu çağırın.
Bir ERC-20 jetonunu bu sözleşmeye transfer edersek ne olur?
RecipientContract
adresine bir ERC-20 jetonu gönderilirse, jetonlar transfer edilir ancak transfer tanınmaz (hiçbir Deposit()
olayı tetiklenmez ve depozito değeri değişmez). İstenmeyen ERC-20 depozitoları filtrelenemez veya engellenemez.
Jeton yatırımı tamamlandıktan sonra bazı fonksiyonları yürütmek istersek ne yapmalıyız?
Bunu yapmanın birkaç yolu vardır. Bu örnekte, ERC-223 transferlerini Ether transferlerine özdeş hale getiren yöntemi takip edeceğiz:
1contract RecipientContract is IERC223Recipient {2 event Foo();3 event Bar(uint256 someNumber);4 address tokenA; // The only token that we want to accept.5 function tokenReceived(address _from, uint _value, bytes memory _data) public override6 {7 require(msg.sender == tokenA);8 address(this).call(_data); // Handle incoming transaction and perform a subsequent function call.9 }10 function foo() public11 {12 emit Foo();13 }14 function bar(uint256 _someNumber) public15 {16 emit Bar(_someNumber);17 }18}Tümünü gösterKopyala
RecipientContract
bir ERC-223 jetonu aldığında sözleşme, tıpkı Ether işlemlerinin fonksiyon çağrılarını işlem data
olarak kodlaması gibi jeton işleminin _data
parametresi olarak kodlanan bir fonksiyonu yürütür. Daha fazla bilgi için veri alanını(opens in a new tab) okuyun.
Yukarıdaki örnekte, bir ERC-223 jetonunun transfer(address,uin256,bytes calldata _data)
fonksiyonu ile RecipientContract
adresine transferi gerekmektedir. Eğer veri parametresi 0xc2985578
(foo()
fonksiyonunun imzası) ise, jeton depozitosu alındıktan sonra foo() fonksiyonu çağrılır ve Foo() olayı tetiklenir.
Parametreler jeton transferinin data
sına da kodlanabilir, örneğin _someNumber
için 12345 değeriyle bar() fonksiyonunu çağırabiliriz. Bu durumda data
şu şekilde olmalıdır: 0x0423a13200000000000000000000000000000000000000000000000000000000000004d2
, burada 0x0423a132
, bar(uint256)
fonksiyonunun imzası ve 00000000000000000000000000000000000000000000000000000000000004d2
ise uint256 olarak 12345'tir.
Sınırlamalar
ERC-223, ERC-20 standardında bulunan birkaç sorunu ele alırken, kendi sınırlamaları da vardır:
- Benimsenme ve Uyumluluk: ERC-223 henüz geniş çapta benimsenmemiştir, bu da mevcut araç ve platformlarla uyumluluğunu sınırlayabilir.
- Geriye Dönük Uyumluluk: ERC-223, ERC-20 ile geriye dönük uyumlu değildir; bu nedenle mevcut ERC-20 sözleşmeleri ve araçlar, ERC-223 jetonları ile modifikasyon yapılmadan çalışmaz.
- Gaz Maliyetleri: ERC-223 transferlerindeki ek kontrol ve işlevler, ERC-20 işlemlerine kıyasla daha yüksek gaz maliyetlerine neden olabilir.