The second article by Roman Nguyen on True NFT. This time, Roman talks about how modern blockchains approach the issue of data storage in decentralized systems and what advantages such a complex relative to the existing token transfer model has.
What Is A Distributed Ledger?
If we talk about distributed ledger systems as such, there are a lot of implementations — from torrents and IPFS to blockchains. The approach is not new, and, lately, it has been increasingly developing towards blockchains. Blockchain, as a technology, solves a number of diverse problems, from ensuring the reliability of information to its storage. As a rule, these are the regular “key-value” pairs, where some identifier corresponds to a certain value. For example “number-balance”, “name-status” or “domain name-address”. In any blockchain with smart contracts, we will have similar structures in one way or another.
What’s The Problem With Regular Ledgers?
In general, nothing at all. The data structure itself has existed since time immemorial and has been used successfully in both centralized and decentralized systems, including blockchains. However, in blockchain any action (except reading) costs something, and in some blockchains, such as FreeTON, data storage is not free either.
In terms of data storage, the key problem is always the limitations of the media — a conditionally infinite ledger requires a conditionally infinite amount of storage. In real life, we can think of a large data center as a kind of single media, which, if necessary, can be expanded. In decentralized systems (blockchains with smart contracts) this approach is not possible. It is simply impossible to store an infinite amount of data in one contract: we will inevitably run into, for example, the size of the block or catch a collision, which will lead to unpredictable consequences. This is the same as in real life, not adding new media to the data center, but building another one nearby. The comparison is very abstract, but it illustrates the situation.
Additionally, existing ledgers in blockchains, as a rule, are a large smart contract that supports a complete list of records or a tree-like solution that splits the list into parts based on certain parameters. Such solutions disappear due to lack of scalability, high maintenance costs, long search time with increasing data volume, single point of failure, and so on.
So What To Do?
A set of criteria that a solution must meet:
- it must be able to store data in key-value format;
- it must be conditionally infinitely scalable;
- it must perform crud (create read update delete) operations;
- the user experience of interacting with the solution should not differ from that of regular ledgers.
The first thing that comes to mind is that the ledger records should be divided into some parts, which will not exceed a certain maximum possible size. But creating a mass of contracts with ledger parts makes no sense, they need to be linked somehow.
You can create a blockchain on a blockchain and try to link the records to each other — that way, each record will have one or two links to similar records and will represent something like a table row. But in this case, you will have to deal with the issue of deleting and creating records, which will entail changing not only the record on which the operation is performed but also others.
Creating a central contract and remembering record references is also not suitable – even an array of line references can be conditionally infinite within one contract.
That leaves one thing — the records must be linked somehow, while not remembering the links to them. It would be nice to come up with a way to search and verify records, as well as to create and provide irreplaceable records, without having to remember the parts.
Sounds like a fantasy, but Free TON offers an elegant solution to this problem.
In regular blockchains, the contract address is usually either a public key or some hash from it. In Free TON it’s different. The address is a hash of the public key (can be taken as part of the initial data), the code of the smart contract itself, and the initial data.
Since all addresses are calculated from the contract code, public key, and initial data, we can deploy the same contract code with the same public key (usually zero), changing only its initial data. This allows you to calculate a contract address from anywhere by specifying a unique identifier in the initial data. The principle remains — we, as in a centralized ledger, can get the address of the contract, which contains data, by a unique identifier without creating a ledger as such, while completely excluding the possibility of replacing a child contract. In the latter case, when you change the address of the child contract will also change the code, leading to a change in subsequent addresses.
That is, if we put a unique ID in the contract initial data, we will get a unique address.
In general, the ledger will look like the following scheme:
But how do you get a record? The client accesses the root smart contract, which already contains the child contract code, transfers the initial data (in our example, only the identifier), and calculates the contract address. It turns out the address of the contract – an identifier that points to a ledger string.
This approach is not only possible by changing the initial data, the code itself can also be changed. A “salt” code has been added to TIP-31, which makes it possible to change the contract code without changing its functionality by adding some data structure directly to it. This is useful if you need to separate ledger lines in two different ledgers and when searching for a contract by code hash.
Issues And Security
But how do you solve the problem of “fake” contracts that can be deployed with the same parameters without referring to the parent contract?
To do this, all child contracts write the address of the parent contract in the initial data in addition to the ID. This gives you the ability to check in the constructor when deploying a contract, who deploys that contract, and whether it is parental, otherwise the message is rejected.
If this verification is removed and the contract is recompiled, the contract code will change, which will still lead to the wrong address in terms of the parent contract.
The described approach allows you to look at the blockchain from an unfamiliar angle – as a database storing the format [contract code, initial data] -> contract address. This opens the door to the world of distributed ledgers of unlimited scalability, which will undoubtedly lead to the creation of a new generation of distributed ledger systems, which is what True NFT is.