mirror of https://github.com/status-im/EIPs.git
EIP 1203 (#1204)
This commit is contained in:
parent
12072384a9
commit
485b14afc8
|
@ -0,0 +1,230 @@
|
|||
---
|
||||
eip: 1203
|
||||
title: ERC-1203 Multi-Class Token Standard (ERC-20 Extension)
|
||||
author: Jeff Huang <jeffishjeff@gmail.com>, Min Zu <crawlregister@gmail.com>
|
||||
discussions-to: https://github.com/ethereum/EIPs/issues/1203
|
||||
status: Draft
|
||||
type: Standards Track
|
||||
category: ERC
|
||||
created: 2018-07-01
|
||||
---
|
||||
|
||||
## Simple Summary
|
||||
|
||||
A standard interface for multi-class tokens (MCTs).
|
||||
|
||||
## Abstract
|
||||
|
||||
The following standard allows for the implementation of a standard API for MCTs within smart contracts. This standard provides basic functionality to track, transfer, and convert MCTs.
|
||||
|
||||
## Motivation
|
||||
|
||||
This standard is heavily inspired by ERC-20 Token Standard and ERC-721 Non-Fungible Token Standard. However, whereas these standards are chiefly concerned with representation of items/value in a single class, fungible or note, this proposed standard focus on that of a more complexed, multi-class system. It is fair to think of MCTs as a hybrid of fungible tokens (FT) and non-fungible tokens (NFTs), that is tokens are fungible within the same class but non-fungible with that from a different class. And conversions between classes may be optionally supported.
|
||||
|
||||
MCTs are useful in representing various structures with heterogeneous components, such as:
|
||||
|
||||
- **Abstract Concepts:** A company may have different classes of stocks (e.g. senior preferred, junior preferred, class A common, class B common) that together make up its outstanding equities. A shareholder's position of such company composites of zero or more shares in each class.
|
||||
|
||||
- **Virtual Items:** A sandbox computer game may have many types of resources (e.g. rock, wood, berries, cows, meat, knife, etc.) that together make up that virtual world. A player's inventory has any combination and quantity of these resources
|
||||
|
||||
- **Physical Items:** A supermarket may have many SKUs it has available for purchase (e.g. eggs, milk, beef jerky, beer, etc.). Things get added or removed from a shopper's cart as it moves down the aisle.
|
||||
|
||||
It's sometimes possible, especially with regard to abstract concepts or virtual items, to convert from one class to another, at a specified conversion ratio. When it comes to physical items, such conversion essentially is the implementation of bartering. Though it might generally be easier to introduce a common intermediary class, i.e. money.
|
||||
|
||||
## Specification
|
||||
|
||||
```solidity
|
||||
contract ERC20 {
|
||||
function totalSupply() public view returns (uint256);
|
||||
function balanceOf(address _owner) public view returns (uint256);
|
||||
function transfer(address _to, uint256 _value) public returns (bool);
|
||||
function approve(address _spender, uint256 _value) public returns (bool);
|
||||
function allowance(address _owner, address _spender) public view returns (uint256);
|
||||
function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
|
||||
|
||||
event Transfer(address indexed _from, address indexed _to, uint256 _value);
|
||||
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
||||
}
|
||||
|
||||
contract ERC1203 is ERC20 {
|
||||
function totalSupply(uint256 _class) public view returns (uint256);
|
||||
function balanceOf(address _owner, uint256 _class) public view returns (uint256);
|
||||
function transfer(address _to, uint256 _class, uint256 _value) public returns (bool);
|
||||
function approve(address _spender, uint256 _class, uint256 _value) public returns (bool);
|
||||
function allowance(address _owner, address _spender, uint256 _class) public view returns (uint256);
|
||||
function transferFrom(address _from, address _to, uint256 _class, uint256 _value) public returns (bool);
|
||||
|
||||
function fullyDilutedTotalSupply() public view returns (uint256);
|
||||
function fullyDilutedBalanceOf(address _owner) public view returns (uint256);
|
||||
function fullyDilutedAllowance(address _owner, address _spender) public view returns (uint256);
|
||||
function convert(uint256 _fromClass, uint256 _toClass, uint256 _value) public returns (bool);
|
||||
|
||||
event Transfer(address indexed _from, address indexed _to, uint256 _class, uint256 _value);
|
||||
event Approval(address indexed _owner, address indexed _spender, uint256 _class, uint256 _value);
|
||||
event Convert(uint256 indexed _fromClass, uint256 indexed _toClass, uint256 _value);
|
||||
}
|
||||
```
|
||||
|
||||
### ERC-20 Methods and Events (fully compatible)
|
||||
|
||||
Please see [ERC-20 Token Standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) for detailed specifications. Do note that these methods and events only work on the "default" class of an MCT.
|
||||
|
||||
```solidity
|
||||
function totalSupply() public view returns (uint256);
|
||||
function balanceOf(address _owner) public view returns (uint256);
|
||||
function transfer(address _to, uint256 _value) public returns (bool);
|
||||
function approve(address _spender, uint256 _value) public returns (bool);
|
||||
function allowance(address _owner, address _spender) public view returns (uint256);
|
||||
function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
|
||||
|
||||
event Transfer(address indexed _from, address indexed _to, uint256 _value);
|
||||
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
||||
```
|
||||
|
||||
### Tracking and Transferring
|
||||
|
||||
**totalSupply**
|
||||
|
||||
Returns the total number of tokens in the specified `_class`
|
||||
|
||||
```solidity
|
||||
function totalSupply(uint256 _class) public view returns (uint256);
|
||||
```
|
||||
|
||||
**balanceOf**
|
||||
|
||||
Returns the number of tokens of a specified `_class` that the `_owner` has
|
||||
|
||||
```solidity
|
||||
function balanceOf(address _owner, uint256 _class) public view returns (uint256);
|
||||
```
|
||||
|
||||
**transfer**
|
||||
|
||||
Transfer `_value` tokens of `_class` to address specified by `_to`, return `true` if successful
|
||||
|
||||
```solidity
|
||||
function transfer(address _to, uint256 _class, uint256 _value) public returns (bool);
|
||||
```
|
||||
|
||||
**approve**
|
||||
|
||||
Grant `_spender` the right to transfer `_value` tokens of `_class`, return `true` if successful
|
||||
|
||||
```solidity
|
||||
function approve(address _spender, uint256 _class, uint256 _value) public returns (bool);
|
||||
```
|
||||
|
||||
**allowance**
|
||||
|
||||
Return the number of tokens of `_class` that `_spender` is authorized to transfer on the behalf of `_owner`
|
||||
|
||||
```solidity
|
||||
function allowance(address _owner, address _spender, uint256 _class) public view returns (uint256);
|
||||
```
|
||||
|
||||
**transferFrom**
|
||||
|
||||
Transfer `_value` tokens of `_class` from address specified by `_from` to address specified by `_to` as previously approved, return `true` if successful
|
||||
|
||||
```solidity
|
||||
function transferFrom(address _from, address _to, uint256 _class, uint256 _value) public returns (bool);
|
||||
```
|
||||
|
||||
**Transfer**
|
||||
|
||||
Triggered when tokens are transferred or created, including zero value transfers
|
||||
|
||||
```solidity
|
||||
event Transfer(address indexed _from, address indexed _to, uint256 _class, uint256 _value);
|
||||
```
|
||||
|
||||
**Approval**
|
||||
|
||||
Triggered on successful `approve`
|
||||
|
||||
```solidity
|
||||
event Approval(address indexed _owner, address indexed _spender, uint256 _class, uint256 _value);
|
||||
```
|
||||
|
||||
### Conversion and Dilution
|
||||
|
||||
**fullyDilutedTotalSupply**
|
||||
|
||||
Return the total token supply as if all converted to the lowest common denominator class
|
||||
|
||||
```solidity
|
||||
function fullyDilutedTotalSupply() public view returns (uint256);
|
||||
```
|
||||
|
||||
**fullyDilutedBalanceOf**
|
||||
|
||||
Return the total token owned by `_owner` as if all converted to the lowest common denominator class
|
||||
|
||||
```solidity
|
||||
function fullyDilutedBalanceOf(address _owner) public view returns (uint256);
|
||||
```
|
||||
|
||||
**fullyDilutedAllowance**
|
||||
|
||||
Return the total token `_spender` is authorized to transfer on behalf of `_owner` as if all converted to the lowest common denominator class
|
||||
|
||||
```solidity
|
||||
function fullyDilutedAllowance(address _owner, address _spender) public view returns (uint256);
|
||||
```
|
||||
|
||||
**convert**
|
||||
|
||||
Convert `_value` of `_fromClass` to `_toClass`, return `true` if successful
|
||||
|
||||
```solidity
|
||||
function convert(uint256 _fromClass, uint256 _toClass, uint256 _value) public returns (bool);
|
||||
```
|
||||
|
||||
**Conversion**
|
||||
|
||||
Triggered on successful `convert`
|
||||
|
||||
```solidity
|
||||
event Conversion(uint256 indexed _fromClass, uint256 indexed _toClass, uint256 _value);
|
||||
```
|
||||
|
||||
## Rationale
|
||||
This standard purposely extends ERC-20 Token Standard so that new MCTs following or existing ERC-20 tokens extending this standard are fully compatible with current wallets and exchanges. In addition, new methods and events are kept as closely to ERC-20 conventions as possible for ease of adoption.
|
||||
|
||||
We have considered alternative implementations to support the multi-class structure, as discussed below, and we found current token standards incapable or inefficient in deal with such structures.
|
||||
|
||||
**Using multiple ERC-20 tokens**
|
||||
|
||||
It is certainly possible to create an ERC-20 token for each class, and a separate contract to coordinate potential conversions, but the short coming in this approach is clearly evident. The rationale behind this standard is to have a single contract to manage multiple classes of tokens.
|
||||
|
||||
**Shoehorning ERC-721 token**
|
||||
|
||||
Treating each token as unique, the non-fungible token standard offers maximum representational flexibility arguably at the expense of convenience. The main challenge of using ERC-721 to represent multi-class token is that separate logic is required to keep track of which tokens belongs to which class, a hacky and unnecessary endeavor.
|
||||
|
||||
**Using ERC-1178 token**
|
||||
|
||||
We came across ERC-1178 as we were putting final touches on our own proposal. The two ERCs look very similar on the surface but we believe there're a few key advantages this one has over ERC-1178.
|
||||
|
||||
- ERC-1178 offers no backward compatibility whereas this proposal is an extension of ERC-20 and therefore fully compatible with all existing wallets and exchanges
|
||||
- By the same token, existing ERC-20 contracts can extend themselves to adopt this standard and support additional classes without affecting their current behaviors
|
||||
- This proposal introduces the concept of cross class conversion and dilution, making each token class integral part of a whole system rather than many silos
|
||||
|
||||
## Backwards Compatibility
|
||||
This EIP is fully compatible with the mandatory methods of ERC20 Token Standard so long as the implementation includes a "lowest common denominator" class, which may be class B common/gold coin/money in the abstract/virtual/physical examples above respectively. Where it is not possible to implement such class, then the implementation should specify a default class for tracking or transferring unless otherwise specified, e.g. US dollar is transferred unless other currency is explicitly specified.
|
||||
|
||||
We find it contrived to require the optional methods of ERC20 Token Standard, `name()`, `symbol()`, and `decimals()`, but developers are certainly free to implement these as they wish.
|
||||
|
||||
## Test Cases
|
||||
The repository at [jeffishjeff/ERC-1203](https://github.com/jeffishjeff/ERC-1203) contains the [sample test cases](https://github.com/jeffishjeff/ERC-1203/blob/master/token.test.js).
|
||||
|
||||
## Implementation
|
||||
The repository at [jeffishjeff/ERC-1203](https://github.com/jeffishjeff/ERC-1203) contains the [sample implementation](https://github.com/jeffishjeff/ERC-1203/blob/master/token.sol).
|
||||
|
||||
## References
|
||||
- ERC-20 Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
|
||||
- ERC-721 Non-Fungible Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
|
||||
- ERC-1178 Multi-class Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1178.md
|
||||
|
||||
## Copyright
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
Loading…
Reference in New Issue