6.9 KiB
eip | title | author | type | category | status | created | discussions-to |
---|---|---|---|---|---|---|---|
1155 | Crypto Item Standard | Witek Radomski <witek@enjin.com>, Andrew Cooke <andrew@enjin.com> | Standards Track | ERC | Draft | 2018-06-17 | 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, 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 <uint128: base item id><uint128: index of NFT>
.
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
Copyright
Copyright and related rights waived via CC0.