From 4636f54df7d480010accf8882a0fd0eef28a8742 Mon Sep 17 00:00:00 2001 From: Witek Date: Mon, 25 Jun 2018 00:29:35 -0700 Subject: [PATCH] eip-1155 Crypto Item Standard (#1181) * eip-1155 Crypto Item Standard * Update eip-1155.md --- EIPS/eip-1155.md | 174 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 EIPS/eip-1155.md diff --git a/EIPS/eip-1155.md b/EIPS/eip-1155.md new file mode 100644 index 00000000000000..bee5cffef42cba --- /dev/null +++ b/EIPS/eip-1155.md @@ -0,0 +1,174 @@ +--- +eip: 1155 +title: Crypto Item Standard +author: Witek Radomski , Andrew Cooke +type: Standards Track +category: ERC +status: Draft +created: 2018-06-17 +discussions-to: https://github.com/ethereum/EIPs/issues/1155 +--- + +## Simple Summary + +A standard interface for multiple item/token definitions in a single deployed contract. + +## 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. + +The `_itemId` parameter is named as such and placed at the beginning of each function. + +## Motivation + +Tokens standards like ERC-20 and ERC-721 require a separate contract to be deployed for each fungible or NFT token/collection. This places a lot of redundant bytecode on the Ethereum blockchain and limits certain functionality by the nature of separating each token contract into its own permissioned address. With the rise of crypto games and platforms like [Enjin Coin](https://enjincoin.io/), game developers may be creating tens of thousands of items, and a new type of token standard is needed to support this. + +New functionality is possible with this design, such as transferring or approving multiple token types at once, saving on transaction costs. Trading (escrow / atomic swaps) of multiple tokens can be built on top of this standard and it removes the need to "approve" individual tokens separately. It is also easy to describe and mix multiple fungible or non-fungible tokens in a single contract. + +## 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); + + // 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); + + // 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); +} +``` + +### transfer + +Transfers quantities of each `_itemId[]` to the addresses specified. +Each parameter array should be the same length, with each index correlating. + +MUST trigger `Transfer` event. + +### transferFrom + +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. + +MUST trigger `Transfer` event. + +### approve + +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. + +MUST trigger `Approval` event. + +### increaseApproval + +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. + +MUST trigger `Approval` event. + +### decreaseApproval + +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. + +MUST trigger `Approval` event. + +### name + +Returns the Item ID's name. + +This function is OPTIONAL but highly recommended. + +### 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. + +## Non-Fungible Items + +An example strategy to mix Fungible and Non-Fungible Items together in the same contract would be to pass the base item ID in the top 128 bits of the uint256 `_itemID` parameter and then use the bottom 128 bits for any extra data you wish to pass to the contract. + +Non-Fungible Items can be interacted with using an index based accessor into the contract/item data set. Therefore to access a particular item set within a mixed data contract and particular NFT within that set, `_itemID` could be passed as ``. + +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. + +### Example of split ID bits + +``` +uint256 baseToken = 12345 << 128; +uint128 index = 50; + +balanceOf(baseToken, msg.sender); // Get balance of the base token +balanceOf(baseToken + index, msg.sender); // Get balance of the Non-Fungible token index +``` + +## Implementation + +- [Enjin Coin](https://enjincoin.io) ([github](https://github.com/enjin)) + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).