forked from onflow/nft-catalog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNonFungibleToken.cdc
144 lines (112 loc) · 4.71 KB
/
NonFungibleToken.cdc
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
## The Flow Non-Fungible Token standard
## `NonFungibleToken` contract interface
The interface that all non-fungible token contracts could conform to.
If a user wants to deploy a new nft contract, their contract would need
to implement the NonFungibleToken interface.
Their contract would have to follow all the rules and naming
that the interface specifies.
## `NFT` resource
The core resource type that represents an NFT in the smart contract.
## `Collection` Resource
The resource that stores a user's NFT collection.
It includes a few functions to allow the owner to easily
move tokens in and out of the collection.
## `Provider` and `Receiver` resource interfaces
These interfaces declare functions with some pre and post conditions
that require the Collection to follow certain naming and behavior standards.
They are separate because it gives the user the ability to share a reference
to their Collection that only exposes the fields and functions in one or more
of the interfaces. It also gives users the ability to make custom resources
that implement these interfaces to do various things with the tokens.
By using resources and interfaces, users of NFT smart contracts can send
and receive tokens peer-to-peer, without having to interact with a central ledger
smart contract.
To send an NFT to another user, a user would simply withdraw the NFT
from their Collection, then call the deposit function on another user's
Collection to complete the transfer.
*/
// The main NFT contract interface. Other NFT contracts will
// import and implement this interface
//
pub contract interface NonFungibleToken {
// The total number of tokens of this type in existence
pub var totalSupply: UInt64
// Event that emitted when the NFT contract is initialized
//
pub event ContractInitialized()
// Event that is emitted when a token is withdrawn,
// indicating the owner of the collection that it was withdrawn from.
//
// If the collection is not in an account's storage, `from` will be `nil`.
//
pub event Withdraw(id: UInt64, from: Address?)
// Event that emitted when a token is deposited to a collection.
//
// It indicates the owner of the collection that it was deposited to.
//
pub event Deposit(id: UInt64, to: Address?)
// Interface that the NFTs have to conform to
//
pub resource interface INFT {
// The unique ID that each NFT has
pub let id: UInt64
}
// Requirement that all conforming NFT smart contracts have
// to define a resource called NFT that conforms to INFT
pub resource NFT: INFT {
pub let id: UInt64
}
// Interface to mediate withdraws from the Collection
//
pub resource interface Provider {
// withdraw removes an NFT from the collection and moves it to the caller
pub fun withdraw(withdrawID: UInt64): @NFT {
post {
result.id == withdrawID: "The ID of the withdrawn token must be the same as the requested ID"
}
}
}
// Interface to mediate deposits to the Collection
//
pub resource interface Receiver {
// deposit takes an NFT as an argument and adds it to the Collection
//
pub fun deposit(token: @NFT)
}
// Interface that an account would commonly
// publish for their collection
pub resource interface CollectionPublic {
pub fun deposit(token: @NFT)
pub fun getIDs(): [UInt64]
pub fun borrowNFT(id: UInt64): &NFT
}
// Requirement for the the concrete resource type
// to be declared in the implementing contract
//
pub resource Collection: Provider, Receiver, CollectionPublic {
// Dictionary to hold the NFTs in the Collection
pub var ownedNFTs: @{UInt64: NFT}
// withdraw removes an NFT from the collection and moves it to the caller
pub fun withdraw(withdrawID: UInt64): @NFT
// deposit takes a NFT and adds it to the collections dictionary
// and adds the ID to the id array
pub fun deposit(token: @NFT)
// getIDs returns an array of the IDs that are in the collection
pub fun getIDs(): [UInt64]
// Returns a borrowed reference to an NFT in the collection
// so that the caller can read data and call methods from it
pub fun borrowNFT(id: UInt64): &NFT {
pre {
self.ownedNFTs[id] != nil: "NFT does not exist in the collection!"
}
}
}
// createEmptyCollection creates an empty Collection
// and returns it to the caller so that they can own NFTs
pub fun createEmptyCollection(): @Collection {
post {
result.getIDs().length == 0: "The created collection must be empty!"
}
}
}