In this article, we will analyze what True NFT is, how the technology was created, its architecture, main scenarios, talk about customization options, and answer the main question — what requirements a finished system must meet to be called True NFT.
True NFT is a technology created jointly by the developer teams Surf and RSquad to implement NFT tokens based on the Free TON network.
The technology allows:
At the start of development, NFT implementations already existed in the Free TON blockchain, for example, TIP-3 NFT. Also, TIP-31 has just been released, developing the ideas of TIP-3 and providing new opportunities for developing contracts, and no one has canceled the option with the implementation of the ERC-721 analogue.
The Surf and RSquad teams were tasked with studying existing solutions and developing NFT technology for Free TON that meets the following requirements:
The study of existing solutions showed they do not fit the above requirements and have a lot of problems regarding the task. For example, the currently classic ERC-721 is conditionally unrealizable in Free TON because of large mappings, and TIP-3 forces users to deploy additional wallets for each NFT collection.
Moreover, you can send tokens only between these very wallets, whose addresses you need to know. Multiplying these problems because it is necessary to come up with a mechanism for getting all the user's tokens, knowing only his address, we get the conclusion: it is necessary to come up with something new.
As a result of brainstorming, it became obvious to the team that each NFT wallet must generate an address so that it can be found throughout the network, for example, by storing the owner's address in the initial data.
The solution would allow finding all the user's wallets that contain his tokens. This approach removed a number of abstractions from TIP-3 and brought elements of TIP-31, but still left a lot of questions:
All these questions prompted the team to conclude that it is necessary to get rid of wallets as part of the system.
As a result, the team decided, inspired by TIP-31, to create a new functionality — to store the owner of a specific token in the initial data, thereby making it searchable, keeping the address unique, and deleting the old contract, and deploying a new one when transferring the token.
Moreover, to put the data into a separate non-removable contract and create some kind of search indexes that can be recreated when the token owner changes. Thus, a way was found that led the team to the solution of the task.
The solution itself became possible due to the representation of the Free TON blockchain as a key:value storage, where key is a certain combination of the contract code and initial data, and value is the address or the contract itself.
In Free TON, there are many ways to find the right contract besides the usual "I know the address — I can pull". There are a huge number of similar contracts within the network in terms of functionality (such as contests or NFT collections), and Free TON allows you to get them all.
It is enough to understand that a contract has a code, you can take a hash from it, use GraphQL and get all the addresses where the contracts corresponding to the specified code are located.
The address in Free TON is some combination of the contract code and its initial data. Thus, knowing these two parameters used in the contract deployment, it is possible to calculate its address.
It is important to understand that the code can be changed later, but the address cannot. Therefore, searching by a code hash and collecting an address are fundamentally different things.
Before the publication of TIP-31, the ability to “salt” the contract code was added, i.e. add a data set (“salt”) to the compiled code with the subsequent ability to read it. This does not affect the mechanisms described above, but it allows you to store data not only in the initial data but also in the contract code itself, adding some flexibility to the initialization process.
Thus, we got a simple concept: to make a set of immutable system contracts that will serve as search indexes, and add to them a set of contracts that will contain customized logic and data.
Figure 1. Conceptual system architecture
Figure 1 shows a contract diagram of the resulting conceptual system. The developed system core and examples can be found in the repository.
IndexBasis, or simply basis, is a contract that is used to find all NFT collections in the network. From the diagram you can see that its code is not "salted", and the uniqueness of the address is achieved by adding a NftRoot contract address and the hash code of the Data contract. Thus, to be considered TrueNFT, each system must issue a basis for each NFT collection.
IndexOwner and IndexOwnerRoot
These contracts are combined into one group because they are essentially identical and inherit the Index contract. In other words, they have the same code, but they are needed for different purposes and are “salted” in different ways.
In both indexes, the address of the Data contract is stored in the initial data, which is a link from the index to Data. IndexOwner is “salted” with only the owner address, which allows us to search for all tokens of a specific user, and IndexOwnerRoot is “salted” with both the owner address and the NftRoot address, which allows us to find all user tokens within a specific collection in one query. Bottom line: to be considered TrueNFT, each system must issue an IndexOwner and IndexOwnerRoot for each NFT.
An NFT collection contract generally contains token-minting logic and information about a collection. It is worth noting that because the contract has a basis, implementing the contract can be completely different within different systems. The project repository and the diagram contain only an example of the basic implementation of NftRoot for a general understanding of the system concept.
The NFT token data contract, or simply NFT, contains the token data, a link to the media, usually the transfer logic, and a set of additional logic. The contract, like NftRoot, is completely customizable because the token has a different set of fields within different collections.
In the example of the basic implementation, the transfer is also implemented in Data, in order to save transactions, but in real systems, it can be moved to a separate contract or be absent altogether. To be considered TrueNFT, each system must store all NFT data in a Data contract or have links to other contracts within the network, all data from other sources is not considered part of the system.
Data includes a script to upload media and create a link to it. We will consider this aspect of the system in future publications.
We have a set of three search indexes that must be immutable within any TrueNFT systems, NftRoot and Data contracts, which contain the logic of a single system and are fully customizable.
The most important part of the technology is the transfer ownership scenario. The logic around the transfer can be absolutely any, but to be called TrueNFT, the system must preserve the NFT transition logic from one owner to another, regardless of the logic around it.
Consider a basic transfer ownership scenario in a system where the owner of a token can transfer his token to anyone. The user knows the address of the other user to whom he wants to send his NFT.
Figure 2. Transfer ownership sequence
The user enters the recipient's address in the interface and the token is transferred without additional action. The recipient can see the received token in his interface without performing any actions at all. Sounds simple. Under the hood, the user calls the transfer method from his Data contract. Next, Data deletes its search indexes, changes ownership, and deploys new indexes with a new owner in the initial data.
The data integrity is preserved. At any given time, the NFT (both in terms of indexes and in terms of the Data contract) belongs to one owner or does not belong to anyone.
Additional logic, for example, royalties to the author, can be implemented as part of the transfer ownership method itself, or there may be no method at all, and the transfer can be carried out only upon purchase — it does not matter. The important thing is that for the system to be called TrueNFT, it must preserve the logic of the transfer of ownership with the re-creation of search indexes and the change of ownership in the Data contract.
Token minting works almost the same way as a transfer.
Figure 3. Mint sequence
The user who may issue tokens calls NftRoot while transferring NFT data. NftRoot deploys the Data contract, which in turn deploys its indexes. Minting rights, the presence/absence of it as such, or minting at purchase, for example, is a customizable part of the system. At the same time, for the system to be called TrueNFT, it must preserve the logic of creating tokens with date deployment and search indexes.
In the process, specific requirements for search capabilities were formalized. The system must allow you to find everything:
As we already know, Free TON provides us with the GraphQL API as an interface for getting data from the blockchain (in fact, of course, not directly from the blockchain, but from the caching database, which gives us additional tools for searching and filtering), from which we can get addresses.
The answer to the question of why we need these indexes if we can customize the interface within each individual project is simple. As the ecosystem grows, catalogs showing all collections and wallets showing all user tokens will be created. Standardization in this matter will allow all systems that meet the standard to be automatically listed in these catalogs, simply by being deployed to the network.
We have deduced several requirements for a system to be considered TrueNFT, it must:
In the next articles, we will talk about media uploading, write our simple TrueNFT system, consider examples of receiving and displaying tokens, and discuss how to develop applications that work with decentralized ledgers in modern blockchains.
Surf & RSquad