-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add EIP-223: Token standard with event handling implementation #6485
Changes from 16 commits
b32a8a2
09f3879
4c6e49d
337c7a0
f3563ba
74493a4
b305a79
4523668
537c9c6
2f4595f
0bad3d8
f13c699
a3d05a5
0c8db1b
4ef1631
b3f6e3c
f265fed
8e87c99
10502bc
489a021
e691b31
8b8ebfb
fda8c4c
5eb2b7c
8076fc2
db8bdb4
797dfef
7c3387a
c888759
2b387f7
73bbb95
8afcba5
f51655b
e61458a
1857d83
c7a4cd9
0628cef
6f64550
4024619
88aff68
0b54c09
3090cc6
5f7b6ac
7b67c2e
6093c8f
bf71b97
b8463c0
52da79f
71ef953
936eca6
bbba42b
bd965a3
5bf8c06
5735aaa
ab5818b
ba4b2d1
98e74ca
218324b
5b09164
419550a
1a74ba0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,389 @@ | ||||||||||||||||||
--- | ||||||||||||||||||
eip: 223 | ||||||||||||||||||
title: 223 Token with communication model | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
description: Token with event handling and communication model | ||||||||||||||||||
author: Dexaran (@Dexaran) | ||||||||||||||||||
discussions-to: https://ethereum-magicians.org/t/erc-223-token-standard/12894 | ||||||||||||||||||
status: Review | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
type: Standards Track | ||||||||||||||||||
category: ERC | ||||||||||||||||||
created: 2017-05-03 | ||||||||||||||||||
--- | ||||||||||||||||||
|
||||||||||||||||||
## Abstract | ||||||||||||||||||
|
||||||||||||||||||
The following describes standard functions a token contract and contract which is intended to work with specified token can implement. This standard introduces a communication model which allows for the implementation of **event handling** on the receiver's side. | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
## Motivation | ||||||||||||||||||
|
||||||||||||||||||
1. This token introduces a communication model for contracts that can be utilized to straighten the behavior of contracts that interact with tokens as opposed to [ERC-20](./eip-20.md) where a token transfer could be ignored by the receiving contract. | ||||||||||||||||||
2. This token is more gas-efficient when depositing tokens to contracts. | ||||||||||||||||||
3. This token allows for `_data` recording for financial transfers. | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
## Specification | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generally we recommend using the blurb from the EIP template referring to RFC 2119 to define "MUST", "SHOULD", etc. |
||||||||||||||||||
Token | ||||||||||||||||||
Contracts that works with tokens | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
### Methods | ||||||||||||||||||
|
||||||||||||||||||
NOTE: An important point is that contract developers must implement `tokenReceived` if they want their contracts to work with the specified tokens. | ||||||||||||||||||
|
||||||||||||||||||
If the receiver does not implement the `tokenReceived` function, consider the contract is not designed to work with tokens, then the transaction must fail and no tokens will be transferred. An analogy with an Ether transaction that is failing when trying to send Ether to a contract that did not implement `receive() payable`. | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
#### totalSupply | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function totalSupply() constant returns (uint256 totalSupply) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
On another note, I'm not familiar with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'll update the code description to match the current version of Solidity Here is the actual 0.8.0 code https://github.com/Dexaran/ERC223-token-standard/blob/development/token/ERC223/ERC223.sol |
||||||||||||||||||
|
||||||||||||||||||
Get the total token supply | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be a good idea to define what "total token supply" means. |
||||||||||||||||||
|
||||||||||||||||||
#### name | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function name() constant returns (string _name) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
Get the name of token | ||||||||||||||||||
|
||||||||||||||||||
#### symbol | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function symbol() constant returns (bytes32 _symbol) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
Get the symbol of token | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, it might be a good idea to define what a symbol is. |
||||||||||||||||||
|
||||||||||||||||||
#### decimals | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function decimals() constant returns (uint8 _decimals) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
Get decimals of token | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's a decimal? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Solidity cannot operate on floating point numbers. As the result we use a quirk that we have "decimals" variable in each contract and whenever an interface displays your tokens the actual value is divided by I.e. USDT has 6 decimals. If you have 123,88 USD on your balance then it means that in the contract your |
||||||||||||||||||
|
||||||||||||||||||
#### standard | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function standard() constant returns (string _standard) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
Get the standard of token contract. For some services it is important to know how to treat this particular token. If token supports [ERC-223](./eip-223.md) standard then it must explicitly tell that it does. | ||||||||||||||||||
|
||||||||||||||||||
This function **MUST** return "ERC-223" for this token standard. If no "standard()" function is implemented in the contract then the contract must be considered to be ERC-20. | ||||||||||||||||||
|
||||||||||||||||||
#### balanceOf | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function balanceOf(address _owner) constant returns (uint256 balance) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
Get the account balance of another account with address _owner | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
#### transfer(address, uint) | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function transfer(address _to, uint _value) returns (bool) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
Needed due to backwards compatibility reasons because of ERC-20 transfer function doesn't have `bytes` parameter. This function must transfer tokens and invoke the function `tokenReceived(address, uint256, bytes calldata)` in `_to`, if _to is a contract. If the `tokenReceived` function is not implemented in `_to` (receiver contract), then the transaction must fail and the transfer of tokens should be reverted. | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
#### transfer(address, uint, bytes) | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function transfer(address _to, uint _value, bytes calldata _data) returns (bool) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
function that is always called when someone wants to transfer tokens. | ||||||||||||||||||
This function must transfer tokens and invoke the function `tokenReceived (address, uint256, bytes)` in `_to`, if _to is a contract. If the `tokenReceived` function is not implemented in `_to` (receiver contract), then the transaction must fail and the transfer of tokens should not occur. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would say that this was a correct wording because the whole transaction must fail on this error. If there are multiple calls within one transaction then it must fail altogether, not just this function call. |
||||||||||||||||||
If `_to` is an externally owned address, then the transaction must be sent without trying to execute `tokenReceived` in `_to`. | ||||||||||||||||||
`_data` can be attached to this token transaction and it will stay in blockchain forever (requires more gas). `_data` can be empty. | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
NOTE: The recommended way to check whether the `_to` is a contract or an address is to assemble the code of `_to`. If there is no code in `_to`, then this is an externally owned address, otherwise it's a contract. | ||||||||||||||||||
|
||||||||||||||||||
### Events | ||||||||||||||||||
|
||||||||||||||||||
#### Transfer | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
event Transfer(address indexed _from, address indexed _to, uint256 _value) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
Triggered when tokens are transferred. Compatible with ERC-20 `Transfer` event. | ||||||||||||||||||
|
||||||||||||||||||
#### TransferData | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
event TransferData(bytes _data) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
Triggered when tokens are transferred and logs transaction metadata. This is implemented as a separate event to keep `Transfer(address, address, uint256)` ERC-20-compatible. | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
### Contract that is intended to receive ERC-223 tokens | ||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
|
||||||||||||||||||
function tokenReceived(address _from, uint _value, bytes calldata _data) | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
A function for handling token transfers, which is called from the token contract, when a token holder sends tokens. `_from` is the address of the sender of the token, `_value` is the amount of incoming tokens, and `_data` is attached data similar to `msg.data` of Ether transactions. It works by analogy with the fallback function of Ether transactions and returns nothing. | ||||||||||||||||||
|
||||||||||||||||||
NOTE: `msg.sender` will be a token-contract inside the `tokenReceived` function. It may be important to filter which tokens are sent (by token-contract address). The token sender (the person who initiated the token transaction) will be `_from` inside the `tokenReceived` function. | ||||||||||||||||||
|
||||||||||||||||||
IMPORTANT: This function must be named `tokenReceived` and take parameters `address`, `uint256`, `bytes` to match the function signature `0xc0ee0b8a`. | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
## Rationale | ||||||||||||||||||
|
||||||||||||||||||
This standard introduces a communication model by enforcing the `transfer` to execute a handler function in the destination address. This is an important security consideration as it is required that the receiver explicitly implements the token handling function. In cases where the receiver does not implements such function the transfer MUST be reverted. | ||||||||||||||||||
|
||||||||||||||||||
This standard sticks to the push transaction model where the transfer of assets is initiated on the senders side and handled on the receivers side. As the result, ERC-223 transfers are more gas-efficient while dealing with depositing to contracts as ERC-223 tokens can be deposited with just one transaction while ERC-20 tokens require at least two calls (one for `approve` and the second that will invoke `transferFrom`). | ||||||||||||||||||
|
||||||||||||||||||
- [ERC-20](./eip-20.md) deposit: `approve` ~53K gas, `transferFrom` ~80K gas | ||||||||||||||||||
|
||||||||||||||||||
- ERC-223 deposit: `transfer` and handling on the receivers side ~46K gas | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does the deposit + call use less gas than an approve? I feel like this gas usage might be outdated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have performed this tests https://github.com/Dexaran/Token_Deposits_GAS_testing using REMIX, solidity 0.8.19, optimization 200 runs Updated the values:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your transferFrom function is very unoptimized, with 7 total internal contract calls from the initial |
||||||||||||||||||
|
||||||||||||||||||
This standard introduces the ability to correct user errors by allowing to handle ANY transactions on the recipient side and reject incorrect or improper transactions. This tokens utilize ONE transferring method for both types of interactions with tokens and externally owned addresses which can simplify the user experience and allow to avoid possible user mistakes. | ||||||||||||||||||
|
||||||||||||||||||
One downside of the commonly used [ERC-20](./eip-20.md) standard that ERC-223 is intended to solve is that [ERC-20](./eip-20.md) implements two methods of token transferring: (1) `transfer` function and (2) `approve + transferFrom` pattern. Transfer function of [ERC-20](./eip-20.md) standard does not notify the receiver and therefore if any tokens are sent to a contract with the `transfer` function then the receiver will not recognize this transfer and the tokens can become stuck in the receivers address without any possibility of recovering them. | ||||||||||||||||||
|
||||||||||||||||||
ERC-223 standard is intended to simplify the interaction with contracts that are intended to work with tokens. ERC-223 utilizes "deposit" pattern similar to plain Ether depositing patterns - in case of ERC-223 deposit to the contract a user or a UI must simply send the tokens with the `transfer` function. This is one transaction as opposed to two step process of `approve + transferFrom` depositing. | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
This standard allows payloads to be attached to transactions using the `bytes calldata _data` parameter, which can encode a second function call in the destination address, similar to how `msg.data` does in an Ether transaction, or allow for public loggin on chain should it be necessary for financial transactions. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo in "logging" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
## Security Considerations | ||||||||||||||||||
|
||||||||||||||||||
This token utilizes the model similar to plain Ether behavior. Therefore replay issues must be taken into account. | ||||||||||||||||||
Pandapip1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
### Reference implementation | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
```js | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
pragma solidity ^0.8.0; | ||||||||||||||||||
|
||||||||||||||||||
// Source: https://github.com/Dexaran/ERC-223 | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
||||||||||||||||||
library Address { | ||||||||||||||||||
/** | ||||||||||||||||||
* @dev Returns true if `account` is a contract. | ||||||||||||||||||
* | ||||||||||||||||||
* This test is non-exhaustive, and there may be false-negatives: during the | ||||||||||||||||||
* execution of a contract's constructor, its address will be reported as | ||||||||||||||||||
* not containing a contract. | ||||||||||||||||||
* | ||||||||||||||||||
* > It is unsafe to assume that an address for which this function returns | ||||||||||||||||||
* false is an externally-owned account (EOA) and not a contract. | ||||||||||||||||||
*/ | ||||||||||||||||||
function isContract(address account) internal view returns (bool) { | ||||||||||||||||||
// This method relies in extcodesize, which returns 0 for contracts in | ||||||||||||||||||
// construction, since the code is only stored at the end of the | ||||||||||||||||||
// constructor execution. | ||||||||||||||||||
|
||||||||||||||||||
uint256 size; | ||||||||||||||||||
// solhint-disable-next-line no-inline-assembly | ||||||||||||||||||
assembly { size := extcodesize(account) } | ||||||||||||||||||
return size > 0; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Converts an `address` into `address payable`. Note that this is | ||||||||||||||||||
* simply a type cast: the actual underlying value is not changed. | ||||||||||||||||||
*/ | ||||||||||||||||||
function toPayable(address account) internal pure returns (address payable) { | ||||||||||||||||||
return payable(account); | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
abstract contract IERC223Recipient { | ||||||||||||||||||
/** | ||||||||||||||||||
* @dev Standard ERC223 function that will handle incoming token transfers. | ||||||||||||||||||
* | ||||||||||||||||||
* @param _from Token sender address. | ||||||||||||||||||
* @param _value Amount of tokens. | ||||||||||||||||||
* @param _data Transaction metadata. | ||||||||||||||||||
*/ | ||||||||||||||||||
function tokenReceived(address _from, uint _value, bytes memory _data) public virtual; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @title Reference implementation of the ERC223 standard token. | ||||||||||||||||||
*/ | ||||||||||||||||||
contract ERC223Token { | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Event that is fired on successful transfer. | ||||||||||||||||||
*/ | ||||||||||||||||||
event Transfer(address indexed from, address indexed to, uint value); | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Additional event that is fired on successful transfer and logs transfer metadata, | ||||||||||||||||||
* this event is implemented to keep Transfer event compatible with ERC20. | ||||||||||||||||||
*/ | ||||||||||||||||||
event TransferData(bytes data); | ||||||||||||||||||
|
||||||||||||||||||
string private _name; | ||||||||||||||||||
string private _symbol; | ||||||||||||||||||
uint8 private _decimals; | ||||||||||||||||||
uint256 private _totalSupply; | ||||||||||||||||||
|
||||||||||||||||||
mapping(address => uint256) public balances; // List of user balances. | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with | ||||||||||||||||||
* a default value of 18. | ||||||||||||||||||
* | ||||||||||||||||||
* To select a different value for {decimals}, use {_setupDecimals}. | ||||||||||||||||||
* | ||||||||||||||||||
* All three of these values are immutable: they can only be set once during | ||||||||||||||||||
* construction. | ||||||||||||||||||
*/ | ||||||||||||||||||
|
||||||||||||||||||
constructor(string memory new_name, string memory new_symbol, uint8 new_decimals) | ||||||||||||||||||
{ | ||||||||||||||||||
_name = new_name; | ||||||||||||||||||
_symbol = new_symbol; | ||||||||||||||||||
_decimals = new_decimals; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev ERC223 tokens must explicitly return "erc223" on standard() function call. | ||||||||||||||||||
*/ | ||||||||||||||||||
function standard() public pure returns (string memory) | ||||||||||||||||||
{ | ||||||||||||||||||
return "ERC-223"; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Returns the name of the token. | ||||||||||||||||||
*/ | ||||||||||||||||||
function name() public view returns (string memory) | ||||||||||||||||||
{ | ||||||||||||||||||
return _name; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Returns the symbol of the token, usually a shorter version of the | ||||||||||||||||||
* name. | ||||||||||||||||||
*/ | ||||||||||||||||||
function symbol() public view returns (string memory) | ||||||||||||||||||
{ | ||||||||||||||||||
return _symbol; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Returns the number of decimals used to get its user representation. | ||||||||||||||||||
* For example, if `decimals` equals `2`, a balance of `505` tokens should | ||||||||||||||||||
* be displayed to a user as `5,05` (`505 / 10 ** 2`). | ||||||||||||||||||
* | ||||||||||||||||||
* Tokens usually opt for a value of 18, imitating the relationship between | ||||||||||||||||||
* Ether and Wei. This is the value {ERC223} uses, unless {_setupDecimals} is | ||||||||||||||||||
* called. | ||||||||||||||||||
* | ||||||||||||||||||
* NOTE: This information is only used for _display_ purposes: it in | ||||||||||||||||||
* no way affects any of the arithmetic of the contract, including | ||||||||||||||||||
* {IERC223-balanceOf} and {IERC223-transfer}. | ||||||||||||||||||
*/ | ||||||||||||||||||
function decimals() public view returns (uint8) | ||||||||||||||||||
{ | ||||||||||||||||||
return _decimals; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev See {IERC223-totalSupply}. | ||||||||||||||||||
*/ | ||||||||||||||||||
function totalSupply() public view returns (uint256) | ||||||||||||||||||
{ | ||||||||||||||||||
return _totalSupply; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Returns balance of the `_owner`. | ||||||||||||||||||
* | ||||||||||||||||||
* @param _owner The address whose balance will be returned. | ||||||||||||||||||
* @return balance Balance of the `_owner`. | ||||||||||||||||||
*/ | ||||||||||||||||||
function balanceOf(address _owner) public view returns (uint256) | ||||||||||||||||||
{ | ||||||||||||||||||
return balances[_owner]; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Transfer the specified amount of tokens to the specified address. | ||||||||||||||||||
* Invokes the `tokenFallback` function if the recipient is a contract. | ||||||||||||||||||
* The token transfer fails if the recipient is a contract | ||||||||||||||||||
* but does not implement the `tokenFallback` function | ||||||||||||||||||
* or the fallback function to receive funds. | ||||||||||||||||||
* | ||||||||||||||||||
* @param _to Receiver address. | ||||||||||||||||||
* @param _value Amount of tokens that will be transferred. | ||||||||||||||||||
* @param _data Transaction metadata. | ||||||||||||||||||
*/ | ||||||||||||||||||
function transfer(address _to, uint _value, bytes calldata _data) public returns (bool success) | ||||||||||||||||||
{ | ||||||||||||||||||
// Standard function transfer similar to ERC20 transfer with no _data . | ||||||||||||||||||
// Added due to backwards compatibility reasons . | ||||||||||||||||||
balances[msg.sender] = balances[msg.sender] - _value; | ||||||||||||||||||
balances[_to] = balances[_to] + _value; | ||||||||||||||||||
if(Address.isContract(_to)) { | ||||||||||||||||||
IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data); | ||||||||||||||||||
} | ||||||||||||||||||
emit Transfer(msg.sender, _to, _value); | ||||||||||||||||||
emit TransferData(_data); | ||||||||||||||||||
return true; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* @dev Transfer the specified amount of tokens to the specified address. | ||||||||||||||||||
* This function works the same with the previous one | ||||||||||||||||||
* but doesn't contain `_data` param. | ||||||||||||||||||
* Added due to backwards compatibility reasons. | ||||||||||||||||||
* | ||||||||||||||||||
* @param _to Receiver address. | ||||||||||||||||||
* @param _value Amount of tokens that will be transferred. | ||||||||||||||||||
*/ | ||||||||||||||||||
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(Address.isContract(_to)) { | ||||||||||||||||||
IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty); | ||||||||||||||||||
} | ||||||||||||||||||
emit Transfer(msg.sender, _to, _value); | ||||||||||||||||||
emit TransferData(_empty); | ||||||||||||||||||
return true; | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
## Copyright | ||||||||||||||||||
Dexaran marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to other editors: this eip is resurrecting #223