Přeskočit na hlavní obsah
Change page

Standard tokenu ERC-223

Stránka naposledy aktualizována: 6. září 2025

Úvod

Co je ERC-223?

ERC-223 je standard pro zastupitelné tokeny, podobný standardu ERC-20. Klíčový rozdíl spočívá v tom, že ERC-223 definuje nejen API tokenu, ale také logiku pro převod tokenů od odesílatele k příjemci. Zavádí komunikační model, který umožňuje zpracování převodů tokenů na straně příjemce.

Rozdíly oproti ERC-20

ERC-223 řeší některá omezení ERC-20 a zavádí novou metodu interakce mezi kontraktem tokenu a kontraktem, který může tokeny přijímat. Existuje několik věcí, které jsou s ERC-223 možné, ale s ERC-20 ne:

  • Zpracování převodu tokenů na straně příjemce: Příjemci mohou zjistit, že je ukládán token ERC-223.
  • Odmítnutí nesprávně odeslaných tokenů: Pokud uživatel odešle tokeny ERC-223 do kontraktu, který nemá tokeny přijímat, může kontrakt transakci odmítnout a zabránit tak ztrátě tokenů.
  • Metadata v převodech: Tokeny ERC-223 mohou obsahovat metadata, což umožňuje k transakcím s tokeny připojit libovolné informace.

Předpoklady

Tělo

ERC-223 je tokenový standard, který implementuje API pro tokeny v rámci chytrých kontraktů. Deklaruje také API pro kontrakty, které mají přijímat tokeny ERC-223. Kontrakty, které nepodporují rozhraní API ERC-223 Receiver, nemohou přijímat tokeny ERC-223, což zabraňuje chybám uživatelů.

Pokud chytrý kontrakt implementuje následující metody a události, lze jej označit za kontrakt tokenu kompatibilní s ERC-223. Po nasazení bude zodpovědný za sledování vytvořených tokenů na Ethereu.

Kontrakt nemusí obsahovat pouze tyto funkce a vývojář může do tohoto kontraktu přidat jakoukoli jinou funkci z různých tokenových standardů. Například funkce approve a transferFrom nejsou součástí standardu ERC-223, ale v případě potřeby je lze implementovat.

Z EIP-223 (opens in a new tab):

Metody

Token ERC-223 musí implementovat následující metody:

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)

Kontrakt, který má přijímat tokeny ERC-223, musí implementovat následující metodu:

1function tokenReceived(address _from, uint _value, bytes calldata _data)

Pokud jsou tokeny ERC-223 odeslány do kontraktu, který neimplementuje funkci tokenReceived(..), převod musí selhat a tokeny nesmí být přesunuty ze zůstatku odesílatele.

Události

1event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data)

Příklady

API tokenu ERC-223 je podobné API ERC-20, takže z hlediska vývoje uživatelského rozhraní zde není žádný rozdíl. Jedinou výjimkou je, že tokeny ERC-223 nemusí mít funkce approve + transferFrom, protože ty jsou pro tento standard volitelné.

Příklady v Solidity

Následující příklad ukazuje, jak funguje základní kontrakt tokenu ERC-223:

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}
Zobrazit vše

Nyní chceme, aby jiný kontrakt přijímal vklady tokenu tokenA za předpokladu, že tokenA je tokenem ERC-223. Kontrakt musí přijímat pouze tokenA a odmítat všechny ostatní tokeny. Když kontrakt obdrží tokenA, musí emitovat událost Deposit() a zvýšit hodnotu interní proměnné deposits.

Zde je kód:

1contract RecipientContract is IERC223Recipient {
2 event Deposit(address whoSentTheTokens);
3 uint256 deposits = 0;
4 address tokenA; // Jediný token, který chceme přijmout.
5 function tokenReceived(address _from, uint _value, bytes memory _data) public override
6 {
7 // Je důležité si uvědomit, že v rámci této funkce
8 // msg.sender je adresa tokenu, který je přijímán,
9 // msg.value je vždy 0, protože kontrakt tokenu ve většině případů nevlastní ani neposílá ether,
10 // _from je odesílatel převodu tokenu,
11 // _value je množství vložených tokenů.
12 require(msg.sender == tokenA);
13 deposits += _value;
14 emit Deposit(_from);
15 }
16}
Zobrazit vše

Často kladené dotazy

Co se stane, když do kontraktu pošleme nějaký tokenB?

Transakce selže a převod tokenů se neuskuteční. Tokeny budou vráceny na adresu odesílatele.

Jak můžeme na tento kontrakt provést vklad?

Zavolejte funkci transfer(address,uint256) nebo transfer(address,uint256,bytes) tokenu ERC-223 a zadejte adresu kontraktu RecipientContract.

Co se stane, když na tento kontrakt převedeme token ERC-20?

Pokud je na RecipientContract odeslán token ERC-20, tokeny budou převedeny, ale převod nebude rozpoznán (nebude spuštěna žádná událost Deposit() a hodnota vkladů se nezmění). Nežádoucí vklady ERC-20 nelze filtrovat ani jim zabránit.

Co když chceme po dokončení vkladu tokenu spustit nějakou funkci?

Existuje několik způsobů, jak toho dosáhnout. V tomto příkladu se budeme řídit metodou, díky níž jsou převody ERC-223 totožné s převody etheru:

1contract RecipientContract is IERC223Recipient {
2 event Foo();
3 event Bar(uint256 someNumber);
4 address tokenA; // Jediný token, který chceme přijmout.
5 function tokenReceived(address _from, uint _value, bytes memory _data) public override
6 {
7 require(msg.sender == tokenA);
8 address(this).call(_data); // Zpracujte příchozí transakci a proveďte následné volání funkce.
9 }
10 function foo() public
11 {
12 emit Foo();
13 }
14 function bar(uint256 _someNumber) public
15 {
16 emit Bar(_someNumber);
17 }
18}
Zobrazit vše

Když RecipientContract obdrží token ERC-223, spustí funkci zakódovanou jako parametr _data transakce tokenu, a to stejným způsobem, jakým transakce s etherem kódují volání funkcí jako transakční data. Pro více informací si přečtěte o datovém poli.

Ve výše uvedeném příkladu musí být token ERC-223 převeden na adresu kontraktu RecipientContract pomocí funkce transfer(address,uin256,bytes calldata _data). Pokud bude datový parametr 0xc2985578 (podpis funkce foo()), pak bude po přijetí vkladu tokenu vyvolána funkce foo() a bude spuštěna událost Foo().

Parametry lze také zakódovat do dat převodu tokenu, například můžeme zavolat funkci bar() s hodnotou 12345 pro _someNumber. V tomto případě musí být data 0x0423a13200000000000000000000000000000000000000000000000000000000000004d2, kde 0x0423a132 je podpis funkce bar(uint256) a 00000000000000000000000000000000000000000000000000000000000004d2 je 12345 jako uint256.

Omezení

Ačkoli ERC-223 řeší několik problémů, které se vyskytují ve standardu ERC-20, není bez vlastních omezení:

  • Přijetí a kompatibilita: ERC-223 ještě není široce přijat, což může omezit jeho kompatibilitu se stávajícími nástroji a platformami.
  • Zpětná kompatibilita: ERC-223 není zpětně kompatibilní s ERC-20, což znamená, že stávající kontrakty a nástroje ERC-20 nebudou s tokeny ERC-223 fungovat bez úprav.
  • Náklady na palivo: Dodatečné kontroly a funkce v převodech ERC-223 mohou mít za následek vyšší náklady na palivo ve srovnání s transakcemi ERC-20.

Další čtení

Byl tento článek užitečný?