Skip to main content

Non-Fungible Token On-chain storage (TIP-4.4)

Requires: TIP-4.1 Requires: TIP-6.1

Abstract

Using the Storage contract, you can store NFT-related bytes in blockchain

Motivation

Fault tolerance. If off-chain services are unavailable, the user will view NFT-related bytes, because it is stored on-chain.

Specification

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119

Contracts

  • Collection - TIP4.1 contract that minted token and store Storage contract code
  • NFT - TIP4.1 contract that store token information and Storage contract address
  • Storage - contract that store token byte content. Storage is independent. Storage doesn’t store NFT address because NFT contract address can be changed by burning and redeployment from another collection.

Collection

Every TIP-4.1 Collection contract must implement TIP4_4Collection

pragma ton-solidity >= 0.58.0;

interface TIP4_4Collection {
function storageCode() external view responsible returns (TvmCell code);
function storageCodeHash() external view responsible returns (uint256 codeHash);
function resolveStorage(address nft) external view responsible returns (address addr);
}

NOTE The TIP-6.1 identifier for this interface is 0x6302A6F8

TIP4_4Collection.storageCode()

function storageCode() external view responsible returns (TvmCell code);
  • code (TvmCell) - storage contract code

TIP4_4Collection.storageCode()

function storageCodeHash() external view responsible returns (uint256 hash);
  • hash (uint256) - storage contract code hash

TIP4_4Collection.resolveStorage()

function resolveStorage(address nft) external view responsible returns (address addr);
  • nft (address) - token contract address
  • addr (address) - storage contract address

NFT

Every TIP-4.1 NFT contract must implement TIP4_4NFT

pragma ton-solidity >= 0.58.0;

interface TIP4_4NFT {
function onStorageFillComplete(address gasReceiver) external;
function getStorage() external view responsible returns (address addr);
}

NOTE The TIP-6.1 identifier for this interface is 0x009DC09A

TIP4_4NFT.onStorageFillComplete()

function onStorageFillComplete(address gasReceiver) external;
  • gasReceiver (address) - address of contract that receive all remaining contract balance then last chunk filled Calling the Storage.fill() on storage contract that fills the last chunk should call TIP4_4NFT.onStorageFillComplete() on token contract

TIP4_4NFT.getStorage()

function getStorage() external view responsible returns (address addr);
  • addr (address) - storage contract address

Storage

Every Storage contract must implement TIP4_4Storage

pragma ton-solidity >= 0.58.0;

interface TIP4_4Storage {
function fill(uint32 id, bytes chunk, address gasReceiver) external;
function getInfo() external view responsible returns (
address nft,
address collection,
string mimeType,
mapping(uint32 => bytes) content,
string contentEncoding
);
}

NOTE The TIP-6.1 identifier for this interface is 0x204D6296

TIP4_4Storage.fill()

function fill(uint32 id, bytes chunk, address gasReceiver) external;
  • id (uint32) - chunk number. From 0 to 4 294 967 295
  • bytes (chunk) - data. Max size of data is limited by external message payload size. Maximum size external message payload size is 16KB at 2022-03-18.
  • gasReceiver (address) - address of contract that receive all remaining contract balance then last chunk filled.

TIP4_4Storage.getInfo()

function getInfo() external view responsible returns (
address nft,
address collection,
string mimeType,
mapping(uint32 => bytes) chunks,
string contentEncoding
);
  • nft (address) - token contract address
  • collection (address) - collection token contract address
  • mimeType (string) - MIME types are defined and standardized in IETF's RFC 6838
  • content (mapping(uint32 => bytes)) - byte content. Maximum content size is 4 294 967 295 chunks * chunk size. Max size of data is limited by external message payload size. Maximum size external message payload size is 16KB at 2022-03-18 Maximum content size is 4 294 967 295 * 16KB ≈ 69TB at 2022-03-18.
  • contentEncoding (string) - Was it compressed by any algorithm. If it was compressed with zstd contentEncoding need to be zstd, all other need to be like http content encoding

Visualization

Legend

Legend Legend

NFT minting with Storage

Storage

Storage filling

Storage

Storage with Index

How to interaction on-chain indexes and Storage contracts Storage