mirror of
https://github.com/status-im/EIPs.git
synced 2025-02-25 13:15:44 +00:00
Automatically merged updates to draft EIP(s) 1155
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
5d5db7bc66
commit
5ace6aa0f4
426
EIPS/eip-1155.md
426
EIPS/eip-1155.md
@ -15,9 +15,9 @@ A standard interface for multiple item/token definitions in a single deployed co
|
||||
|
||||
## Abstract
|
||||
|
||||
This standard proposes a new monolithic token contract that can mint any quantity of Fungible and Non-Fungible tokens in the same contract. We call these "Items" as they differ from the existing standards by being full definitions and configurations of multiple tokens inside a single contract. Standards like ERC-20 require deployment of separate contracts per token. The ERC-721 standard's Token ID is a single non-fungible index and the group of these non-fungibles is deployed as a single contract with settings for the entire collection. Instead, the Crypto Item Standard allows for each Item ID to represent a new configurable token type, which may have its own totalSupply value and other such attributes.
|
||||
This standard outlines a smart contract interface where one can represent any number of Fungible and Non-Fungible assets in a single contract. Existing standards such as ERC-20 require deployment of separate contracts per token. The ERC-721 standard's Token ID is a single non-fungible index and the group of these non-fungibles is deployed as a single contract with settings for the entire collection. Instead, the ERC-1155 Crypto Item Standard allows for each Item ID to represent a new configurable token type, which may have its own totalSupply value and other such attributes.
|
||||
|
||||
The `_itemId` parameter is named as such and placed at the beginning of each function.
|
||||
The `_id` parameter is contained in each function's parameters and indicates a specific item or item type in a transaction.
|
||||
|
||||
## Motivation
|
||||
|
||||
@ -27,126 +27,305 @@ New functionality is possible with this design, such as transferring or approvin
|
||||
|
||||
## Specification
|
||||
|
||||
```
|
||||
solidity
|
||||
interface ICryptoItems {
|
||||
// Events
|
||||
event Transfer(uint256 indexed _itemId, address indexed _from, address indexed _to, uint256 _value);
|
||||
event Approval(uint256 indexed _itemId, address indexed _owner, address indexed _spender, uint256 _value);
|
||||
```solidity
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
// Required Functions
|
||||
function transfer(uint256[] _itemId, address[] _to, uint256[] _value) external returns (bool success);
|
||||
function transferFrom(uint256[] _itemId, address[] _from, address[] _to, uint256[] _value) external returns (bool success);
|
||||
function approve(uint256[] _itemId, address[] _spender, uint256[] _value) external returns (bool success);
|
||||
function increaseApproval(uint256[] _itemId, address[] _spender, uint256[] _addedValue) external returns (bool success);
|
||||
function decreaseApproval(uint256[] _itemId, address[] _spender, uint256[] _subtractedValue) external returns (bool success);
|
||||
/**
|
||||
@title ERC-1155 Crypto Items Standard
|
||||
@dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
|
||||
Note: the ERC-165 identifier for this interface is 0xf23a6e61.
|
||||
*/
|
||||
interface IERC1155 {
|
||||
/**
|
||||
@dev MUST trigger on any successful call to approve(address _spender, uint256 _value)
|
||||
*/
|
||||
event Approval(address indexed _owner, address indexed _spender, uint256 indexed _id, uint256 _oldValue, uint256 _value);
|
||||
|
||||
/**
|
||||
@dev MUST trigger when tokens are transferred, including zero value transfers
|
||||
This emits when ownership of any NFT changes by any mechanism.
|
||||
This event emits when NFTs are created (`from` == 0) and destroyed
|
||||
(`to` == 0). Exception: during contract creation, any number of NFTs
|
||||
may be created and assigned without emitting Transfer. At the time of
|
||||
any transfer, the approved address for that NFT (if any) is reset to none.
|
||||
*/
|
||||
event Transfer(address _spender, address indexed _from, address indexed _to, uint256 indexed _id, uint256 _value);
|
||||
|
||||
// Required View Functions
|
||||
function totalSupply(uint256 _itemId) external view returns (uint256);
|
||||
function balanceOf(uint256 _itemId, address _owner) external view returns (uint256);
|
||||
function allowance(uint256 _itemId, address _owner, address _spender) external view returns (uint256);
|
||||
|
||||
// Optional View Functions
|
||||
function name(uint256 _itemId) external view returns (string);
|
||||
function symbol(uint256 _itemId) external view returns (string);
|
||||
function decimals(uint256 _itemId) external view returns (uint8);
|
||||
|
||||
// Optional Functions for Non-Fungible Items
|
||||
function ownerOf(uint256 _itemId) external view returns (address);
|
||||
function itemURI(uint256 _itemId) external view returns (string);
|
||||
function itemByIndex(uint256 _itemId, uint256 _index) external view returns (uint256);
|
||||
function itemOfOwnerByIndex(uint256 _itemId, address _owner, uint256 _index) external view returns (uint256);
|
||||
/**
|
||||
@dev Transfers value amount of an _id from the _from address to the _to addresses specified. Each parameter array should be the same length, with each index correlating.
|
||||
Caller must have a sufficient allowance by _from for the _id/_value pair
|
||||
@param _from source addresses
|
||||
@param _to target addresses
|
||||
@param _id ID of the CryptoItem
|
||||
@param _value transfer amounts
|
||||
*/
|
||||
function transferFrom(address _from, address _to, uint256 _id, uint256 _value) external;
|
||||
|
||||
/**
|
||||
@dev Transfers value amount of an _id from the _from address to the _to addresses specified. Each parameter array should be the same length, with each index correlating.
|
||||
Caller must have a sufficient allowance by _from for the _id/_value pair
|
||||
Throws if `_to` is the zero address.
|
||||
Throws if `_id` is not a valid NFT.
|
||||
When transfer is complete, this function checks if `_to` is a smart contract (code size > 0). If so, it calls `onERC1155Received` on `_to` and throws if the return value is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
|
||||
@param _from source addresses
|
||||
@param _to target addresses
|
||||
@param _id ID of the CryptoItem
|
||||
@param _value transfer amounts
|
||||
@param _data Additional data with no specified format, sent in call to `_to`
|
||||
*/
|
||||
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes _data) external;
|
||||
|
||||
/**
|
||||
@dev Allow other accounts/contracts to spend tokens on behalf of msg.sender
|
||||
Also, to minimize the risk of the approve/transferFrom attack vector
|
||||
(see https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/), this function will throw if the current approved allowance does not equal the expected _currentValue, unless _value is 0
|
||||
@param _spender Address to approve
|
||||
@param _id ID of the CryptoItem
|
||||
@param _currentValue Expected current value of approved allowance.
|
||||
@param _value Allowance amount
|
||||
*/
|
||||
function approve(address _spender, uint256 _id, uint256 _currentValue, uint256 _value) external;
|
||||
|
||||
/**
|
||||
@dev Get the balance of an account's CryptoItems
|
||||
@param _id ID of the CryptoItem
|
||||
@param _owner The address of the token holder
|
||||
@return The _owner's balance of the CryptoItem type requested
|
||||
*/
|
||||
function balanceOf(uint256 _id, address _owner) external view returns (uint256);
|
||||
|
||||
/**
|
||||
@dev Queries the spending limit approved for an account
|
||||
@param _id ID of the CryptoItem
|
||||
@param _owner The owner allowing the spending
|
||||
@param _spender The address allowed to spend.
|
||||
@return The _spender's allowed spending balance of the CryptoItem requested
|
||||
*/
|
||||
function allowance(uint256 _id, address _owner, address _spender) external view returns (uint256);
|
||||
}
|
||||
```
|
||||
|
||||
### transfer
|
||||
<details>
|
||||
<summary>
|
||||
Simple/Extended Transfers</summary>
|
||||
|
||||
Transfers quantities of each `_itemId[]` to the addresses specified.
|
||||
Each parameter array should be the same length, with each index correlating.
|
||||
```solidity
|
||||
interface IERC1155Extended {
|
||||
/**
|
||||
@dev Send a single type of CryptoItem
|
||||
@param _to Transfer destination address
|
||||
@param _id ID of the CryptoItem
|
||||
@param _value Transfer amount
|
||||
*/
|
||||
function transfer(address _to, uint256 _id, uint256 _value) external;
|
||||
|
||||
/**
|
||||
@dev Send a single type of CryptoItem (with safety call)
|
||||
@param _to Transfer destination address
|
||||
@param _id ID of the CryptoItem
|
||||
@param _value Transfer amount
|
||||
@param _data Additional data with no specified format, sent in call to `_to`
|
||||
*/
|
||||
function safeTransfer(address _to, uint256 _id, uint256 _value, bytes _data) external;
|
||||
}
|
||||
```
|
||||
|
||||
MUST trigger `Transfer` event.
|
||||
</details>
|
||||
|
||||
### transferFrom
|
||||
<details>
|
||||
<summary>
|
||||
Batch Transfers</summary>
|
||||
|
||||
Transfers quantities of each `_itemId[]` from one or more `_from[]` addresses to the `_to[]` addresses specified.
|
||||
Each parameter array should be the same length, with each index correlating.
|
||||
```solidity
|
||||
interface IERC1155BatchTransfer {
|
||||
/**
|
||||
@dev Send multiple types of CryptoItems from a 3rd party in one transfer
|
||||
For the purpose of transfer fees, each id/value pair is counted as a transfer
|
||||
Caller must have a sufficient allowance by _from for each of the _id/_value pairs
|
||||
Throws on any error rather than return a false flag to minimize user errors
|
||||
@param _from Source address
|
||||
@param _to Target address
|
||||
@param _ids Types of CryptoItems
|
||||
@param _values Transfer amounts per item type
|
||||
*/
|
||||
function batchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values) external;
|
||||
|
||||
/**
|
||||
@dev Send multiple types of CryptoItems from a 3rd party in one transfer (with safety call)
|
||||
For the purpose of transfer fees, each id/value pair is counted as a transfer
|
||||
Caller must have a sufficient allowance by _from for each of the _id/_value pairs
|
||||
Throws on any error rather than return a false flag to minimize user errors
|
||||
@param _from Source address
|
||||
@param _to Target address
|
||||
@param _ids Types of CryptoItems
|
||||
@param _values Transfer amounts per item type
|
||||
@param _data Additional data with no specified format, sent in call to `_to`
|
||||
*/
|
||||
function safeBatchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values, bytes _data) external;
|
||||
|
||||
/**
|
||||
@dev Allow other accounts/contracts to spend tokens on behalf of msg.sender
|
||||
Also, to minimize the risk of the approve/transferFrom attack vector
|
||||
(see https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/), this function will throw if the current approved allowance does not equal the expected _currentValue, unless _value is 0
|
||||
@param _spender Address to approve
|
||||
@param _ids IDs of the CryptoItems
|
||||
@param _currentValues Expected current values of allowances per item type
|
||||
@param _values Allowance amounts per item type
|
||||
*/
|
||||
function batchApprove(address _spender, uint256[] _ids, uint256[] _currentValues, uint256[] _values) external;
|
||||
}
|
||||
```
|
||||
|
||||
MUST trigger `Transfer` event.
|
||||
</details>
|
||||
|
||||
### approve
|
||||
<details>
|
||||
<summary>
|
||||
Simple/Extended Batch Transfers</summary>
|
||||
|
||||
Approves an account for the ability to transfer a maximum quantity of multiple `_itemId[]` on behalf of another account (using transferFrom).
|
||||
Each parameter array should be the same length, with each index correlating.
|
||||
```solidity
|
||||
interface IERC1155BatchTransferExtended {
|
||||
/**
|
||||
@dev Send multiple types of CryptoItems in one transfer
|
||||
For the purpose of transfer fees, each id/value pair is counted as a transfer
|
||||
@param _to Transfer destination address
|
||||
@param _ids IDs of the CryptoItems
|
||||
@param _values Transfer amounts per item type
|
||||
*/
|
||||
function batchTransfer(address _to, uint256[] _ids, uint256[] _values) external;
|
||||
|
||||
/**
|
||||
@dev Send multiple types of CryptoItems in one transfer (with safety call)
|
||||
For the purpose of transfer fees, each id/value pair is counted as a transfer
|
||||
@param _to Transfer destination address
|
||||
@param _ids IDs of the CryptoItems
|
||||
@param _values Transfer amounts per item type
|
||||
@param _data Additional data with no specified format, sent in call to `_to`
|
||||
*/
|
||||
function safeBatchTransfer(address _to, uint256[] _ids, uint256[] _values, bytes _data) external;
|
||||
}
|
||||
```
|
||||
|
||||
MUST trigger `Approval` event.
|
||||
</details>
|
||||
|
||||
### increaseApproval
|
||||
<details>
|
||||
<summary>
|
||||
Extended Approvals</summary>
|
||||
|
||||
Increases the allowance amount of one or more items without requiring a reset to 0.
|
||||
Each parameter array should be the same length, with each index correlating.
|
||||
```solidity
|
||||
interface IERC1155Operators {
|
||||
event OperatorApproval(address indexed _owner, address indexed _operator, uint256 indexed _id, bool _approved);
|
||||
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
|
||||
|
||||
MUST trigger `Approval` event.
|
||||
/**
|
||||
@notice Enable or disable approval for a third party ("operator") to manage
|
||||
all of `msg.sender`'s assets for a particular CryptoItem types.
|
||||
@dev Emits the OperatorApproval event
|
||||
@param _operator Address to add to the set of authorized operators
|
||||
@param _ids The IDs of the CryptoItems
|
||||
@param _approved True if the operators is approved, false to revoke approval
|
||||
*/
|
||||
function setApproval(address _operator, uint256[] _ids, bool _approved) external;
|
||||
|
||||
/**
|
||||
@dev Queries the approval status of an operator for a given CryptoItem and owner
|
||||
@param _owner The owner of the CryptoItems
|
||||
@param _operator Address of authorized operator
|
||||
@param _id ID of the CryptoItem
|
||||
@return True if the operator is approved, false if not
|
||||
*/
|
||||
function isApproved(address _owner, address _operator, uint256 _id) external view returns (bool);
|
||||
|
||||
/**
|
||||
@notice Enable or disable approval for a third party ("operator") to manage
|
||||
all of `msg.sender`'s assets.
|
||||
@dev Emits the OperatorApproval event
|
||||
@param _operator Address to add to the set of authorized operators
|
||||
@param _approved True if the operator is approved, false to revoke approval
|
||||
*/
|
||||
function setApprovalForAll(address _operator, bool _approved) external;
|
||||
|
||||
/**
|
||||
@dev Queries the approval status of an operator for a given CryptoItem and owner
|
||||
@param _owner The owner of the CryptoItems
|
||||
@param _operator Address of authorized operator
|
||||
@return True if the operator is approved, false if not
|
||||
*/
|
||||
function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator);
|
||||
}
|
||||
```
|
||||
|
||||
### decreaseApproval
|
||||
</details>
|
||||
|
||||
Decreases the allowance amount of one or more items without requiring a reset to 0.
|
||||
Each parameter array should be the same length, with each index correlating.
|
||||
<details>
|
||||
<summary>
|
||||
Views</summary>
|
||||
|
||||
MUST trigger `Approval` event.
|
||||
```solidity
|
||||
interface IERC1155Views {
|
||||
/**
|
||||
@dev Returns how many of a CryptoItem are deemed or expected to exist in circulation
|
||||
@param _id ID of the CryptoItem
|
||||
@return The number of CryptoItems in circulation
|
||||
*/
|
||||
function totalSupply(uint256 _id) external view returns (uint256);
|
||||
|
||||
/**
|
||||
@dev Returns a human readable string that identifies a CryptoItem, similar to ERC20
|
||||
@param _id ID of the CryptoItem
|
||||
@return The name of the CryptoItem type
|
||||
*/
|
||||
function name(uint256 _id) external view returns (string);
|
||||
|
||||
/**
|
||||
@dev Returns symbol of a CryptoItem, similar to ERC20 and ERC721
|
||||
@param _id ID of the CryptoItem
|
||||
@return The symbol of the CryptoItem
|
||||
*/
|
||||
function symbol(uint256 _id) external view returns (string);
|
||||
|
||||
/**
|
||||
@dev Returns the number of decimal places for a CryptoItem, similar to ERC20
|
||||
@param _id ID of the CryptoItem
|
||||
@return Number of decimals
|
||||
*/
|
||||
function decimals(uint256 _id) external view returns (uint8);
|
||||
|
||||
/**
|
||||
@notice A distinct Uniform Resource Identifier (URI) for a given asset
|
||||
@dev URIs are defined in RFC 3986
|
||||
@return URI string
|
||||
*/
|
||||
function uri(uint256 _id) external view returns (string);
|
||||
}
|
||||
```
|
||||
|
||||
### name
|
||||
</details>
|
||||
|
||||
Returns the Item ID's name.
|
||||
<details>
|
||||
<summary>
|
||||
ERC-1155 Token Receiver</summary>
|
||||
|
||||
This function is OPTIONAL but highly recommended.
|
||||
```solidity
|
||||
interface IERC1155TokenReceiver {
|
||||
/**
|
||||
@notice Handle the receipt of an ERC1155 type
|
||||
@dev The smart contract calls this function on the recipient
|
||||
after a `safeTransfer`. This function MAY throw to revert and reject the
|
||||
transfer. Return of other than the magic value MUST result in the
|
||||
transaction being reverted
|
||||
Note: the contract address is always the message sender
|
||||
@param _operator The address which called `safeTransferFrom` function
|
||||
@param _from The address which previously owned the token
|
||||
@param _id The identifier of the item being transferred
|
||||
@param _value The amount of the item being transferred
|
||||
@param _data Additional data with no specified format
|
||||
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
|
||||
*/
|
||||
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes _data) external returns(bytes4);
|
||||
}
|
||||
```
|
||||
|
||||
### symbol
|
||||
|
||||
Returns the Item ID's symbol.
|
||||
|
||||
This function is OPTIONAL.
|
||||
|
||||
### decimals
|
||||
|
||||
Returns the Item ID's decimals.
|
||||
|
||||
This function is OPTIONAL but highly recommended.
|
||||
|
||||
### totalSupply
|
||||
|
||||
Returns the Item ID's totalSupply.
|
||||
|
||||
### balanceOf
|
||||
|
||||
Returns an account's balance of specified Item ID.
|
||||
|
||||
### allowance
|
||||
|
||||
Returns the allowance set by any of the approve functions.
|
||||
|
||||
### ownerOf
|
||||
|
||||
For NFTs, this returns the owner of a specific `_itemId`.
|
||||
|
||||
This function is OPTIONAL.
|
||||
|
||||
### itemURI
|
||||
|
||||
Returns a distinct Uniform Resource Identifier (URI) for a given `_itemId`.
|
||||
|
||||
This function is OPTIONAL.
|
||||
|
||||
### itemByIndex
|
||||
|
||||
Enumerate valid NFTs.
|
||||
|
||||
This function is OPTIONAL.
|
||||
|
||||
### itemOfOwnerByIndex
|
||||
|
||||
Enumerate NFTs assigned to an owner.
|
||||
|
||||
This function is OPTIONAL.
|
||||
</details>
|
||||
|
||||
## Non-Fungible Items
|
||||
|
||||
@ -156,9 +335,55 @@ Non-Fungible Items can be interacted with using an index based accessor into the
|
||||
|
||||
Inside the contract code the two pieces of data needed to access the individual NFT can be extracted with uint128(~0) and the same mask shifted by 128.
|
||||
|
||||
### Interface
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
Optional Non Fungible Interface</summary>
|
||||
|
||||
```solidity
|
||||
interface IERC1155NonFungible {
|
||||
/**
|
||||
@notice Find the owner of an NFT
|
||||
@dev NFTs assigned to zero address are considered invalid, and queries about them do throw
|
||||
@param _id The identifier for an NFT
|
||||
@return The address of the owner of the NFT
|
||||
*/
|
||||
function ownerOf(uint256 _id) external view returns (address);
|
||||
|
||||
/**
|
||||
@notice Enumerate valid NFs
|
||||
@dev Throws if `_index` >= `totalSupply()`.
|
||||
@param _index A counter less than `totalSupply()`
|
||||
@return The token identifier for the `_index`th NFT (sort order not specified)
|
||||
*/
|
||||
function nonFungibleByIndex(uint256 _id, uint128 _index) external view returns (uint256);
|
||||
|
||||
/**
|
||||
@notice Enumerate NFTs assigned to an owner
|
||||
@dev Throws if `_index` >= `balanceOf(_owner)` or if
|
||||
`_owner` is the zero address, representing invalid NFTs
|
||||
@param _owner An address where we are interested in NFTs owned by them
|
||||
@param _index A counter less than `balanceOf(_owner)`
|
||||
@return The token identifier for the `_index`th NFT assigned to `_owner` (sort order not specified)
|
||||
*/
|
||||
function nonFungibleOfOwnerByIndex(uint256 _id, address _owner, uint128 _index) external view returns (uint256);
|
||||
|
||||
/**
|
||||
@notice Is this token non fungible?
|
||||
@dev If this returns true, the token is non-fungible.
|
||||
@param _id The identifier for a potential non-fungible.
|
||||
@return True if the token is non-fungible
|
||||
*/
|
||||
function isNonFungible(uint256 _id) external view returns (bool);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Example of split ID bits
|
||||
|
||||
```
|
||||
```solidity
|
||||
uint256 baseToken = 12345 << 128;
|
||||
uint128 index = 50;
|
||||
|
||||
@ -168,6 +393,7 @@ balanceOf(baseToken + index, msg.sender); // Get balance of the Non-Fungible tok
|
||||
|
||||
## Implementation
|
||||
|
||||
- [ERC-1155 Reference Implementation](https://github.com/enjin/erc-1155)
|
||||
- [Enjin Coin](https://enjincoin.io) ([github](https://github.com/enjin))
|
||||
|
||||
## Copyright
|
||||
|
Loading…
x
Reference in New Issue
Block a user