Native non-fungible token standard #492
Replies: 11 comments 20 replies
-
FVM has the ability of provable storage, which can perform the "mint" operation while verifying that the data is stored in filecoin for a long time. Then matadata will be more expressive than ERC721's TokenUrl, not limited to external url links, but can be directly represented by CID, SVG, JSON, HTML, etc. |
Beta Was this translation helpful? Give feedback.
-
Thanks @alexytsu! Regarding the |
Beta Was this translation helpful? Give feedback.
-
Similar applies to TransferFrom. By reference to FRC-0046, only the balances are returned, not the transferred amount. |
Beta Was this translation helpful? Give feedback.
-
For |
Beta Was this translation helpful? Give feedback.
-
It looks like we're missing an |
Beta Was this translation helpful? Give feedback.
-
It is interesting that the Adding the from address would require either limiting the batching scope to a single owner (by specifying a single
Even more interesting is the lack of A more complicated data structure could again describe a batch of tokens associated with different |
Beta Was this translation helpful? Give feedback.
-
I think the pagination API is not quite sufficient. We're not mandating that token IDs be dense, small integers. Without knowing the range of IDs, a caller can't choose good initial values for pagination. E.g. there may be zero IDs in the range (0, 1000), but the return value of an empty list doesn't carry any information about whether there are tokens with higher IDs. I suggest that the parameters might instead be |
Beta Was this translation helpful? Give feedback.
-
Re approval semantics, ERC-721
This suggests that an address that was nominated via SetApprovalForAll can approve other addresses for specific tokens. But it can't call SetApprovalForAll, and neither can an address approved for a single token approve some other address for that token. So, should we follow the prior art in this case of allowing an account-wide authorised operator to delegate operation of specific tokens? |
Beta Was this translation helpful? Give feedback.
-
I'm not sure what the right solution is right now, but having Would explorers not have an explicit list of known NFT actor types to symbols? I assume that's the only secure way to do it (again, without a registry). |
Beta Was this translation helpful? Give feedback.
-
Enumerable TokenIDs Counts and bitfields are tricky. There will likely be counts for which the bitfield may be too large to return in one go, but that depends on the bitfield and how packed it is. I would consider instead defining this method as: fn ListTokens(rangeStart: TokenID) -> {tokens: TokenList, more: bool} That way, the actor can decide how many to return based on how sparse the bitfield is. For example, it might want to return some number of ranges of token IDs rather than a specific number of token IDs. |
Beta Was this translation helpful? Give feedback.
-
One divergence from the fungible token is that this currently uses u64 for balances (including total supply). I feel a bit uneasy about this. On the one hand, it's a pretty big number, and it goes with u64 for token IDs. But on the other hand, I'm nervous this will limit some applications in the future of vastly abundant, almost fungible tokens. An alternative is |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Non-Fungible Token Standard
Simple Summary
A standard interface for native actor non-fungible tokens (NFTs).
Abstract
This proposal provides a standard API for the implementation of non-fungible
tokens (NFTs) as FVM native actors. The proposal learns from NFT standards
developed for other blockchain ecosystems, being heavily inspired by
ERC-721. However, as a design goal,
this proposal aims to complement the existing fungible token interface described
in FRC-0046. As such
it brings along equivalent specifications for:
front-running
The interface has been designed with gas-optimisations in mind and hence methods
support batch-operations where practical.
Change Motivation
The concept of a non-fungible token is widely established in other blockchains.
As on other blockchains, a complementary NFT standard to FRC-0046 allows the
ownership of uniquely identifiable assets to be tracked on-chain. The Filecoin
ecosystem will benefit from a standard API implemented by these actors. A
standard permits easy building of UIs, wallets, tools, and higher level
applications on top of a variety of tokens representing different assets.
Specification
Methods and types are described with a Rust-like pseudocode. All parameters and
return types are IPLD types in a CBOR tuple encoding.
Methods are to be dispatched according to the calling convention described in
FRC-0042.
Interface
An actor implementing a FRC-00XX token must provide the following methods.
Receiver Interface
An actor must implement a receiver hook to receive NFTs. The receiver hook is
defined in FRC-0046 and must not abort when handling an incoming token. When
transferring batch of tokens, the receiver hook is invoked once meaning the
entire set of NFTs is either accepted or rejected (by aborting).
Behaviour
Universal receiver hook
The NFT collection must invoke the receiver hook method on the receiving address
whenever it credits tokens. The
type
parameter must beFRCXXTokenType
andthe payload must be the IPLD-CBOR serialized
FRCXXTokensReceived
structure.The attempted credit is only persisted if the receiver hook is implemented and
does not abort. A mint or transfer operation should abort if the receiver hook
does, or in any case must not credit tokens to that address.
Minting
API methods for minting are left unspecified. A newly minted token cannot have
the same ID as an existing token or a token that was previously burned. Minting
must invoke the receiver hook on the receiving address and fail if it aborts.
Transfers
Empty transfers are allowed, including when the
from
address has zero balance.An empty transfer must invoke the receiver hook of the
to
address and abort ifthe hook aborts. An empty transfer can thus be used to send messages between
actors in the context of a specific NFT collection.
Operators
Operators can be approved at two separate levels.
Token level operators are approved by the owner of the token via the
Approve
method. If an account is an operator on a token, it is permitted to debit (burn
or transfer) that token. An NFT can have many operators at a time, but
transferring the token will revoke approval on all its existing operators.
Account level operators are approved via the
ApproveForAll
method. If anowner approves an operator at the account level, that operator has permission to
debit any token belonging to the owner's account. This includes tokens that are
not yet owned by the account at the time of approval.
Addresses
Addresses for receivers and operators must be resolvable to an actor ID.
Balances must only be credited to an actor ID. All token methods must attempt to
resolve addresses provided in parameters to actor IDs. A token should attempt to
initialise an account for any address which cannot be resolved by sending a
zero-value transfer of the native token to the address.
Note that this means that an uninitialized actor-type (f2) address cannot
receive tokens or be authorized as an operator. Future changes to the FVM may
permit initialization of such addresses by sending a message to them, in which
case they should automatically become functional for this standard.
Extensions
An NFT collection may implement other methods for transferring tokens and
managing operators. These must maintain the invariants about supply and
balances, and invoke the receiver hook when crediting tokens.
An NFT collection may implement restrictions on allowances and transfer of
tokens.
Optional Extension - Enumerable NFT
An actor may choose to implement a method to retrieve the list of all
circulating NFTs.
When listing tokens, the NFT actor should return the list of all currently
circulating NFTs in the range
[mintokenID, maxTokenID)
.Design Rationale
Batching
Methods on this interface accept a list of token_ids. It is up to specific
implementations how duplicates, invalid IDs etc. are handled. The reference
implementation, for example aborts the entire transfer if any of the specified
token IDs are invalid.
However, it may be desirable for some implementations partially succeed for
batch operations. For example, the intent to
Revoke
operator status on a setof TokenIDs can succeed even if some of the TokenIDs are burnt or no longer
owned by the caller to promote security. Methods should inform the caller which
TokenIDs were succesfully acted upon in the return. It is recommended to return
an empty list rather than abort when no TokenIDs are valid.
Synergy with fungible tokens
In order for higher synergy with the existing FRC-0046 fungible token standard,
this proposal aims for a conceptually similar interface in terms of balances,
supply and operators. For the same safety reasons described in FRC-0046, this
token standard requires a universal receiver on actors that wish to hold tokens.
This allows easier interactions between fungible tokens and NFTs and opens
possibilities for composition of the the two standards to represent different
structures of ownership such as fractionalized NFTs or semi-fungible tokens.
Instead of encoding such semantics directly into the standard, a minimal
interface is proposed instead to make the primary simple use cases more
efficient and straightforward.
Transfers
There is no technical need to separate the
Transfer
andTransferFrom
methods. A transfer method could function given only the list of token ids that
the caller wishes to transfer and for each token asserts that:
However, the authors judge that the benefit of aligning with existing
conventions (FRC-46, ERC-721 etc.) and having separate flows for operators and
token owners will reduce risk of mistakes and unexpected behaviour.
Backwards Compatability
There are no implementatons of NFT collections yet on Filecoin.
Test Cases
Extensive test cases are present in the implementation of this proposal at
https://github.com/helix-onchain/filecoin/tree/main/frcxx_nft.
Security Considerations
Reentrancy
Receiver hooks introduce the possibility of complex call flows, the most
concerning of which might be a malicious receiver that calls back to a token
actor in an attempt to exploit a re-entrancy bug. We expect that one or more
high quality reference implementations of the token state and logic will keep
the vast majority of NFT actors safe. We judge the risk to more complex actors
as lesser than the aggregate risk of losses due to misdirected transfers.
Incentive Considerations
N/A
Product Considerations
??
Implementation
An implementation of this standard is in development at
https://github.com/helix-onchain/filecoin/tree/main/frcxx_nft.
Copyright
Copyright and related rights waived via
CC0.
Beta Was this translation helpful? Give feedback.
All reactions