AssetClass Proposal


#1

Motivation

We’re considering the ways to implement Non-Fungible Tokens (NFTs) which we believe would be quite useful. NFTs’ distinguishing feature is that they’re not interchangeable since each NFT describes a unique object and has characteristics that recognize it from all other tokens. NFTs can be used in many ways, for example in gaming, ticketing and as proof of ownership.

Currently, we able to issue an asset for each NF-token, but the problem here is that assets issuance is expensive. We propose to issue them simultaneously, and they will share a common script as well.

The proposed feature would give the ability to create NFTs and manage common assets scripts’ more conveniently.
What do you think about this feature?

The Basic Explanation

An AssetClass is a way to generalize an Asset. Essentially, an AssetClass is a category that contains assets. An asset may either belong to only one AssetClass or not belong to any.

AssetClassTransaction

We propose to add a new transaction type that is used for the creation of an AssetClass and issuing assets in it.

AssetClassTransaction Example:

{
  "sender" : "3PBSduYkK7GQxVFWkKWMq8GQkVdAGX71hTx",
  "senderPublicKey" : "3LZmDK7vuSBsDmFLxJ4qihZynUz8JF9e88dNu5fsus5p",
  "version" : 1,
  "id" : "GnupVrhwszpPSAsKAQT741sLptYPAviGs9iXXGj7NhtE",
  "script" : "base64:AQQAAAAEaW5hbAIAAAAESW5hbAQAAAAFZWxlbmECAAAABAAAEaW5hbAUAAAAFZWxlbmEFAAAABGxvdmV4ZFt5",
  "description" : "My Game Characters",
  "assets" : [ {
    "id" : 1,
    "name" : "Zombie",
    "quantity" : 1000,
    "reissuable" : true,
    "decimals" : 0
  }, {
    "id" : 2,
    "name" : "Dragon",
    "quantity" : 1,
    "reissuable" : false,
    "decimals" : 0
  } ],
  "fee" : 100000000,
  "timestamp" : 1519271860,
  "proofs" : [ "jh24r6c4K427G245Y8725L8g68tcrEJ52HG8FK8528g25G8HFfJGHdCfghdefgJEf" ]
}

The issued assets cannot have scripts, but they share an AssetClass’ script.

The issued assets can be treated like any other assets. Their AssetIds are calculated by replacing the last 4 bytes of AssetClassId with Id bytes (see the example for details).

This method of an AssetId calculation allows for the following possibilities:

  1. Uniform AssetId generation from the AssetClassId.
  2. Ability to store some object’s characteristics in its Id as a binary mask.

Applications

Fungible Tokens with a Common Script

We can issue fungible assets in an AssetClass and regulate them with a common script. The script is specified in the AssetClass but validates all transactions with every asset in the class.

Semi-Fungible Tokens

Semi-fungible tokens enable interchangeability of some assets of a certain type but types still are not interchangeable with each other:

Non-Fungible Tokens

Using AssetClasses we’re able to create non-fungible tokens (NFTs).

We have to create AssetClass that contains assets, each has decimals=0, totalAmount=1. We also might want to create an account with state containing assets’ descriptions.

AssetClass would solve the following problems relating to NFTs:

  1. fixed issue price;
  2. ease of use;
  3. common assets’ script.

This approach also allows for the following features:

  1. NFTs are interchangeable with fungible tokens and users are able to resell NFTs.
  2. NFTs’ metadata can be stored off-chain. The smart account’s state contains a reference to metadata and its hash, so it would be easy to ensure that the metadata wasn’t changed.
  3. Users are able to track an asset’s history to check its provenance.
  4. The issuer can have a share from each users’ NFT resell.
  5. The issuer can set restrictions for resale (deny increasing the price; set a minimum and maximum price caps).
  6. The issuer can control reissuability of each asset.

#2

Example: NFT-based game creation process

  1. Create Tokens’ Descriptions.

First of all, we need to design the game’s tokens and add their descriptions to a DB:

NAME ID METADATA
Knight 1 metadata1
Dragon 2 metadata2
Yeti 3 metadata3
  1. Create an account.

  2. Issue an AssetClass (Write a script for it if needed) via AssetClassTransaction.

{
  "type" : 99,
  "sender" : "3PBSduYkK7GQxVFWkKWMq8GQkVdAGX71hTx",
  "senderPublicKey" : "3LZmDK7vuSBsDmFLxJ4qihZynUz8JF9e88dNu5fsus5p",
  "version" : 1,
  "id" : "GnupVrhwszpPSAsKAQT741sLptYPAviGs9iXXGj7NhtE",
  "script" : "base64:AQQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE0V4Y2hhbmdlVHJhbnNhY3Rpb24EAAAAAnR4BQAAAAckbWF0Y2gwCQAAAAAAAAIIBQAAAAJ0eAAAAAZzZW5kZXIJAQAAABFhZGRyZXNzRnJvbVN0cmluZwAAAAECAAAAIzNQSmFEeXBydmVrdlBYUHVBdHhyYXBhY3VESm9wZ0pSYVUzBtDvQU0=",
  "description" : "My Game Characters",
 
  "assets" : [ {
    "id" : 1,
    "name" : "Knight",
    "quantity" : 15,
    "reissuable" : true,
    "decimals" : 0
  }, {
    "id" : 2,
    "name" : "Dragon",
    "quantity" : 1,
    "reissuable" : false,
    "decimals" : 0
  }, {
    "id" : 3,
    "name" : "Yeti",
    "quantity" : 1,
    "reissuable" : false,
    "decimals" : 0
  } ],
 
  "fee" : 1000,
  "timestamp" : 1537879628968,
  "proofs" : [ "KMGJysgMi71WKBwEd22369H75YZcrZEji2XdPNLyY64enSLu7darS6mfBxCqzLrdGXCegu8ct3MZgKRuYyUdkVE" ]
}
  1. The assets’ AssetId can be calculated as follows.

We have the following AssetClassId: “GnupVrhwszpPSAsKAQT741sLptYPAviGs9iXXGj7NhtE”.

Bytes decoded from Base58:

234 162 151 92 205 179 89 227

The last 4 bytes of AssetClassId are replaced with Id bytes:

234 162 151 92 0 0 0 1

After base58-encoding this new array we get a result AssetId : “GnupVrhwszpPSAsKAQT741sLptYPAviGs9iXXGdrR15A”.

So our tokens will have the following AssetIds:

Token AssetId
Knight GnupVrhwszpPSAsKAQT741sLptYPAviGs9iXXGdrR15A
Dragon GnupVrhwszpPSAsKAQT741sLptYPAviGs9iXXGdrR15B
Yeti GnupVrhwszpPSAsKAQT741sLptYPAviGs9iXXGdrR15C
  1. Change the account’s state via DataTransacton with tokens’ metadata.

  2. Now we’re able to trade the tokens on DEX or transfer/massTransfer them as usual assets. And the assets’ holders are able to do that as well.

  3. We’re also able to reissue one of the assets via ReissueTransaction.


#3

I am not fun of games but this idea seems pretty usefull for the sector. Still didn’t get how the characters or items will be traded on dex.I guess game companies will issue the tokens and will integrate their service here. :thinking:


#4

This is a FANTASTIC proposal and something I am super excited to have on Waves. PLEASE PLEASE implement this!