Skip to content

Instantly share code, notes, and snippets.

@harry830622
Created February 27, 2022 06:23
Show Gist options
  • Save harry830622/d40f4968bcb72b71b731fd2049f0d963 to your computer and use it in GitHub Desktop.
Save harry830622/d40f4968bcb72b71b731fd2049f0d963 to your computer and use it in GitHub Desktop.
// 這裡定義一個卡片 collection 可以公開的介面,基本上就是一些非提領或是改動的動作
// 像是將卡片加入帳戶 collection、存取帳戶 collection 中有哪些卡片等等
pub resource interface MomentCollectionPublic {
pub fun deposit(token: @NonFungibleToken.NFT)
pub fun batchDeposit(tokens: @NonFungibleToken.Collection)
pub fun getIDs(): [UInt64]
pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
pub fun borrowMoment(id: UInt64): &TopShot.NFT? {
// If the result isn't nil, the id of the returned reference
// should be the same as the argument to the function
post {
(result == nil) || (result?.id == id):
"Cannot borrow Moment reference: The ID of the returned reference is incorrect"
}
}
}
// Collection 就是帳戶的 NBA Top Shot 收藏,裡面包含某個帳戶所有的卡片收藏
// 除了實作了本合約的 MomentCollectionPublic 介面
// 也實作了官方的 NFT Provider/Receiver、CollectionPublic 介面讓收藏可以加入卡片及提出卡片
// 最後也有實作 MetadataViews.ResolverCollection 介面以獲取 metadata
pub resource Collection: MomentCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
// 儲存收藏裡的所有卡片
// 是一個卡片 ID -> 卡片 NFT 的 mapping
pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
init() {
self.ownedNFTs <- {}
}
// 從收藏中提出某張卡片,
// 並發出提領某張卡片的 event
pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
// Remove the nft from the Collection
let token <- self.ownedNFTs.remove(key: withdrawID)
?? panic("Cannot withdraw: Moment does not exist in the collection")
emit Withdraw(id: token.id, from: self.owner?.address)
// Return the withdrawn token
return <-token
}
// 一次提出多張卡片到另一個 collection 並回傳
pub fun batchWithdraw(ids: [UInt64]): @NonFungibleToken.Collection {
// Create a new empty Collection
var batchCollection <- create Collection()
// Iterate through the ids and withdraw them from the Collection
for id in ids {
batchCollection.deposit(token: <-self.withdraw(withdrawID: id))
}
// Return the withdrawn tokens
return <-batchCollection
}
// 存入某張卡片至收藏中,
// 並發出存入某張卡片的 event 假如這個收藏目前是被人擁有的
pub fun deposit(token: @NonFungibleToken.NFT) {
// 嘗試 cast NFT 為卡片,確保型態正確
let token <- token as! @TopShot.NFT
// Get the token's ID
let id = token.id
// Add the new token to the dictionary
let oldToken <- self.ownedNFTs[id] <- token
// Only emit a deposit event if the Collection
// is in an account's storage
if self.owner?.address != nil {
emit Deposit(id: id, to: self.owner?.address)
}
// Destroy the empty old token that was "removed"
destroy oldToken
}
// 存入多張卡片至收藏中
pub fun batchDeposit(tokens: @NonFungibleToken.Collection) {
// Get an array of the IDs to be deposited
let keys = tokens.getIDs()
// Iterate through the keys in the collection and deposit each one
for key in keys {
self.deposit(token: <-tokens.withdraw(withdrawID: key))
}
// Destroy the empty Collection
destroy tokens
}
// 這是 MetadataViews.ResolverCollection 必須實作的一個 function
// 目的是回傳收藏中的所有卡片 ID
pub fun getIDs(): [UInt64] {
return self.ownedNFTs.keys
}
// 借用某張 NFT 的讀取權限,但這裡是官方 NFT 介面的權限,
// 所以只會有 ID 的讀取權限
pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
return &self.ownedNFTs[id] as &NonFungibleToken.NFT
}
// 借用某張卡的讀取權限,
// 就可以讀取到所有卡片相關的資訊了,
// 包含 ID, playID, setID, serial number 等等
pub fun borrowMoment(id: UInt64): &TopShot.NFT? {
if self.ownedNFTs[id] != nil {
let ref = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT
return ref as! &TopShot.NFT
} else {
return nil
}
}
// 這是 MetadataViews.ResolverCollection 必須實作的一個 function
// 目的是借用某張卡的 metadata 讀取權限,
// 包含讀取球員名字、球員生日、所屬球隊等等
pub fun borrowViewResolver(id: UInt64): &AnyResource{MetadataViews.Resolver} {
let nft = &self.ownedNFTs[id] as auth &NonFungibleToken.NFT
let topShotNFT = nft as! &TopShot.NFT
return topShotNFT as &AnyResource{MetadataViews.Resolver}
}
// 若收藏被銷毀,則收藏裡的所有卡片也會同時被銷毀
destroy() {
destroy self.ownedNFTs
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment