Smart Contract
PackOpener
A.a49cc0ee46c54bfb.PackOpener
1import MotoGPAdmin from 0xa49cc0ee46c54bfb
2import MotoGPPack from 0xa49cc0ee46c54bfb
3import MotoGPCard from 0xa49cc0ee46c54bfb
4import NonFungibleToken from 0x1d7e57aa55817448
5import ContractVersion from 0xa49cc0ee46c54bfb
6
7// Contract for managing pack opening.
8//
9// A PackOpener Collection is created when a user authorizes a tx that saves a PackOpener Collection in the user's storage.
10// The user authorises transfer of a pack to the pack opener.
11// The admin accesses the pack opener to open the pack, which deposits the cards into the user's
12// card collection and destroys the pack.
13//
14pub contract PackOpener: ContractVersion {
15
16 pub fun getVersion(): String {
17 return "1.0.0"
18 }
19
20 pub event Withdraw(id: UInt64, from: Address?)
21 pub event Deposit(id: UInt64, to: Address?)
22 pub event PackOpened(packId: UInt64, packType: UInt64, cardIDs:[UInt64], serials: [UInt64])
23
24 pub resource interface IPackOpenerPublic {
25 pub fun openPack(adminRef: &MotoGPAdmin.Admin, id: UInt64, cardIDs: [UInt64], serials: [UInt64])
26 pub fun deposit(token: @MotoGPPack.NFT)
27 pub fun getIDs(): [UInt64]
28 pub fun borrowPack(id: UInt64): &MotoGPPack.NFT?
29 }
30
31 pub let packOpenerStoragePath: StoragePath
32 pub let packOpenerPublicPath: PublicPath
33
34 pub resource Collection: IPackOpenerPublic {
35
36 access(self) let packMap: @{UInt64: MotoGPPack.NFT}
37 access(self) let cardCollectionCap: Capability<&MotoGPCard.Collection{MotoGPCard.ICardCollectionPublic}>
38
39 pub fun getIDs(): [UInt64] {
40 return self.packMap.keys
41 }
42
43 pub fun deposit(token: @MotoGPPack.NFT) {
44 let id: UInt64 = token.id
45 let oldToken <- self.packMap[id] <- token
46 if self.owner?.address != nil {
47 emit Deposit(id: id, to: self.owner?.address)
48 }
49 destroy oldToken
50 }
51
52 // The withdraw method is not part of IPackOpenerPublic interface, and can only be accessed by the PackOpener collection owner
53 //
54 pub fun withdraw(withdrawID: UInt64): @MotoGPPack.NFT {
55 let token <- self.packMap.remove(key: withdrawID) ?? panic("MotoGPPack not found and can't be removed")
56 emit Withdraw(id: token.id, from: self.owner?.address)
57 return <-token
58 }
59
60 // The openPack method requires a admin reference as argument to open the pack
61 //
62 pub fun openPack(adminRef: &MotoGPAdmin.Admin, id: UInt64, cardIDs: [UInt64], serials: [UInt64]) {
63 pre {
64 adminRef != nil : "adminRef is nil"
65 cardIDs.length == serials.length : "cardIDs and serials are not same length"
66 UInt64(cardIDs.length) == UInt64(3) : "cardsIDs.length is not 3"
67 }
68
69 let cardCollectionRef = self.cardCollectionCap.borrow()!
70 let pack <- self.withdraw(withdrawID: id)
71 var tempCardCollection <- MotoGPCard.createEmptyCollection()
72 let numberOfCards: UInt64 = UInt64(cardIDs.length)
73
74 var i: UInt64 = 0
75 while i < numberOfCards {
76 let tempCardID = cardIDs[i]
77 let tempSerial = serials[i]
78 let newCard <- MotoGPCard.createNFT(cardID: tempCardID, serial: tempSerial)
79 tempCardCollection.deposit(token: <-newCard)
80 i = i + (1 as UInt64)
81 }
82 cardCollectionRef.depositBatch(cardCollection: <-tempCardCollection)
83
84 emit PackOpened(packId: id, packType: pack.packInfo.packType, cardIDs: cardIDs, serials: serials)
85
86 destroy pack
87 }
88
89 pub fun borrowPack(id: UInt64): &MotoGPPack.NFT? {
90 return &self.packMap[id] as &MotoGPPack.NFT?
91 }
92
93 init(_cardCollectionCap: Capability<&MotoGPCard.Collection{MotoGPCard.ICardCollectionPublic}>){
94 self.packMap <- {}
95 self.cardCollectionCap = _cardCollectionCap
96 }
97
98 destroy(){
99 destroy self.packMap
100 }
101 }
102
103 pub fun createEmptyCollection(cardCollectionCap: Capability<&MotoGPCard.Collection{MotoGPCard.ICardCollectionPublic}>): @Collection {
104 return <- create Collection(_cardCollectionCap: cardCollectionCap)
105 }
106
107 init(){
108 self.packOpenerStoragePath = /storage/motogpPackOpenerCollection
109 self.packOpenerPublicPath = /public/motogpPackOpenerCollection
110 }
111
112}