Skip to content

Instantly share code, notes, and snippets.

@alex-miller-0
Created March 6, 2018 00:41
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alex-miller-0/51dbc7fc5c363eaa3225c5f8da12e38b to your computer and use it in GitHub Desktop.
Save alex-miller-0/51dbc7fc5c363eaa3225c5f8da12e38b to your computer and use it in GitHub Desktop.
Meta-Non-Fungible Token

Meta-Non-Fungible Token

Non-fungible tokens (NFTs) are all the rage these days, but their current manifestation (ERC721) is inefficient. It is not possible to move multiple tokens at the same time or package multiple tokens for e.g. deposit into a plasma child chain.

Contract pseudocode

The following is a new design for an NFT token that allows aggregation of assets. The rest of the functionality can be inherited from ERC721.

contract NFT {
  tokens mapping(address => mapping(bytes32 => uint));
  
  transfer (bytes32 id, uint n, address to) {
    assert(tokens[msg.sender][id] >= n);
    tokens[msg.sender][id] -= n;
    tokens[to][id] += n;
  }
  
  transferBundle(address to, bytes data) {
    for (uint i = 0; i < data.length; i += 64) {
      uint n = data.slice(i, i+32);
      uint token = data.slice(i+32, i+64);
      transfer(token, n, to);
    }
  }
}

Note that we are representing tokens in a different construction than ERC721. Each token has an id, which is a hash of its metadata (this should be unique) and any user may own any number of each unique token.

Users can transfer one or more of a single token via transfer() or move several tokens to a recipient via transferBundle()

NFT UTXOs

This design enables us to package tokens reasonably efficiently and transfer them off chain to e.g. a plasma child chain.

Interestingly, these NFTs can also be represented as UTXOs:

{
  id: <string>   // keccak256(prevId, to, n, data)
  to: <string>   // new owner of this token
  n: <int>       // number of tokens in this UTXO
  data: <string> // token metadata. This should be unique to the token (e.g. for a card in a trading card game)
}

The only difference between this and fungible token UTXOs is the presence of the data field, which is simply hashed into the id and never changes as tokens move through the system.

Such tokens can then be traded off-chain (via UTXO signing) and withdrawn later onto the root chain via a submission of the UTXO's provenance. (for example, if Bob got a card from Alice, he would need to submit her signed transaction in order to withdraw his new card).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment