Cadence Cookbook

Contribute

Minting a Moment in TopShot Set

Minting a Moment in TopShot Set

01 Apr 2022

Contributed by Flow Blockchain

Intermediate

You've added plays in your set, now it's time to mint them. This code will mint moments or plays in your TopShot sets.

Smart Contract Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 //More TopShot Code Above pub resource Set { // mintMoment mints a new Moment and returns the newly minted Moment // // Parameters: playID: The ID of the Play that the Moment references // // Pre-Conditions: // The Play must exist in the Set and be allowed to mint new Moments // // Returns: The NFT that was minted // pub fun mintMoment(playID: UInt32): @NFT { pre { self.retired[playID] != nil: "Cannot mint the moment: This play doesn't exist." !self.retired[playID]!: "Cannot mint the moment from this play: This play has been retired." } // Gets the number of Moments that have been minted for this Play // to use as this Moment's serial number let numInPlay = self.numberMintedPerPlay[playID]! // Mint the new moment let newMoment: @NFT <- create NFT(serialNumber: numInPlay + UInt32(1), playID: playID, setID: self.setID) // Increment the count of Moments minted for this Play self.numberMintedPerPlay[playID] = numInPlay + UInt32(1) return <-newMoment } // batchMintMoment mints an arbitrary quantity of Moments // and returns them as a Collection // // Parameters: playID: the ID of the Play that the Moments are minted for // quantity: The quantity of Moments to be minted // // Returns: Collection object that contains all the Moments that were minted // pub fun batchMintMoment(playID: UInt32, quantity: UInt64): @Collection { let newCollection <- create Collection() var i: UInt64 = 0 while i < quantity { newCollection.deposit(token: <-self.mintMoment(playID: playID)) i = i + UInt64(1) } return <-newCollection } .... } .... pub struct MomentData { // The ID of the Set that the Moment comes from pub let setID: UInt32 // The ID of the Play that the Moment references pub let playID: UInt32 // The place in the edition that this Moment was minted // Otherwise know as the serial number pub let serialNumber: UInt32 init(setID: UInt32, playID: UInt32, serialNumber: UInt32) { self.setID = setID self.playID = playID self.serialNumber = serialNumber } } .... // The resource that represents the Moment NFTs // pub resource NFT: NonFungibleToken.INFT { // Global unique moment ID pub let id: UInt64 // Struct of Moment metadata pub let data: MomentData init(serialNumber: UInt32, playID: UInt32, setID: UInt32) { // Increment the global Moment IDs TopShot.totalSupply = TopShot.totalSupply + UInt64(1) self.id = TopShot.totalSupply // Set the metadata struct self.data = MomentData(setID: setID, playID: playID, serialNumber: serialNumber) emit MomentMinted(momentID: self.id, playID: playID, setID: self.data.setID, serialNumber: self.data.serialNumber) } // If the Moment is destroyed, emit an event to indicate // to outside ovbservers that it has been destroyed destroy() { emit MomentDestroyed(id: self.id) } } ... //More TopShot Code below

You would find the function the mint a moment in your Set resource. To mint a moment you would call on this function and input the playID you would like to mint.

Remember when we added our play to the set we intialized the moments as 0 so when you mint a moment it will add 1 to that minted moment per play. Before we mint however, we check to see if the play exists in the set or if the play is retired.

If not, we then get the number of moments minted for this play and store that number variable in numInPlay. We would then mint a new Moment as an NFT resource type. We would send in all the parameters specified for the NFT and once we mint that new Moment we then increase the number of moments minted for this play by one.

We then return the moment with is of an NFT resource type, to later be stored in a collection in a receivers account.

We could also batch mint these moments. This would save a lot of time if you wanted to mint 60,000 moments. When doing this, you would have to create a collection resource that would deposit all of the minted NFTS into it.

Once that happens you would return the collection resource and then deposit that into the receivers collection.

Transaction Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import TopShot from 0x01 transaction { let admin: &TopShot.Admin let borrowedSet: &TopShot.Set prepare(acct: AuthAccount) { self.admin = acct.borrow<&TopShot.Admin>(from: /storage/TopShotAdmin) ?? panic("Cant borrow admin resource") self.borrowedSet = self.admin.borrowSet(setID: 1) let recieverRef = acct.getCapability<&{TopShot.MomentCollectionPublic}>(/public/MomentCollection).borrow() ?? panic("Can't borrow collection ref") let collection <- self.borrowedSet.batchMintMoment(playID: 3, quantity: 3) recieverRef.batchDeposit(tokens: <- collection) } execute{ log("plays minted") } }

To mint a moment you will need to borrow a reference to the admin resource from the Auth Account.

Once you do, you will need to borrow the set that you would like access to by calling the borrowSet function. This gets whatever setID is created that you want to have access to.

You will also need to have the capability to receive the NFT or NFTS for the receiving account referenced.

In this case we use the batchMintMoment to return a collection of minted NFTS that we can store it into the receivers collection.

Then we specify what playID we would like to mint and how many moments will be minted. After that we deposit the collection that is returned into the receivers account.


ProgressNFT Fundamentals

100%


Related Recipes

14 Oct 2022
Mint NFT
Beginner
14 Oct 2022
Collection for Holding NFTs
Beginner
14 Oct 2022
NFT with Metadata
Beginner