Introducing Crypto Composables

Since the introduction of Bitcoin, we’ve had a provable model of decentralized digital scarcity for fungible assets on a distributed ledger. Fungible: all units are equal and when combined, sums are indistinguishable. The first non-fungible assets or deeds using the Bitcoin network model were introduced in 2010 through a discussion of BitDNS/Namecoin, a decentralized DNS service. Ownership of real world assets was proposed later by the Colored Coins project. We now have a thriving example of virtual non-fungible assets. Cryptokitties is built on the Ethereum network; a programmable, general purpose blockchain. However, not all assets virtual or otherwise are easily represented by a single deed, or in the case of the Ethereum Request for Comment, ERC-721, a single identifying integer.

Cryptokitty lusting over Ether.

When buying or selling a home, officially, the title is for land, anything above and below. However, the house is what you are selling; it’s the perceived value. The real value is in land as an appreciating asset. Perhaps the plan is to demolish and rebuild, or sell the house separately, if possible. In all other transactions of land titles, the house and perhaps its contents will be a major part of the sale. Purchasing a home becomes a complex decision; a single transfer of title representing a composition of items that may be broken apart later. How might we accomplish this on the Ethereum blockchain?

Enter Crypto Composables

A standard extension for any non-fungible token (NFT) to own another non-fungible ERC-721 token or fungible ERC-20 tokens. Transferring the token composition means transferring the entire hierarchy of items. Virtual assets can own their own assets. For example, a cryptokitty may own a scratching post and a feeding dish; the dish may contain some amount of fungible “chow” tokens. That’s one happy and well fed virtual cat.

Remember Tamagotchi? Coming soon to a blockchain near your wallet?

One of the most interesting aspects of Cryptokitties was the breeding function. Composed assets can also be provided with actions based on “equipping” a child asset. Think of adding a food asset to a virtual character, like our kitty with chow tokens. Now the kitty can eat chow tokens and speed up their breeding rest period to become more valuable. A bit out of scope for this post would be a proposed standard for, “active assets”, allowing composable assets to act on other assets, their children or use a special action based on ownership of a child asset. What other games or business use cases could we serve with composable and actionable assets?

ERC-998 Composable NFTs

What would a standard be without a sample implementation? In the following sections I will discuss in detail how this would work.

UPDATE

As things move rather fast in blockchain, I am updating this section of the post explaining the functional parts of ERC-998 to reflect the latest resources, specification and reference implementations:

EIP-998 Master is where you will find the latest specification.

Composables-998 is where you’ll find an up to date reference implementation.

Use Cases Post

Original Detailed Explanation

What follows is a high level overview of the basic concepts from the original post. Solidity code has been removed to not confuse the reader.

The “parent” will refer to the composable ERC-721 (now ERC-998) token, and the “child” will refer to any ERC-721 or ERC-20 tokens owned by the composable.

This required mapping for an ERC-998 is from the parent tokenId of the composable to another mapping between the child contract address and an unsigned integer. When the parent owns a non-fungible child token, the child contract address maps to the child token IDs the parent may own. When the parent owns a fungible token, the child contract address maps to the balance of child tokens. For ERC-721 children we keep track of the token IDs, and for ERC-20 we keep track of the token amount. This internal bookkeeping will help to ensure someone who does not own the parent, is not able to transfer the children.

In both instances, the actual owning address of child tokens in their contracts is the composable ERC-998 contract. The mapping allows us to enforce a parent child relationship and ownership through the parent token ID. Child tokens are only able to be transferred from the contract if the sender also owns the parent token ID. A major caveat is that you MUST trust the composable ERC-998 contract does not also have the ability to arbitrarily transfer child tokens the contact technically owns.

Adding Children

The ERC-998 contract requires approval from the child token so that it can use the transferFrom(owner, to, tokenId) function. This function allows the parent to transfer ownership from the current owner, the user adding the child to the parent, to the parent smart contract.

Optionally, you can transfer from ERC-721 and ERC-223 directly and use the optional bytes field to indicate which NFT in the ERC-998 contract you wish to transfer to. This results in only a single transaction to move a composable.

Once this is complete and returns successfully, the parent adds the child to the internal mappings. This will allow us to enforce the parent child relationship later when transferring children.

Transferring Non-Fungible ERC-721 Children

Transferring the child of a composable asset can be thought of as asset decomposition. In order to transfer a non-fungible child token we need to know who we are transferring the token to and the ID of the parent token that owns the child to enforce ownership; lastly we will need the child contract address and child token ID. Using this information we check the following first:

  • The sender of the function call owns the parent token, a standard method in the ERC-721 specification implemented as _owns(address, tokenId)
  • We’ve implemented rootOwnerOf which will actually check who owns the parent token ID all the way up the tree if there is a hierarchy of composable tokens
  • The parent token ID is mapped to the child token ID through the child contract address, enforcing the parent child relationship

Once these are OK, we can call the transfer function of the child contract and if our transfer is successful we set the children mapping to 0 reflecting that the child asset is no longer owned by the parent asset. This is called decomposing the asset.

Transferring Fungible ERC-20 Children

Like the example above, we can transfer the child if two conditions are met:

  • The sender of the function call owns the parent token ID
  • The parent token owns enough of a balance of the fungible child tokens in order to transfer the amount

The second condition prevents parents from overspending the child tokens in the instance that multiple parents own the same type of tokens. Again, all child assets are owned by the parent token’s contract address, not directly by the parent tokens themselves. If everything checks out and the transfer is a success we will transfer the tokens and decrement the amount of child tokens in the children mapping.

Making use of “chow” tokens.

Summary

I’ve presented a new standard for composable NFTs, ERC-998. This standard allows an ERC-998 token to own ERC-998, ERC-721 and ERC-20 tokens. This allows standard Ethereum assets to be composed into complex compositions and traded using a single transfer. Additional functionality can be added to a NFT based on the presence of specific child tokens and is open for exploration. I believe that standard interfaces for non-fungible and fungible assets to be composed and provided with actions is an exciting new area for the Ethereum community to explore and I look forward to seeing future work.

Original GitHub issue: ERC-998 Composable Non-Fungible Token Standard

Thank you for indulging me.

medium.com/@mattdlockyer
twitter.com/mattdlockyer
linkedin.com/in/mattlockyer

UPDATES

EIP-998 Master is where you will find the latest specification.

Composables-998 is where you’ll find an up to date reference implementation.

Thanks to Nick Mudge, CryptoKitties, Fabiano PS, Trent McConaghy

References

https://github.com/ethereum/EIPs

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md