This page lists common examples of working with NFTs .
Accepting NFT ownership assignment
Notification message of assigned NFT ownership has the following structure:
message ( 0x05138d91 ) NFTOwnershipAssigned {
forwardPayload : Slice as remaining ;
▶️ Open in Web IDE
Use receiver function to accept notification message.
Validation can be done in two ways:
Directly store the NFT item address and validate against it.
message ( 0x05138d91 ) NFTOwnershipAssigned {
forwardPayload : Slice as remaining ;
contract SingleNft with Deployable {
init ( nftItemAddress : Address ) {
self . nftItemAddress = nftItemAddress ;
receive ( msg : NFTOwnershipAssigned ) {
require ( self . nftItemAddress == sender (), "NFT contract is not the sender" );
// your logic of processing nft ownership assign notification
▶️ Open in Web IDE
Use StateInit
and derived address of the NFT item.
message ( 0x05138d91 ) NFTOwnershipAssigned {
forwardPayload : Slice as remaining ;
collectionAddress : Address ;
inline fun calculateNFTAddress ( index : Int , collectionAddress : Address , nftCode : Cell ): Address {
let initData = NFTItemInitData {
return contractAddress ( StateInit { code : nftCode , data : initData . toCell ()});
contract NftInCollection with Deployable {
nftCollectionAddress : Address ;
nftItemIndex : Int as uint64 ;
init ( nftCollectionAddress : Address , nftItemIndex : Int , nftCode : Cell ) {
self . nftCollectionAddress = nftCollectionAddress ;
self . nftItemIndex = nftItemIndex ;
receive ( msg : NFTOwnershipAssigned ) {
let expectedNftAddress = calculateNFTAddress ( self . nftItemIndex , self . nftCollectionAddress , self . nftCode ); // or you can even store expectedNftAddress
require ( expectedNftAddress == sender (), "NFT contract is not the sender" );
// your logic of processing nft ownership assign notification
▶️ Open in Web IDE
Since the initial data layout of the NFT item can vary, the first approach is often more suitable.
Transferring NFT item
To send NFT item transfer use send ()
function.
message ( 0x5fcc3d14 ) NFTTransfer {
newOwner : Address ; // address of the new owner of the NFT item.
responseDestination : Address ; // address where to send a response with confirmation of a successful transfer and the rest of the incoming message coins.
customPayload : Cell ? = null ; // optional custom data. In most cases should be null
forwardAmount : Int as coins ; // the amount of nanotons to be sent to the new owner.
forwardPayload : Slice as remaining ; // optional custom data that should be sent to the new owner.
init ( nftItemAddress : Address ) {
self . nftItemAddress = nftItemAddress ;
// ... add more code from previous examples ...
// FIXME : Change this according to your needs
responseDestination : myAddress (),
forwardPayload : rawSlice ( "F" ), // precomputed beginCell().storeUint(0xF, 4).endCell().beginParse()
▶️ Open in Web IDE
Get NFT static info
Note, that TON Blockchain does not allow contracts to call each other getters .
In order to receive data from another contract, you must exchange messages.
message ( 0x2fcb26a2 ) NFTGetStaticData {
message ( 0x8b771735 ) NFTReportStaticData {
collectionAddress : Address ;
inline fun calculateNFTAddress ( index : Int , collectionAddress : Address , nftCode : Cell ): Address {
let initData = NFTItemInitData {
return contractAddress ( StateInit { code : nftCode , data : initData . toCell ()});
nftCollectionAddress : Address ;
nftItemIndex : Int as uint64 ;
init ( nftCollectionAddress : Address , nftItemIndex : Int , nftCode : Cell ) {
self . nftCollectionAddress = nftCollectionAddress ;
self . nftItemIndex = nftItemIndex ;
// ... add more code from previous examples ...
receive ( "get static data" ) {
// FIXME : Put proper address("[NFT_ADDRESS]") here
let nftAddress = sender ();
receive ( msg : NFTReportStaticData ) {
let expectedNftAddress = calculateNFTAddress ( msg . index , msg . collection , self . nftCode );
require ( expectedNftAddress == sender (), "NFT contract is not the sender" );
// Save nft static data or do something
▶️ Open in Web IDE
Get NFT royalty params
NFT royalty params are described here .
message ( 0x693d3950 ) NFTGetRoyaltyParams {
message ( 0xa8cb00ad ) NFTReportRoyaltyParams {
numerator : Int as uint16 ;
denominator : Int as uint16 ;
nftCollectionAddress : Address ;
init ( nftCollectionAddress : Address ) {
self . nftCollectionAddress = nftCollectionAddress ;
// ... add more code from previous examples ...
receive ( "get royalty params" ) {
to : self . nftCollectionAddress ,
body : NFTGetRoyaltyParams {
receive ( msg : NFTReportRoyaltyParams ) {
require ( self . nftCollectionAddress == sender (), "NFT collection contract is not the sender" );
▶️ Open in Web IDE
NFT Collection methods
Note that only NFT owners are allowed to use these methods.
Deploy NFT
itemIndex : Int as uint64 ;
amount : Int as coins ; // amount to sent when deploying nft
nftCollectionAddress : Address ;
init ( nftCollectionAddress : Address ) {
self . nftCollectionAddress = nftCollectionAddress ;
// ... add more code from previous examples ...
to : self . nftCollectionAddress ,
nftContent : beginCell (). endCell () // FIXME : Should be your content, mostly generated offchain
▶️ Open in Web IDE
Change owner
message ( 0x3 ) NFTChangeOwner {
nftCollectionAddress : Address ;
init ( nftCollectionAddress : Address ) {
self . nftCollectionAddress = nftCollectionAddress ;
// ... add more code from previous examples ...
receive ( "change owner" ) {
to : self . nftCollectionAddress ,
// FIXME : Put proper address("NEW_OWNER_ADDRESS") here
▶️ Open in Web IDE