mirror of https://github.com/status-im/EIPs.git
Automatically merged updates to draft EIP(s) 777
Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing
This commit is contained in:
parent
00fbcbcd0f
commit
e269280362
|
@ -71,13 +71,35 @@ interface ERC777Token {
|
|||
event RevokedOperator(address indexed operator, address indexed tokenHolder);
|
||||
}
|
||||
```
|
||||
The token contract MUST implement the above interface. The implementation MUST follow the specifications described below.
|
||||
The token contract MUST implement the above interface.
|
||||
The implementation MUST follow the specifications described below.
|
||||
|
||||
The token contract MUST register the `ERC777Token` interface with its own address via [ERC1820]. If the contract has a switch to enable or disable [ERC777] functions, every time the switch is triggered, the token MUST register or unregister the `ERC777Token` interface for its own address accordingly via [ERC1820]. (Unregistering implies setting the address to `0x0`.)
|
||||
The token contract MUST register the `ERC777Token` interface with its own address via [ERC1820].
|
||||
This is done by calling the `setInterfaceImplementer` function on the ERC1820 registry
|
||||
with the token contract address as both the address and the implementer
|
||||
and the `keccak256` hash of `ERC777Token` as the interface hash.
|
||||
|
||||
The smallest unit—for all interactions with the token contract—MUST be `1`. I.e. all amounts and balances MUST be unsigned integers. The display denomination—to display any amount to the end user—MUST be 10<sup>18</sup> of the smallest.
|
||||
If the contract has a switch to enable or disable ERC777 functions, every time the switch is triggered,
|
||||
the token MUST register or unregister the `ERC777Token` interface for its own address accordingly via ERC1820.
|
||||
Unregistering implies calling the `setInterfaceImplementer` with the token contract address as the address,
|
||||
the `keccak256` hash of `ERC777Token` as the interface hash and `0x0` as the implementer.
|
||||
(See [Set An Interface For An Address][erc1820-set] in [ERC1820] for more details.)
|
||||
|
||||
In other words the technical denomination is similar to a wei and the display denomination is similar to an ether. It is equivalent to an [ERC20]'s `decimals` function returning `18`. E.g. if a token contract holds a balance of `500,000,000,000,000,000` (0.5×10<sup>18</sup>) for a user, the user interface SHOULD show `0.5` tokens to the user. If the user wishes to send `0.3` tokens, the contract MUST be called with an amount of `300,000,000,000,000,000` (0.3×10<sup>18</sup>).
|
||||
When interacting with the token contract, all amounts and balances MUST be unsigned integers.
|
||||
I.e. Internally, all values are stored as a denomination of 1E-18 of a token.
|
||||
The display denomination—to display any amount to the end user—MUST be 10<sup>18</sup> of the internal denomination.
|
||||
|
||||
In other words, the internal denomination is similar to a wei
|
||||
and the display denomination is similar to an ether.
|
||||
It is equivalent to an [ERC20]'s `decimals` function returning `18`.
|
||||
E.g. if a token contract returns a balance of `500,000,000,000,000,000` (0.5×10<sup>18</sup>) for a user,
|
||||
the user interface MUST show `0.5` tokens to the user.
|
||||
If the user wishes to send `0.3` tokens,
|
||||
the contract MUST be called with an amount of `300,000,000,000,000,000` (0.3×10<sup>18</sup>).
|
||||
|
||||
User Interfaces which are generated programmatically from the ABI of the token contract
|
||||
MAY use and display the internal denomination.
|
||||
But this MUST be made clear, for example by displaying the `uint256` type.
|
||||
|
||||
#### **View Functions**
|
||||
|
||||
|
@ -89,7 +111,7 @@ The `view` functions detailed below MUST be implemented.
|
|||
function name() external view returns (string)
|
||||
```
|
||||
|
||||
Returns the name of the token, e.g., `"MyToken"`.
|
||||
Get the name of the token, e.g., `"MyToken"`.
|
||||
|
||||
> <small>**returns:** Name of the token.</small>
|
||||
|
||||
|
@ -99,7 +121,7 @@ Returns the name of the token, e.g., `"MyToken"`.
|
|||
function symbol() external view returns (string)
|
||||
```
|
||||
|
||||
Returns the symbol of the token, e.g., `"MYT"`.
|
||||
Get the symbol of the token, e.g., `"MYT"`.
|
||||
|
||||
> <small>**returns:** Symbol of the token.</small>
|
||||
|
||||
|
@ -113,7 +135,7 @@ Get the total number of minted tokens.
|
|||
|
||||
*NOTE*: The total supply MUST be equal to the sum of the balances of all addresses—as returned by the `balanceOf` function.
|
||||
|
||||
*NOTE*: The total supply MUST be equal to the sum of all the minted tokens as defined in all the `Minted` events minus the sum of all the burned tokens as defined in all the `Burned` events. (This applies as well to [tokens minted when the token contract is created][initial supply].)
|
||||
*NOTE*: The total supply MUST be equal to the sum of all the minted tokens as defined in all the `Minted` events minus the sum of all the burned tokens as defined in all the `Burned` events.
|
||||
|
||||
|
||||
> <small>**returns:** Total supply of tokens currently in circulation.</small>
|
||||
|
@ -131,7 +153,7 @@ The balance MUST be zero (`0`) or higher.
|
|||
> <small>**parameters**</small>
|
||||
> <small>`tokenHolder`: Address for which the balance is returned.</small>
|
||||
>
|
||||
> <small>**returns:** Amount of token held by `tokenHolder` in the token contract.</small>
|
||||
> <small>**returns:** Amount of tokens held by `tokenHolder` in the token contract.</small>
|
||||
|
||||
**`granularity` function**
|
||||
|
||||
|
@ -158,14 +180,11 @@ The following rules MUST be applied regarding the *granularity*:
|
|||
*NOTE*: [`defaultOperators`][defaultOperators] and [`isOperatorFor`][isOperatorFor] are also `view` functions, defined under the [operators] for consistency.
|
||||
|
||||
*[ERC20] compatibility requirement*:
|
||||
The decimals of the token MUST always be `18`. For a *pure* ERC777 token the [ERC20] `decimal` function is OPTIONAL, and its existence SHALL NOT be relied upon when interacting with the token contract. (The decimal value of `18` is implied.) For an [ERC20] compatible token, the `decimal` function is REQUIRED and MUST return `18`. (In [ERC20], the `decimals` function is OPTIONAL. If the function is not present, the `decimals` value is not clearly defined and may be assumed to be `0`. Hence for compatibility reasons, `decimals` MUST be implemented for [ERC20] compatible tokens.)
|
||||
|
||||
*[ERC20] compatibility requirement*:
|
||||
The `name`, `symbol`, `totalSupply`, and `balanceOf` `view` functions MUST be backward compatible with [ERC20].
|
||||
The decimals of the token MUST always be `18`. For a *pure* ERC777 token the [ERC20] `decimals` function is OPTIONAL, and its existence SHALL NOT be relied upon when interacting with the token contract. (The decimal value of `18` is implied.) For an [ERC20] compatible token, the `decimals` function is REQUIRED and MUST return `18`. (In [ERC20], the `decimals` function is OPTIONAL. If the function is not present, the `decimals` value is not clearly defined and may be assumed to be `0`. Hence for compatibility reasons, `decimals` MUST be implemented for [ERC20] compatible tokens.)
|
||||
|
||||
#### **Operators**
|
||||
|
||||
An `operator` is an address which is allowed to send and burn tokens on behalf of another address.
|
||||
An `operator` is an address which is allowed to send and burn tokens on behalf of some *token holder*.
|
||||
|
||||
When an address becomes an *operator* for a *token holder*, an `AuthorizedOperator` event MUST be emitted. The `AuthorizedOperator`'s `operator` (topic 1) and `tokenHolder` (topic 2) MUST be the addresses of the *operator* and the *token holder* respectively.
|
||||
|
||||
|
@ -194,8 +213,6 @@ The following rules apply to any *operator*:
|
|||
|
||||
*NOTE*: A *token holder* MAY revoke an already revoked *operator*. A `RevokedOperator` MUST be emitted each time.
|
||||
|
||||
*NOTE*: A token holder MAY have multiple *operators* at the same time.
|
||||
|
||||
**`AuthorizedOperator` event** <a id="authorizedoperator"></a>
|
||||
|
||||
``` solidity
|
||||
|
@ -286,7 +303,7 @@ Indicate whether the `operator` address is an *operator* of the `tokenHolder` ad
|
|||
|
||||
When an *operator* sends an `amount` of tokens from a *token holder* to a *recipient* with the associated `data` and `operatorData`, the token contract MUST apply the following rules:
|
||||
|
||||
- Any *token holder* MAY send tokens to any *recipient*.
|
||||
- Any authorized *operator* MAY send tokens to any *recipient* (except to `0x0`).
|
||||
- The balance of the *token holder* MUST be decreased by the `amount`.
|
||||
- The balance of the *recipient* MUST be increased by the `amount`.
|
||||
- The balance of the *token holder* MUST be greater or equal to the `amount`—such that its resulting balance is greater or equal to zero (`0`) after the send.
|
||||
|
@ -300,6 +317,7 @@ The token contract MUST `revert` when sending in any of the following cases:
|
|||
|
||||
- The *operator* address is not an authorized operator for the *token holder*.
|
||||
- The resulting *token holder* balance or *recipient* balance after the send is not a multiple of the *granularity* defined by the token contract.
|
||||
- The *recipient* is a contract, and it does not implement the `ERC777TokensRecipient` interface via [ERC1820].
|
||||
- The address of the *token holder* or the *recipient* is `0x0`.
|
||||
- Any of the resulting balances becomes negative, i.e. becomes less than zero (`0`).
|
||||
|
||||
|
@ -329,7 +347,7 @@ MAY use the information to decide if they wish to reject the transaction.
|
|||
|
||||
*NOTE*: The `operatorData` field is analogous to the `data` field except it SHALL be provided by the *operator*.
|
||||
|
||||
Typically, `data` is used to describe the intent behind the send. The `operatorData` MUST only be provided by the *operator*. It is intended more for logging purposes and particular cases. (Examples include payment references, cheque numbers, countersignatures and more.) In most of the cases the recipient would ignore the `operatorData`, or at most, it would log the `operatorData`.
|
||||
The `operatorData` MUST only be provided by the *operator*. It is intended more for logging purposes and particular cases. (Examples include payment references, cheque numbers, countersignatures and more.) In most of the cases the recipient would ignore the `operatorData`, or at most, it would log the `operatorData`.
|
||||
|
||||
**`Sent` event** <a id="sent"></a>
|
||||
|
||||
|
@ -352,8 +370,6 @@ Indicate a send of `amount` of tokens from the `from` address to the `to` addres
|
|||
The `send` and `operatorSend` functions described below MUST be implemented to send tokens.
|
||||
Token contracts MAY implement other functions to send tokens.
|
||||
|
||||
*NOTE*: An address MAY send an amount of `0`, which is valid and MUST be treated as a regular send.
|
||||
|
||||
**`send` function**
|
||||
|
||||
``` solidity
|
||||
|
@ -411,7 +427,6 @@ The token contract MUST `revert` when minting in any of the following cases:
|
|||
- The *recipient* is a contract, and it does not implement the `ERC777TokensRecipient` interface via [ERC1820].
|
||||
- The address of the *recipient* is `0x0`.
|
||||
|
||||
<a id="initialSupply"></a>
|
||||
*NOTE*: The initial token supply at the creation of the token contract MUST be considered as minting for the amount of the initial supply to the address(es) receiving the initial supply. This means one or more `Minted` events must be emitted and the `tokensReceived` hook of the recipient(s) MUST be called.
|
||||
|
||||
*[ERC20] compatibility requirement*:
|
||||
|
@ -430,7 +445,6 @@ The token contract MAY mint tokens for multiple *recipients* at once. In this ca
|
|||
to the data field in a regular ether send transaction.
|
||||
The `tokensReceived()` hooks MAY use the information to decide if it wish to reject the transaction.
|
||||
|
||||
|
||||
**`Minted` event** <a id="minted"></a>
|
||||
|
||||
``` solidity
|
||||
|
@ -664,6 +678,7 @@ The following rules apply when calling the `tokensReceived` hook:
|
|||
This hook takes precedence over [ERC20] and MUST be called (if registered) when calling [ERC20]'s `transfer` and `transferFrom` event. When called from a `transfer`, `operator` MUST be the same value as the `from`. When called from a `transferFrom`, `operator` MUST be the address which issued the `transferFrom` call.
|
||||
|
||||
#### **Note On Gas Consumption**
|
||||
|
||||
Dapps and wallets SHOULD first estimate the gas required when sending, minting, or burning tokens—using [`eth_estimateGas`][eth_estimateGas]—to avoid running out of gas during the transaction.
|
||||
|
||||
### Logo
|
||||
|
@ -697,11 +712,21 @@ This standard allows the implementation of [ERC20] functions `transfer`, `transf
|
|||
|
||||
The token MAY implement `decimals()` for backward compatibility with [ERC20]. If implemented, it MUST always return `18`.
|
||||
|
||||
Therefore a token contract MAY implement both [ERC20] and [ERC777] in parallel. The specification of the `view` functions (such as `name`, `symbol`, `balanceOf`, `totalSupply`) and internal data (such as the mapping of balances) overlap without problems. Note however that the following functions are mandatory in [ERC777] and MUST be implemented: `name`, `symbol` `balanceOf` and `totalSupply` (`decimal` is not part of the [ERC777] standard).
|
||||
Therefore a token contract MAY implement both [ERC20] and [ERC777] in parallel. The specification of the `view` functions (such as `name`, `symbol`, `balanceOf`, `totalSupply`) and internal data (such as the mapping of balances) overlap without problems. Note however that the following functions are mandatory in [ERC777] and MUST be implemented: `name`, `symbol` `balanceOf` and `totalSupply` (`decimals` is not part of the [ERC777] standard).
|
||||
|
||||
The state-modifying functions from both standards are decoupled and can operate independently from each other. Note that [ERC20] functions SHOULD be limited to only being called from old contracts.
|
||||
|
||||
If the token implements [ERC20], it MUST register the `ERC20Token` interface with its own address via [ERC1820]. If the contract has a switch to enable or disable [ERC20] functions, every time the switch is triggered, the token MUST register or unregister its own address accordingly the `ERC20Token` interface via [ERC1820]. (Unregistering implies setting the address to `0x0`.)
|
||||
If the token implements [ERC20],
|
||||
it MUST register the `ERC20Token` interface with its own address via [ERC1820].
|
||||
This is done by calling the `setInterfaceImplementer` function on the ERC1820 registry
|
||||
with the token contract address as both the address and the implementer
|
||||
and the `keccak256` hash of `ERC20Token` as the interface hash.
|
||||
|
||||
If the contract has a switch to enable or disable ERC20 functions, every time the switch is triggered,
|
||||
the token MUST register or unregister the `ERC20Token` interface for its own address accordingly via ERC1820.
|
||||
Unregistering implies calling the `setInterfaceImplementer` with the token contract address as the address,
|
||||
the `keccak256` hash of `ERC20Token` as the interface hash and `0x0` as the implementer.
|
||||
(See [Set An Interface For An Address][erc1820-set] in [ERC1820] for more details.)
|
||||
|
||||
The difference for new contracts implementing [ERC20] is that `tokensToSend` and `tokensReceived` hooks take precedence over [ERC20]. Even with an [ERC20] `transfer` and `transferFrom` call, the token contract MUST check via [ERC1820] if the `from` and the `to` address implement `tokensToSend` and `tokensReceived` hook respectively. If any hook is implemented, it MUST be called. Note that when calling [ERC20] `transfer` on a contract, if the contract does not implement `tokensReceived`, the `transfer` call SHOULD still be accepted even if this means the tokens will probably be locked.
|
||||
|
||||
|
@ -766,6 +791,7 @@ Copyright and related rights waived via [CC0].
|
|||
[ERC20]: https://eips.ethereum.org/EIPS/eip-20
|
||||
[ERC777]: https://eips.ethereum.org/EIPS/eip-777
|
||||
[ERC1820]: https://eips.ethereum.org/EIPS/eip-1820
|
||||
[erc1820-set]: https://eips.ethereum.org/EIPS/eip-1820#set-an-interface-for-an-address
|
||||
[0xjac/ERC777]: https://github.com/0xjac/ERC777
|
||||
[npm/erc777]: https://www.npmjs.com/package/erc777
|
||||
[ref tests]: https://github.com/0xjac/ERC777/blob/master/test/ReferenceToken.test.js
|
||||
|
@ -780,7 +806,6 @@ Copyright and related rights waived via [CC0].
|
|||
[sent]: #sent
|
||||
[minted]: #minted
|
||||
[burned]: #burned
|
||||
[initial supply]: #initialSupply
|
||||
|
||||
[logos]: https://github.com/ethereum/EIPs/tree/master/assets/eip-777/logo
|
||||
[beige logo]: ../assets/eip-777/logo/png/ERC-777-logo-beige-48px.png
|
||||
|
|
Loading…
Reference in New Issue