Skip to main content
Some protocols need to store a lot of information in contracts, for example, token contracts with many users. In TON, there is a limit on how much can be stored in a single contract. The solution is to split the data across multiple contracts. Each such contract, referred to as a child contract, is associated with a key that determines its address within a parent contract. Some protocols also introduce a parent contract that coordinates child contracts.

Child contract address by key

The contract address depends on the initial data provided in StateInit. To ensure that a child contract can be accessed using only the key within a specific parent, the initial data includes the key and the parent address, but does not include the associated value. As a result, the address of the child contract can be determined from the parent address and key alone.

NFT and jetton examples

Consider NFTs: the collection acts as the parent contract, and each NFT item is a child contract. The key in this case is the item index, and only the collection can set the initial owner. For jettons, the parent contract is the minter, and the child contracts are user wallets. The key is the wallet’s smart contract address. Both patterns follow the same principle: each key maps to a separate contract. In jetton protocols, there is a unique wallet contract per user, while in NFT collections, there is a unique item contract per NFT index, regardless of who owns the item.

Unbounded data structures

Contract sharding supports an unbounded number of potential child contracts. In general, data structures that can scale to very large sizes are difficult to implement efficiently on blockchains. This pattern allows such scaling by distributing data across multiple contracts. The following example shows a parent contract that deploys child contracts and assigns each child a sequence number. The shared storage file defines the data layouts and message types used by both contracts.
storage.tolk
The child contract stores the parent address in its initial data and accepts the Identify message only from that parent.
child.tolk
The parent contract owns the deployment logic. It derives each child address from the parent address, the child sequence number, and the child code.
parent.tolk