From c61adf544712974586a4bc560d665ac0fd142e19 Mon Sep 17 00:00:00 2001 From: Dexaran Date: Mon, 11 Dec 2023 23:11:22 +0400 Subject: [PATCH 1/7] Update index.md --- src/content/developers/docs/standards/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/developers/docs/standards/index.md b/src/content/developers/docs/standards/index.md index 33cb3349f0a..682558fe2d8 100644 --- a/src/content/developers/docs/standards/index.md +++ b/src/content/developers/docs/standards/index.md @@ -40,6 +40,7 @@ More detailed information on these different types and categories can be found i ### Token standards {#token-standards} - [ERC-20](/developers/docs/standards/tokens/erc-20/) - A standard interface for fungible (interchangeable) tokens, like voting tokens, staking tokens or virtual currencies. +- [ERC-223](/developers/docs/standards/tokens/erc-223/) - A fungible tokens standard that makes tokens behave identical to ether and supports token transfers handling on the recipients side. - [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) - Defines a token interface for ERC-20 tokens that supports executing recipient code after transfer or transferFrom, or spender code after approve. - [ERC-721](/developers/docs/standards/tokens/erc-721/) - A standard interface for non-fungible tokens, like a deed for artwork or a song. - [ERC-2309](https://eips.ethereum.org/EIPS/eip-2309) - A standardized event emitted when creating/transferring one, or many non-fungible tokens using consecutive token identifiers. From 727804b39422ddfbd8bd5e3a1abaa487d099b5ec Mon Sep 17 00:00:00 2001 From: Dexaran Date: Mon, 11 Dec 2023 23:12:14 +0400 Subject: [PATCH 2/7] Create index.md --- src/content/developers/docs/standards/tokens/erc-223/index.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/content/developers/docs/standards/tokens/erc-223/index.md diff --git a/src/content/developers/docs/standards/tokens/erc-223/index.md b/src/content/developers/docs/standards/tokens/erc-223/index.md new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/content/developers/docs/standards/tokens/erc-223/index.md @@ -0,0 +1 @@ + From 3df37f9932d469462d04cc0a1845e3e381e493d1 Mon Sep 17 00:00:00 2001 From: Dexaran Date: Mon, 11 Dec 2023 23:12:28 +0400 Subject: [PATCH 3/7] Update index.md --- .../docs/standards/tokens/erc-223/index.md | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/src/content/developers/docs/standards/tokens/erc-223/index.md b/src/content/developers/docs/standards/tokens/erc-223/index.md index 8b137891791..6b870cea2f1 100644 --- a/src/content/developers/docs/standards/tokens/erc-223/index.md +++ b/src/content/developers/docs/standards/tokens/erc-223/index.md @@ -1 +1,193 @@ +--- +title: ERC-223 Token Standard +description: An overview of the ERC-223 fungible token standard, how it works, and a comparison to ERC-20. +lang: en +--- +## Introduction {#introduction} + +**What is ERC-223?** + +The ERC-223 is another standard for fungible tokens, like the ERC-20. The key difference is that ERC-223 defines not only the token API, but also the logic of how tokens should be transferred from sender to recipient and introduces a communication model that allows token transfers to be handled on the recipients side. + +**How is it different from ERC-20 and why we need another token standard?** + +ERC-223 addresses some limitations of ERC-20 and introduces a new method of interactions between token contract and a contract that may receive the tokens. There are few things that are possible with ERC-223 but not with ERC-20: + +- Token transfer handling on the recipient's side. Recipient can detect that an ERC-223 token is being deposited. +- Rejection of improperly sent tokens. If a user sent ERC-223 tokens to a contract that is not supposed to receive tokens then the contract can reject the transaction and the tokens will not be lost. +- The transfer of ERC-223 tokens may contain metadata, which allows arbitrary information to be attached to the token transactions. + +## Prerequisites {#prerequisites} + +- [Accounts](/developers/docs/accounts) +- [Smart Contracts](/developers/docs/smart-contracts/) +- [Token standards](/developers/docs/standards/tokens/) +- [ERC-20](/developers/docs/standards/tokens/erc-20/) + +## Body {#body} + +The ERC-223 (Ethereum Request for Comments 223), proposed by Dexaran in March 2017, is a token standard that +implements an API for tokens within smart contracts and declares API for a contract that is supposed to receive ERC-223 tokens. Any contract that does not support ERC-223 Receiver API can not receive ERC-223 tokens which prevents the most common user mistakes. + +If a smart contract implements the following methods and events it can be called an ERC-223 compatible token contract. Once deployed, it +will be responsible to keep track of the created tokens on Ethereum. + +The contract is not obligated to have only these functions and a developer can add any other feature from different token standards to this contract. For example, `approve` and `transferFrom` functions are not part of ERC-223 standard but these functions could be implemented should it be necessary. + +From [EIP-223](https://eips.ethereum.org/EIPS/eip-223): + +#### Methods {#methods} + +ERC-223 token must implement the following methods: + +```solidity +function name() public view returns (string) +function symbol() public view returns (string) +function decimals() public view returns (uint8) +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 transfer(address _to, uint256 _value, bytes calldata _data) public returns (bool success) +``` + +A contract that is supposed to receive ERC-223 tokens must implement the following method: + +```solidity +function tokenReceived(address _from, uint _value, bytes calldata _data) +``` + +If ERC-223 tokens are sent to a contract that doesn't implement the `tokenReceived(..)` function then the transfer must fail and the tokens must not be moved from the sender's balance. + +#### Events {#events} + +```solidity +event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data) +``` + +### Examples {#examples} + +The API of ERC-223 token is similar to that of ERC-20, so from UI development point of view there is no difference. The only exception here is that ERC-223 tokens may not have `approve` + `transferFrom` functions as these are optional for this standard. + +### Solidity examples {#solidity-example} + +The purpose of this example is to illustrate how a contract must work with ERC-223 tokens. + +Assume that we have a very basic ERC-223 token: + +```solidity +pragma solidity ^0.8.19; +abstract contract IERC223Recipient { + function tokenReceived(address _from, uint _value, bytes memory _data) public virtual; +} +contract VeryBasicERC223Token { + event Transfer(address indexed from, address indexed to, uint value, bytes data); + string private _name; + string private _symbol; + uint8 private _decimals; + uint256 private _totalSupply; + mapping(address => uint256) private balances; + function name() public view returns (string memory) { return _name; } + function symbol() public view returns (string memory) {return _symbol; } + function decimals() public view returns (uint8) { return _decimals; } + function totalSupply() public view returns (uint256) { return _totalSupply; } + function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; } + function isContract(address account) internal view returns (bool) { + uint256 size; + assembly { size := extcodesize(account) } + return size > 0; + } + function transfer(address _to, uint _value, bytes calldata _data) public returns (bool success){ + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data); + } + emit Transfer(msg.sender, _to, _value, _data); + return true; + } + function transfer(address _to, uint _value) public returns (bool success){ + bytes memory _empty = hex"00000000"; + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty); + } + emit Transfer(msg.sender, _to, _value, _empty); + return true; + } +} +``` + +Now we want another contract to accept deposits of `tokenA` assuming that tokenA is an ERC-223 token. The contract must accept only tokenA and reject any other tokens. When the contract receives tokenA it must emit a `Deposit()` event and increase the value of the internal `deposits` variable. + +Here is the code: + +```solidity +contract RecipientContract is IERC223Recipient { + event Deposit(address whoSentTheTokens); + uint256 deposits = 0; + address tokenA; // The only token that we want to accept. + function tokenReceived(address _from, uint _value, bytes memory _data) public override + { + // It is important to understand that within this function + // msg.sender is the address of a token that is being received, + // msg.value is always 0 as the token contract does not own or send Ether in most cases, + // _from is the sender of the token transfer, + // _value is the amount of tokens that was deposited. + require(msg.sender == tokenA); + deposits += _value; + emit Deposit(_from); + } +} +``` + +## Frequently asked questions {#faq} + +### What will happen if we send some tokenB to the contract? {#sending-tokens} + +The transaction will fail and the transfer of tokens will simply not happen. The tokens will be returned to the sender's address. + +### How can we make a deposit to this contract? {#contract-deposits} + +We can simply call the `transfer(address,uint256)` or `transfer(address,uint256,bytes)` function of the ERC-223 token and tell it to transfer some tokens to the address of the `RecipientContract`. That's it. + +### What will happen if we transfer an ERC-20 token to this contract? {#erc-20-transfers} + +The ERC-20 standard supports two methods of transferring tokens: `transfer` function and `approve + transferFrom` pattern. This is not possible to make a deposit with `transferFrom` function as the `RecipientContract` does not have any functions that subsequently call `transferFrom`. If an ERC-20 token is sent with `transfer` function to the address of the `RecipientContract` then unfortunately the tokens will be transferred from the sender's address to the address of the `RecipientContract` but the transfer will not be recognized i.e. `Deposit()` event will not be fired and `deposits` value will not change. There is also no way to filter or prevent unwanted ERC-20 deposits that are made with the `transfer` function. + +### What if we want to execute some function after the token deposit is completed? {#function-execution} + +There are multiple ways of doing so. In this example we will follow the method which makes ERC-223 transfers identical to Ether transfers: + +```solidity +contract RecipientContract is IERC223Recipient { + event Foo(); + event Bar(uint256 someNumber); + address tokenA; // The only token that we want to accept. + function tokenReceived(address _from, uint _value, bytes memory _data) public override + { + require(msg.sender == tokenA); + address(this).call(_data); // Handle incoming transaction and perform a subsequent function call. + } + function foo() public + { + emit Foo(); + } + function bar(uint256 _someNumber) public + { + emit Bar(_someNumber); + } +} +``` + +When the `RecipientContract` will receive a ERC-223 token the contract will execute a function encoded as `_data` parameter of the token transaction, identical to how Ether transactions encode function calls as transaction `data`. Read [the data field](https://ethereum.org/en/developers/docs/transactions/#the-data-field) for more information. + +In the above example an ERC-223 token must be transferred to the address of the `RecipientContract` with the `transfer(address,uin256,bytes calldata _data)` function. If the data parameter will be `0xc2985578` (the signature of a `foo()` function) then the function foo() will be invoked after the token deposit is received and the event Foo() will be fired. + +Parameters can be encoded in the `data` of the token transfer as well, for example we can call the bar() function with 12345 value for `_someNumber`. In this case the `data` must be `0x0423a13200000000000000000000000000000000000000000000000000000000000004d2` where `0x0423a132` is the signature of the `bar(uint256)` function and `00000000000000000000000000000000000000000000000000000000000004d2` is 12345 as uint256. + +## Further reading {#further-reading} + +- [EIP-223: ERC-223 Token Standard](https://eips.ethereum.org/EIPS/eip-223) +- [Initial ERC-223 proposal](https://github.com/ethereum/eips/issues/223) From 1187dbdec01cb4634723f2589f69616f17c42422 Mon Sep 17 00:00:00 2001 From: Dexaran Date: Mon, 11 Dec 2023 23:13:16 +0400 Subject: [PATCH 4/7] Update index.md --- src/content/developers/docs/standards/tokens/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/developers/docs/standards/tokens/index.md b/src/content/developers/docs/standards/tokens/index.md index 92f8fe8b3fc..46a1064c4f2 100644 --- a/src/content/developers/docs/standards/tokens/index.md +++ b/src/content/developers/docs/standards/tokens/index.md @@ -19,6 +19,7 @@ Many Ethereum development standards focus on token interfaces. These standards h Here are some of the most popular token standards on Ethereum: - [ERC-20](/developers/docs/standards/tokens/erc-20/) - A standard interface for fungible (interchangeable) tokens, like voting tokens, staking tokens or virtual currencies. +- [ERC-223](/developers/docs/standards/tokens/erc-223/) - A fungible token standard with "transaction handling" model that makes token behave identical to ether. - [ERC-721](/developers/docs/standards/tokens/erc-721/) - A standard interface for non-fungible tokens, like a deed for artwork or a song. - [ERC-777](/developers/docs/standards/tokens/erc-777/) - ERC-777 allows people to build extra functionality on top of tokens such as a mixer contract for improved transaction privacy or an emergency recover function to bail you out if you lose your private keys. - [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - ERC-1155 allows for more efficient trades and bundling of transactions – thus saving costs. This token standard allows for creating both utility tokens (such as $BNB or $BAT) and Non-Fungible Tokens like CryptoPunks. From f6b1e6c9316301a8b39a8859f14eac6e37b9fda9 Mon Sep 17 00:00:00 2001 From: Dexaran Date: Mon, 11 Dec 2023 23:15:05 +0400 Subject: [PATCH 5/7] Update developer-docs-links.yaml --- src/data/developer-docs-links.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/data/developer-docs-links.yaml b/src/data/developer-docs-links.yaml index aea656f0866..33a6d28ccb0 100644 --- a/src/data/developer-docs-links.yaml +++ b/src/data/developer-docs-links.yaml @@ -195,6 +195,8 @@ items: - id: docs-nav-erc-20 to: /developers/docs/standards/tokens/erc-20/ + - id: docs-nav-erc-223 + to: /developers/docs/standards/tokens/erc-223/ - id: docs-nav-erc-721 to: /developers/docs/standards/tokens/erc-721/ - id: docs-nav-erc-777 From 7344c188d1cc60a220ec70dd6959863a87d5bf86 Mon Sep 17 00:00:00 2001 From: Joshua <62268199+minimalsm@users.noreply.github.com> Date: Fri, 31 May 2024 12:03:41 +0100 Subject: [PATCH 6/7] Apply suggestions from code review --- .../docs/standards/tokens/erc-223/index.md | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/content/developers/docs/standards/tokens/erc-223/index.md b/src/content/developers/docs/standards/tokens/erc-223/index.md index 6b870cea2f1..aea6618788e 100644 --- a/src/content/developers/docs/standards/tokens/erc-223/index.md +++ b/src/content/developers/docs/standards/tokens/erc-223/index.md @@ -6,17 +6,17 @@ lang: en ## Introduction {#introduction} -**What is ERC-223?** +### What is ERC-223? {#what-is-erc223} -The ERC-223 is another standard for fungible tokens, like the ERC-20. The key difference is that ERC-223 defines not only the token API, but also the logic of how tokens should be transferred from sender to recipient and introduces a communication model that allows token transfers to be handled on the recipients side. +The ERC-223 is a standard for fungible tokens, similar to the ERC-20 standard. The key difference is that ERC-223 defines not only the token API but also the logic for transferring tokens from sender to recipient. It introduces a communication model that allows token transfers to be handled on the recipient's side. -**How is it different from ERC-20 and why we need another token standard?** +### Differences from ERC-20 {#erc20-differences} -ERC-223 addresses some limitations of ERC-20 and introduces a new method of interactions between token contract and a contract that may receive the tokens. There are few things that are possible with ERC-223 but not with ERC-20: +ERC-223 addresses some limitations of ERC-20 and introduces a new method of interaction between the token contract and a contract that may receive the tokens. There are few things that are possible with ERC-223 but not with ERC-20: -- Token transfer handling on the recipient's side. Recipient can detect that an ERC-223 token is being deposited. -- Rejection of improperly sent tokens. If a user sent ERC-223 tokens to a contract that is not supposed to receive tokens then the contract can reject the transaction and the tokens will not be lost. -- The transfer of ERC-223 tokens may contain metadata, which allows arbitrary information to be attached to the token transactions. +- Token transfer handling on the recipient's side: Recipients can detect that an ERC-223 token is being deposited. +- Rejection of improperly sent tokens: If a user sends ERC-223 tokens to a contract not supposed to receive tokens, the contract can reject the transaction, preventing token loss. +- Metadata in transfers: ERC-223 tokens can include metadata, allowing arbitrary information to be attached to token transactions. ## Prerequisites {#prerequisites} @@ -27,8 +27,7 @@ ERC-223 addresses some limitations of ERC-20 and introduces a new method of inte ## Body {#body} -The ERC-223 (Ethereum Request for Comments 223), proposed by Dexaran in March 2017, is a token standard that -implements an API for tokens within smart contracts and declares API for a contract that is supposed to receive ERC-223 tokens. Any contract that does not support ERC-223 Receiver API can not receive ERC-223 tokens which prevents the most common user mistakes. +ERC-223 is a token standard that implements an API for tokens within smart contracts. It also declares an API for contracts that are supposed to receive ERC-223 tokens. Contracts that do not support the ERC-223 Receiver API cannot receive ERC-223 tokens, preventing user error. If a smart contract implements the following methods and events it can be called an ERC-223 compatible token contract. Once deployed, it will be responsible to keep track of the created tokens on Ethereum. @@ -71,9 +70,7 @@ The API of ERC-223 token is similar to that of ERC-20, so from UI development po ### Solidity examples {#solidity-example} -The purpose of this example is to illustrate how a contract must work with ERC-223 tokens. - -Assume that we have a very basic ERC-223 token: +The following example illustrates how a basic ERC-223 token contract operates: ```solidity pragma solidity ^0.8.19; @@ -146,15 +143,15 @@ contract RecipientContract is IERC223Recipient { ### What will happen if we send some tokenB to the contract? {#sending-tokens} -The transaction will fail and the transfer of tokens will simply not happen. The tokens will be returned to the sender's address. +The transaction will fail, and the transfer of tokens will not happen. The tokens will be returned to the sender's address. ### How can we make a deposit to this contract? {#contract-deposits} -We can simply call the `transfer(address,uint256)` or `transfer(address,uint256,bytes)` function of the ERC-223 token and tell it to transfer some tokens to the address of the `RecipientContract`. That's it. +Call the `transfer(address,uint256)` or `transfer(address,uint256,bytes)` function of the ERC-223 token, specifying the address of the `RecipientContract`. ### What will happen if we transfer an ERC-20 token to this contract? {#erc-20-transfers} -The ERC-20 standard supports two methods of transferring tokens: `transfer` function and `approve + transferFrom` pattern. This is not possible to make a deposit with `transferFrom` function as the `RecipientContract` does not have any functions that subsequently call `transferFrom`. If an ERC-20 token is sent with `transfer` function to the address of the `RecipientContract` then unfortunately the tokens will be transferred from the sender's address to the address of the `RecipientContract` but the transfer will not be recognized i.e. `Deposit()` event will not be fired and `deposits` value will not change. There is also no way to filter or prevent unwanted ERC-20 deposits that are made with the `transfer` function. +If an ERC-20 token is sent to the `RecipientContract`, the tokens will be transferred, but the transfer will not be recognized (no `Deposit()` event will be fired, and the deposits value will not change). Unwanted ERC-20 deposits cannot be filtered or prevented. ### What if we want to execute some function after the token deposit is completed? {#function-execution} @@ -187,6 +184,14 @@ In the above example an ERC-223 token must be transferred to the address of the Parameters can be encoded in the `data` of the token transfer as well, for example we can call the bar() function with 12345 value for `_someNumber`. In this case the `data` must be `0x0423a13200000000000000000000000000000000000000000000000000000000000004d2` where `0x0423a132` is the signature of the `bar(uint256)` function and `00000000000000000000000000000000000000000000000000000000000004d2` is 12345 as uint256. +## Limitations {#limitations} + +While ERC-223 addresses several issues found in the ERC-20 standard, it is not without its own limitations: + +- Adoption and Compatibility: ERC-223 is not yet widely adopted, which may limit its compatibility with existing tools and platforms. +- Backward Compatibility: ERC-223 is not backward compatible with ERC-20, meaning that existing ERC-20 contracts and tools will not work with ERC-223 tokens without modifications. +- Gas Costs: The additional checks and functionalities in ERC-223 transfers may result in higher gas costs compared to ERC-20 transactions. + ## Further reading {#further-reading} - [EIP-223: ERC-223 Token Standard](https://eips.ethereum.org/EIPS/eip-223) From 924aef1f0a71840d348d74be350f60cb85add8f2 Mon Sep 17 00:00:00 2001 From: Corwin Smith Date: Tue, 11 Jun 2024 13:24:35 -0600 Subject: [PATCH 7/7] fixes to get working on site --- .../developers/docs/standards/tokens/erc-223/index.md | 8 ++++---- src/lib/utils/md.ts | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) rename {src => public}/content/developers/docs/standards/tokens/erc-223/index.md (96%) diff --git a/src/content/developers/docs/standards/tokens/erc-223/index.md b/public/content/developers/docs/standards/tokens/erc-223/index.md similarity index 96% rename from src/content/developers/docs/standards/tokens/erc-223/index.md rename to public/content/developers/docs/standards/tokens/erc-223/index.md index aea6618788e..76f3f5559c3 100644 --- a/src/content/developers/docs/standards/tokens/erc-223/index.md +++ b/public/content/developers/docs/standards/tokens/erc-223/index.md @@ -8,7 +8,7 @@ lang: en ### What is ERC-223? {#what-is-erc223} -The ERC-223 is a standard for fungible tokens, similar to the ERC-20 standard. The key difference is that ERC-223 defines not only the token API but also the logic for transferring tokens from sender to recipient. It introduces a communication model that allows token transfers to be handled on the recipient's side. +ERC-223 is a standard for fungible tokens, similar to the ERC-20 standard. The key difference is that ERC-223 defines not only the token API but also the logic for transferring tokens from sender to recipient. It introduces a communication model that allows token transfers to be handled on the recipient's side. ### Differences from ERC-20 {#erc20-differences} @@ -36,7 +36,7 @@ The contract is not obligated to have only these functions and a developer can a From [EIP-223](https://eips.ethereum.org/EIPS/eip-223): -#### Methods {#methods} +### Methods {#methods} ERC-223 token must implement the following methods: @@ -58,7 +58,7 @@ function tokenReceived(address _from, uint _value, bytes calldata _data) If ERC-223 tokens are sent to a contract that doesn't implement the `tokenReceived(..)` function then the transfer must fail and the tokens must not be moved from the sender's balance. -#### Events {#events} +### Events {#events} ```solidity event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data) @@ -68,7 +68,7 @@ event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes The API of ERC-223 token is similar to that of ERC-20, so from UI development point of view there is no difference. The only exception here is that ERC-223 tokens may not have `approve` + `transferFrom` functions as these are optional for this standard. -### Solidity examples {#solidity-example} +#### Solidity examples {#solidity-example} The following example illustrates how a basic ERC-223 token contract operates: diff --git a/src/lib/utils/md.ts b/src/lib/utils/md.ts index a7be3d39cfb..38a75b539ed 100644 --- a/src/lib/utils/md.ts +++ b/src/lib/utils/md.ts @@ -140,6 +140,7 @@ const getPostSlugs = (dir: string, files: string[] = []) => { "/developers/docs/standards", "/developers/docs/standards/tokens", "/developers/docs/standards/tokens/erc-20", + "/developers/docs/standards/tokens/erc-223", "/developers/docs/standards/tokens/erc-721", "/developers/docs/standards/tokens/erc-777", "/developers/docs/standards/tokens/erc-1155",