Ugrás a fő tartalomra
Change page

ERC-223 tokenszabvány

Utolsó módosítás: @Satglow(opens in a new tab), 2024. június 11.

Bevezetés

Mi az az ERC-223?

ERC-223 a helyettesíthető tokenek szabványa, amely hasonlít az ERC-20-hoz. A fő különbség az, hogy az ERC-223 nemcsak a token API-t adja meg, hanem a küldési logikát is a küldő és a fogadó között. Egy kommunikációs modellt vezet be, amely alapján a fogadó képes kezelni a token fogadását.

Eltérések az ERC-20-hoz képest

Az ERC-223 kezeli az ERC-20 néhány korlátját, és egy új interakciós módszert vezet be a tokenszerződés és a tokent befogadó szerződés között. Néhány dolog lehetséges az ERC-223-mal, de az ERC-20-szal nem:

  • A tokenküldés kezelése a fogadó oldalán: a fogadó fél képes követni, hogy egy ERC-223-as token érkezett.
  • A helytelenül küldött tokenek elutasítása: ha a felhasználó ERC-223-as tokent küld egy szerződésnek, amely nem fogad tokeneket, akkor el tudja utasítani azt, így nem veszik el.
  • Metaadatok a küldés során: az ERC-223 token metaadatokat is tartalmaz, így bármilyen információt át lehet adni a tokenküldésnél.

Előfeltételek

  • Számlák
  • Okosszerződések
  • Tokenszabványok
  • ERC-20

Törzs

Az ERC-223 egy tokenszabvány, ami API-t implementál a tokeneknek az okosszerződésekben. Emellett API-t határoz meg azoknak a szerződéseknek, melyek ERC-223 tokent fogadnak be. Azok a szerződések, amelyek nem támogatják az ERC-223-at befogadó API-t, nem fogadhatnak ilyen tokent, így megakadályozzák a hibát.

Ha az okosszerződés implementálja a következő metódusokat és eseményeket, akkor egy ERC-223-kompatibilis tokenszerződésnek nevezhető. Amint telepítve van, trekkelnie kell a létrehozott tokeneket az Ethereumon.

A szerződésnek nem kell csak ilyen funkciókkal bírnia, a fejlesztő más jellemzőket is használhat a többi tokenszabványból is. Például az „approve” és a „transferFrom” függvények nincsenek benne az ERC-223 szabványban, de implementálhatók.

EIP-223-ból(opens in a new tab):

Metódusok

Az ERC-223 tokennek a következő metódusokat kell implementálnia:

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)
Másolás

A szerződésnek, mely ERC-223 tokent fogad be, a következő metódusokat kell implementálnia:

1function tokenReceived(address _from, uint _value, bytes calldata _data)
Másolás

Ha ERC-223 tokent küldenek egy olyan szerződésnek, amely nem implementálja a „tokenReceived(..)” függvényt, akkor az átadás elbukik és a token nem hagyja el a küldőt.

Események

1event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data)
Másolás

Példák

Az ERC-223 token API-ja hasonlít az ERC-20-ashoz, ezért felhasználóifelület-fejlesztés szempontból nincs különbség. Az egyetlen kivételaz, hogy az ERC-223 tokenek nem ismerik az „approve” + „transferFrom” függvényeket, mert ezek opcionálisak.

Solidity-példák

A következő példa bemutatja, hogyan működik egy alap ERC-223 tokenszerződés:

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}
Összes megjelenítése
Másolás

Szeretnénk, ha egy másik szerződés „tokenA” letétet fogadna el, feltéve, hogy tokenA egy ERC-223 token. A szerződés csak tokenA-t fogadhat el, a többit el kell utasítsa. Amikor a szerződés tokenA-t kap, akkor „Deposit()” eseményt kell kiadnia, és megnöveli a belső „deposits” változót az adott értékkel.

Íme a kód:

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 override
6 {
7 // It is important to understand that within this function
8 // 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}
Összes megjelenítése
Másolás

Gyakran ismételt kérdések

Mi történik, ha tokenB-t küldünk a szerződésnek?

A tranzakció elbukik, a tokenátadás nem történik meg. A tokenek a küldő címére térnek vissza.

Hogyan lehet letétet elhelyezni ebbe a szerződésbe?

Meg kell hívni az ERC-223 token „transfer(address,uint256)” vagy „transfer(address,uint256,bytes)” függvényeit, megadva a „RecipientContract” címét.

Mi történik, ha ERC-20 tokent küldünk egy ilyen szerződésnek?

Ha ERC-20 tokent küldenek a „RecipientContract” szerződésnek, akkor az átadás megtörténik, de a szerződés nem ismeri fel (nem lesz „Deposit()” esemény, és az érték sem változik). A nem kívánt ERC-20 letéteket nem lehet kiszűrni vagy megakadályozni.

Mi van, ha szeretnénk függvényt végrehajtani, miután a token letét végbement?

Ennek többféle módja van. Ebben a példában megnézzük a metódust, amitől az ERC-223 átadás egyenértékű lesz az ether-küldéssel:

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 override
6 {
7 require(msg.sender == tokenA);
8 address(this).call(_data); // Handle incoming transaction and perform a subsequent function call.
9 }
10 function foo() public
11 {
12 emit Foo();
13 }
14 function bar(uint256 _someNumber) public
15 {
16 emit Bar(_someNumber);
17 }
18}
Összes megjelenítése
Másolás

Amikor a „RecipientContract” kap egy ERC-223 tokent, a szerződés a token tranzakció „_data” paramétereként kódolt függvényt hajt végre, ugyanúgy, ahogy az ether-tranzakciók kódolják a függvényhívásokat a tranzakció „data” paramétereként. Tekintse meg az adatmezőt(opens in a new tab) további információért.

A fenti példában az ERC-223 tokent a „RecipientContract” címre a „transfer(address,uin256,bytes calldata _data)” függvénnyel kell küldeni. Ha az adatparaméter „0xc2985578” (ami a „foo()” függvény jele), akkor a foo() függvény indul el a token letétbe helyezése után, és a Foo() eseményt adja.

A paramétereket be lehet adni a token átadás „data” részébe is, például meghívhatjuk a bar() függvényt az 12345 értékkel „_someNumber” mezőben. Ekkor a „data” a következő „0x0423a13200000000000000000000000000000000000000000000000000000000000004d2”, ahol a „0x0423a132” a „bar(uint256)” függvény aláírása és „00000000000000000000000000000000000000000000000000000000000004d2” a 12345 érték uint256-ként.

Korlátok

Miközben az ERC-223 megold néhány gondot az ERC-20 szabvány kapcsán, megvannak a maga korlátai:

  • Adaptáció és kompatibilitás: az ERC-223 még nincs széles körben adaptálva, ami miatt behatárolt a meglévő eszközökkel és platformokkal való kompatibilitása.
  • Visszafelé ható kompatibilitás: az ERC-223 nem kompatibilis visszafelé az ERC-20-szal, tehát a meglévő ERC-20-as szerződések és eszközök nem fognak működni az ERC-223 tokenekkel változtatás nélkül.
  • Gázköltségek: Az ERC-223 küldés extra ellenőrzései és funkciói nagyobb költségeket eredményezhetnek egy ERC-20 tranzakcióhoz képest.

További olvasnivaló

Hasznosnak találta a cikket?