[FIP-1] Introduce Non-Fungible Tokens to the UTXO Set

[FIP-1] Introduce Non-Fungible Tokens to the UTXO Set

Authors: Zachary Kornberg (@crypdoughdoteth), @Furnic
Created: 2/17/2023
Requires: None

Abstract

Fuel’s inclusion of native assets into the UTXO set brings unique benefits to usage of tokens on Fuel. Including non-fungible tokens in this set seems to make a lot of sense in terms of enforcing consistent behavior for assets on Fuel and the ability to leverage the same benefits of using native tokens. In addition, these changes will lead to a better user experience and developer experience due to the new patterns emerging from the native token system.

Motivation

Fuel’s native asset system is advantageous for the tokens in a few ways: no need to serialize data, native sending/receiving without accessing contract storage, and encouraging better asset handling patterns. While fungible tokens (20/1155) are the only ones able to benefit from native patterns, we have the opportunity to make both the developer experience and user experience better from the outset for NFTs as well. One concrete example is the traditional approval pattern for ledger-based assets. Typically, before a protocol handles tokens, we must first call approve() (with the protocol as spender) on the token’s contract, then we can call the desired function to move assets on the protocol. Hassling users for two signatures isn’t always ideal and not every developer is bound to batch calls to RPC providers. Moreover, if we reduce the number of calls writing to contract storage, we can reduce the pace of state growth. In terms of security risks for ledger-based assets, the traditional approval pattern could also alter balances inadvertently if there is an infinite approval given to a protocol that allows improper access to its functions.
image

Spec

Currently, the reference to assets on fuel uses AssetId and according to Furnic, “currently the AssetId of a token is identical to the ContractId of the minting contract”. We need to differentiate between different non-fungible tokens belonging to the same contract without sacrificing its lack of fungibility. In the Fuel forum, with the help of Furnic, we formulated a possible approach. The idea is that we need I) a unique AssetId while II) also identify the data attached to it (contained in ContractId). In order to make this possible, we can use a bitwise XOR operation such that AssetId = ContractId ^ TokenId where TokenId increments every time a new token is minted from ContractId. Bitwise XOR operations are reversable and therefore ContractId and TokenId will be recoverable from the operation. Moreover, we will need to add a new type of transaction that is designated specifically for the minting of non-fungible tokens given the updated formula.

Rationale

These changes intend for minimize intrusion on the protocol, enforces the consistency of behavior across assets, and lastly allows for tokens to benefit from the native architecture of Fuel.

Security

Review of changes to the protocol are necessary such that we should observe the effects it can have on the size of UTXOs.

Copyright

All rights are waved under CC0

Backwards Compatibility

This will cause the need for adjustments downstream in the SDK, adding a new token transaction type (of sorts), additions to the Sway standard library, and further potential for adjustments should be further examined. Causes backwards compatible issues for nodes that can’t use the new transaction type to create non-fungible tokens should still be able to interact with them given that AssetId is a valid field presently.

Citation

Zachary Kornberg (@crypdoughdoteth), Furnic, "FIP-1: “Introduce Non-Fungible Tokens to the UTXO Set”, Fuel Improvement Proposal, No. 1, February 2023. [Online serial], Available: [FIP-1] Introduce Non-Fungible Tokens to the UTXO Set

Just a point of clarification: for the bitwise XOR operation:
given A = B ^ C, then
C = A ^ B, and
B = A ^ C

so we must always know 2 of the 3 values, and can then recover the third.

1 Like