mirror of https://github.com/status-im/EIPs.git
Automatically merged updates to draft EIP(s) 1155 (#2049)
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
9ed4e96857
commit
5e6d4885f9
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
eip: 1155
|
||||
title: ERC-1155 Multi Token Standard
|
||||
author: Witek Radomski <witek@enjin.com>, Andrew Cooke <ac0dem0nk3y@gmail.com>, Philippe Castonguay <pc@horizongames.net>, James Therien <james@turing-complete.com>, Eric Binet <eric@enjin.com>
|
||||
author: Witek Radomski <witek@enjin.com>, Andrew Cooke <ac0dem0nk3y@gmail.com>, Philippe Castonguay <pc@horizongames.net>, James Therien <james@turing-complete.com>, Eric Binet <eric@enjin.com>, Ronan Sandford <wighawag@gmail.com>
|
||||
type: Standards Track
|
||||
category: ERC
|
||||
status: Draft
|
||||
|
@ -13,7 +13,7 @@ requires: 165
|
|||
|
||||
## Simple Summary
|
||||
|
||||
A standard interface for contracts that manage multiple token types. A single deployed contract may include any combination of fungible tokens, non-fungible tokens, or other configurations (for example, semi-fungible tokens).
|
||||
A standard interface for contracts that manage multiple token types. A single deployed contract may include any combination of fungible tokens, non-fungible tokens, or other configurations (e.g. semi-fungible tokens).
|
||||
|
||||
## Abstract
|
||||
|
||||
|
@ -84,13 +84,13 @@ interface ERC1155 /* is ERC165 */ {
|
|||
MUST revert if `_to` is the zero address.
|
||||
MUST revert if balance of holder for token `_id` is lower than the `_value` sent.
|
||||
MUST revert on any other error.
|
||||
After the above conditions are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
|
||||
MUST emit `TransferSingle` event on transfer success (see "Safe Transfer Rules" section of the standard).
|
||||
MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard).
|
||||
After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
|
||||
@param _from Source address
|
||||
@param _to Target address
|
||||
@param _id ID of the token type
|
||||
@param _value Transfer amount
|
||||
@param _data Additional data with no specified format, MUST be sent in call to `onERC1155Received` on `_to`
|
||||
@param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
|
||||
*/
|
||||
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;
|
||||
|
||||
|
@ -100,15 +100,15 @@ interface ERC1155 /* is ERC165 */ {
|
|||
MUST revert if `_to` is the zero address.
|
||||
MUST revert if length of `_ids` is not the same as length of `_values`.
|
||||
MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
|
||||
MUST revert on any other error.
|
||||
Transfers and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
|
||||
After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
|
||||
MUST emit `TransferSingle` or `TransferBatch` event(s) on transfer success (see "Safe Transfer Rules" section of the standard).
|
||||
MUST revert on any other error.
|
||||
MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard).
|
||||
Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
|
||||
After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
|
||||
@param _from Source address
|
||||
@param _to Target address
|
||||
@param _ids IDs of each token type (order and length must match _values array)
|
||||
@param _values Transfer amounts per token type (order and length must match _ids array)
|
||||
@param _data Additional data with no specified format, MUST be sent in call to the `ERC1155TokenReceiver` hook(s) on `_to`
|
||||
@param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`
|
||||
*/
|
||||
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external;
|
||||
|
||||
|
@ -193,13 +193,13 @@ interface ERC1155TokenReceiver {
|
|||
This function MUST NOT consume more than 5,000 gas.
|
||||
@return `bytes4(keccak256("isERC1155TokenReceiver()"))`
|
||||
*/
|
||||
function isERC1155TokenReceiver() external pure returns (bytes4);
|
||||
function isERC1155TokenReceiver() external view returns (bytes4);
|
||||
}
|
||||
```
|
||||
|
||||
### Safe Transfer Rules
|
||||
|
||||
To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST operate with respect to the `ERC1155TokenReceiver`, a list of scenarios and rules follows.
|
||||
To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST operate with respect to the `ERC1155TokenReceiver` hook functions, a list of scenarios and rules follows.
|
||||
|
||||
#### Scenarios
|
||||
|
||||
|
@ -219,22 +219,30 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
|
|||
**_Scenario#5 :_** The receiver implements the necessary `ERC1155TokenReceiver` interface function(s) but throws an error.
|
||||
* The transfer MUST be reverted.
|
||||
|
||||
**_Scenario#6 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of one and only one balance change (eg. safeTransferFrom called).
|
||||
**_Scenario#6 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of one and only one balance change (e.g. safeTransferFrom called).
|
||||
* All the balances in the transfer MUST have been updated to match the senders intent before any hook is called on a recipient.
|
||||
* All the transfer events for the transfer MUST have been emitted to reflect the balance changes before any hook is called on a recipient.
|
||||
* One of `onERC1155Received` or `onERC1155BatchReceived` MUST be called on the recipient.
|
||||
* The `onERC1155Received` hook SHOULD be called on the recipient contract and its rules followed.
|
||||
- See "onERC1155Received rules" for further rules that MUST be followed.
|
||||
* The `onERC1155BatchReceived` hook MAY be called on the recipient contract and its rules followed.
|
||||
- See "onERC1155BatchReceived rules" for further rules that MUST be followed.
|
||||
|
||||
**_Scenario#7 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of more than one balance change (eg. safeBatchTransferFrom called).
|
||||
**_Scenario#7 :_** The receiver implements the `ERC1155TokenReceiver` interface and is the recipient of more than one balance change (e.g. safeBatchTransferFrom called).
|
||||
* All the balances in the transfer MUST have been updated to match the senders intent before any hook is called on a recipient.
|
||||
* All the transfer events for the transfer MUST have been emitted to reflect the balance changes before any hook is called on a recipient.
|
||||
* `onERC1155Received` or `onERC1155BatchReceived` MUST be called on the recipient as many times as necessary such that every balance change for the recipient in the scenario is accounted for.
|
||||
- The return magic value for every hook call MUST be checked and acted upon as per "onERC1155Received rules" and "onERC1155BatchReceived rules".
|
||||
* The `onERC1155BatchReceived` hook SHOULD be called on the recipient contract and its rules followed.
|
||||
- See "onERC1155BatchReceived rules" for further rules that MUST be followed.
|
||||
* The `onERC1155Received` hook MAY be called on the recipient contract and its rules followed.
|
||||
- See "onERC1155Received rules" for further rules that MUST be followed.
|
||||
|
||||
**_Scenario#8 :_** You are the creator of a contract that implements the `ERC1155TokenReceiver` interface and you forward the token(s) onto another address in one or both of `onERC1155Received` and `onERC1155BatchReceived`.
|
||||
* Forwarding should be considered acceptance and then initiating a new `safeTransferFrom` or `safeBatchTransferFrom` in a new context.
|
||||
- The prescribed keccak256 acceptance value magic for the receiver hook being called MUST be returned after forwarding is successful.
|
||||
* The `_data` argument MAY be re-purposed for the new context.
|
||||
* If forwarding unexpectedly fails the transaction MUST be reverted.
|
||||
|
||||
#### Rules
|
||||
|
||||
|
@ -243,8 +251,8 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
|
|||
* MUST revert if `_to` is the zero address.
|
||||
* MUST revert if balance of holder for token `_id` is lower than the `_value` sent to the recipient.
|
||||
* MUST revert on any other error.
|
||||
* After the above conditions are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "onERC1155Received rules" section).
|
||||
* MUST emit `TransferSingle` event on transfer success (see "TransferSingle and TransferBatch event rules" section).
|
||||
* MUST emit the `TransferSingle` event to reflect the balance change (see "TransferSingle and TransferBatch event rules" section).
|
||||
* After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "onERC1155Received rules" section).
|
||||
|
||||
**_safeBatchTransferFrom rules:_**
|
||||
* Caller must be approved to manage all the tokens being transferred out of the `_from` account (see "Approval" section).
|
||||
|
@ -252,9 +260,9 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
|
|||
* MUST revert if length of `_ids` is not the same as length of `_values`.
|
||||
* MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
|
||||
* MUST revert on any other error.
|
||||
* After the above conditions are met, this function MUST check if `_to` is a smart contract (eg. code size > 0). If so, it MUST call `onERC1155Received` or `onERC1155BatchReceived` on `_to` and act appropriately (see "`onERC1155Received` and onERC1155BatchReceived rules" section).
|
||||
* MUST emit `TransferSingle` or `TransferBatch` event(s) on transfer success (see "TransferSingle and TransferBatch event rules" section).
|
||||
* Transfers and events MUST occur in the array order they were submitted (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
|
||||
* MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "TransferSingle and TransferBatch event rules" section).
|
||||
* The balance changes and events MUST occur in the array order they were submitted (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
|
||||
* After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` or `onERC1155BatchReceived` on `_to` and act appropriately (see "`onERC1155Received` and onERC1155BatchReceived rules" section).
|
||||
|
||||
**_TransferSingle and TransferBatch event rules:_**
|
||||
* `TransferSingle` SHOULD be used to indicate a single balance transfer has occurred between a `_from` and `_to` pair.
|
||||
|
@ -278,6 +286,8 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
|
|||
- When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
|
||||
* The total value transferred from address 0x0 minus the total value transferred to 0x0 MAY be used by clients and exchanges to be added to the "circulating supply" for a given token ID.
|
||||
* To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the `TransferSingle` event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_value` of 0.
|
||||
* All `TransferSingle` and `TransferBatch` events MUST be emitted to reflect all the balance changes that have occurred before any call(s) to `onERC1155Received` or `onERC1155BatchReceived`.
|
||||
- To make sure event order is correct in the case of valid re-entry (e.g. if a receiver contract forwards tokens on receipt) state balance and events balance MUST match before calling an external contract.
|
||||
|
||||
**_onERC1155Received rules:_**
|
||||
* The `_operator` argument MUST be the address of the account/contract that initiated the transfer (i.e. msg.sender).
|
||||
|
@ -285,7 +295,8 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
|
|||
- `_from` MUST be 0x0 for a mint.
|
||||
* The `_id` argument MUST be the token type being transferred.
|
||||
* The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.
|
||||
* The `_data` argument MUST contain the extra information provided by the sender for the transfer.
|
||||
* The `_data` argument MUST contain the unaltered information provided by the sender for the transfer.
|
||||
- i.e. it MUST pass on the unaltered `_data` argument sent via the `safeTransferFrom` or `safeBatchTransferFrom` call for this transfer.
|
||||
* The recipient contract MAY accept an increase of its balance by returning the acceptance magic value `bytes4(keccak256("accept_erc1155_tokens()"))`
|
||||
- If the return value is `bytes4(keccak256("accept_erc1155_tokens()"))` the transfer MUST be completed or MUST revert if any other conditions are not met for success.
|
||||
* The recipient contract MAY reject an increase of its balance by calling revert.
|
||||
|
@ -301,7 +312,8 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
|
|||
- `_from` MUST be 0x0 for a mint.
|
||||
* The `_ids` argument MUST be the list of tokens being transferred.
|
||||
* The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in `_ids`) the holder balance is decreased by and match what the recipient balance is increased by.
|
||||
* The `_data` argument MUST contain the information provided by the sender for a transfer.
|
||||
* The `_data` argument MUST contain the unaltered information provided by the sender for the transfer.
|
||||
- i.e. it MUST pass on the unaltered `_data` argument sent via the `safeTransferFrom` or `safeBatchTransferFrom` call for this transfer.
|
||||
* The recipient contract MAY accept an increase of its balance by returning the acceptance magic value `bytes4(keccak256("accept_batch_erc1155_tokens()"))`
|
||||
- If the return value is `bytes4(keccak256("accept_batch_erc1155_tokens()"))` the transfer MUST be completed or MUST revert if any other conditions are not met for success.
|
||||
* The recipient contract MAY reject an increase of its balance by calling revert.
|
||||
|
@ -314,7 +326,7 @@ To be more explicit about how safeTransferFrom and safeBatchTransferFrom MUST op
|
|||
**_isERC1155TokenReceiver rules:_**
|
||||
* The implementation of `isERC1155TokenReceiver` function SHOULD be as follows:
|
||||
```
|
||||
function isERC1155TokenReceiver() external pure returns (bytes4) {
|
||||
function isERC1155TokenReceiver() external view returns (bytes4) {
|
||||
return 0x0d912442; // bytes4(keccak256("isERC1155TokenReceiver()"))
|
||||
}
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue