Minting a Moment in TopShot Set
Minting a Moment in TopShot Set
01 Apr 2022
Contributed by Flow Blockchain
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.
100%