Hi, I am tweaking NFT tutorial transaction to withdraw NFT which I minted and append into an array in the transaction as follows.
execute {
let myCollections:[@NonFungibleToken.NFT] = []
log("NFT Minted and deposited to Account 2's Collection")
let firstRound = self.minterRef.mintNFT(nfts: 3, recipient: self.receiverRef)
for element in firstRound {
log(element)
myCollections.append(<- self.collectionRef.withdraw(withdrawID: element))
}
}
However, I am getting unexpected token in type: '@' at let myCollections:[@NonFungibleToken.NFT] = [].
If I take that out, then I get missing resource annotation: @as well asincorrect transfer operation. expected `<-``
The following seems almost working except that I get loss of resource.
execute {
let myCollections:@[NonFungibleToken.NFT] <- []
log("NFT Minted and deposited to Account 2's Collection")
let firstRound = self.minterRef.mintNFT(nfts: [], recipient: self.receiverRef)
for element in firstRound {
log(element)
myCollections.append(<- self.collectionRef.withdraw(withdrawID: UInt64(element)))
}
}
It turns out that I cannot iterate array of asset, so decided to change to use Collection.
The code has no error but when I run, I get the following error.
WARN[0048] ERR [feba0b] Execution failed:
unexpectedly found nil while forcing an Optional value
Here is my Mint function (the rest hasnโt changed)
pub fun mintNFT(nfts: &Collection, recipient: &AnyResource{NFTReceiver}): [Int] {
var a = 0
var ids: [UInt64] = nfts.getIDs()
var nftLength = ids.length
var newIds: [Int] = []
if nftLength == 0 {
var newNFT <- create NFT(initID: self.idCount)
recipient.deposit(token: <-newNFT)
self.idCount = self.idCount + UInt64(1)
return [Int(self.idCount)]
}
while a < nftLength {
// create a new NFT
var newNFT <- create NFT(initID: self.idCount)
// deposit it in the recipient's account using their reference
recipient.deposit(token: <-newNFT)
recipient.deposit(token: <-nfts.withdraw(withdrawID: ids[a]))
// change the id so that each ID is unique
self.idCount = self.idCount + UInt64(1)
newIds.append(Int(self.idCount))
newIds.append(Int(ids[a]))
a = a + 1
}
return newIds
}
And here is the transaction
import NonFungibleToken from 0x01cf0e2f2f715450
// This transaction allows the Minter account to mint an NFT
// and deposit it into its collection.
transaction {
// The reference to the collection that will be receiving the NFT
let receiverRef: &{NonFungibleToken.NFTReceiver}
// The reference to the Minter resource stored in account storage
let minterRef: &NonFungibleToken.NFTMinter
let collectionRef: &NonFungibleToken.Collection
let myCollections: &NonFungibleToken.Collection
prepare(acct: AuthAccount) {
// Get the owner's collection capability and borrow a reference
self.receiverRef = acct.getCapability(/public/NFTReceiver)!
.borrow<&{NonFungibleToken.NFTReceiver}>()!
// Borrow a capability for the NFTMinter in storage
self.minterRef = acct.borrow<&NonFungibleToken.NFTMinter>(from: /storage/NFTMinter)!
self.collectionRef = acct.borrow<&NonFungibleToken.Collection>(from: /storage/NFTCollection)!
let collection <- NonFungibleToken.createEmptyCollection()
acct.save<@NonFungibleToken.Collection>(<-collection, to: /storage/MyCollection)
self.myCollections = acct.borrow<&NonFungibleToken.Collection>(from: /storage/MyCollection)!
}
execute {
let firstRound = self.minterRef.mintNFT(nfts: self.myCollections, recipient: self.receiverRef)
for element in firstRound {
log(element)
self.myCollections.deposit(token:<- self.collectionRef.withdraw(withdrawID: UInt64(element)))
}
for element in self.myCollections.getIDs() {
log(element)
let secondRound = self.minterRef.mintNFT(nfts: self.myCollections, recipient: self.receiverRef)
}
}
}
The full code is in this commit. I think I am almost here.
@makoto
The error you are getting: unexpectedly found nil while forcing an Optional value comes from when you use the force-unwrap operator to unwrap an optional and it finds nil.
Whenever you are trying to borrow a reference, I would always recommend using the nil-coalescing operator instead. This way, you can include an error statement so you know which one is nil
So for the first line in the transaction, you would change it to
self.receiverRef = acct.getCapability(/public/NFTReceiver)!
.borrow<&{NonFungibleToken.NFTReceiver}>()
?? panic("Could not borrow receiver reference")
Could you try that out? That will let you know which line it is coming from.
@makoto Sorry I wasnโt clear, I meant to say that you should add something like that everywhere you try to borrow a reference. Youโre right that this isnโt from that. It is from the withdraw function because you are trying to withdraw id=2 from collectionRef instead of MyCollections
Old MyCollection item is being destroyed, when transaction is executed (you probably need to rework this into check if MyCollection exists. I didnโt had time to dive into the idea, just made the whole thing functional
withdraw method on Collection now returns Optional NFT resource. This would allow you to work with optional bindings in your transaction code later. You can read more about optional bindings here: https://docs.onflow.org/docs/cadence#optional-binding