Skip to content

Commit

Permalink
eip-1155 Crypto Item Standard (#1181)
Browse files Browse the repository at this point in the history
* eip-1155 Crypto Item Standard

* Update eip-1155.md
  • Loading branch information
coinfork authored and Arachnid committed Jun 25, 2018
1 parent 3390761 commit 4636f54
Showing 1 changed file with 174 additions and 0 deletions.
174 changes: 174 additions & 0 deletions EIPS/eip-1155.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
eip: 1155
title: Crypto Item Standard
author: Witek Radomski <witek@enjin.com>, Andrew Cooke <andrew@enjin.com>
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 `<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

- [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/).

0 comments on commit 4636f54

Please sign in to comment.