@flowtyio/flow-contracts 0.0.18 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,45 +1,45 @@
1
1
  /*
2
2
  * The FlowStorageFees smart contract
3
3
  *
4
- * An account's storage capacity determines up to how much storage on chain it can use.
4
+ * An account's storage capacity determines up to how much storage on chain it can use.
5
5
  * A storage capacity is calculated by multiplying the amount of reserved flow with `StorageFee.storageMegaBytesPerReservedFLOW`
6
6
  * The minimum amount of flow tokens reserved for storage capacity is `FlowStorageFees.minimumStorageReservation` this is paid during account creation, by the creator.
7
- *
8
- * At the end of all transactions, any account that had any value changed in their storage
7
+ *
8
+ * At the end of all transactions, any account that had any value changed in their storage
9
9
  * has their storage capacity checked against their storage used and their main flow token vault against the minimum reservation.
10
10
  * If any account fails this check the transaction wil fail.
11
- *
12
- * An account moving/deleting its `FlowToken.Vault` resource will result
11
+ *
12
+ * An account moving/deleting its `FlowToken.Vault` resource will result
13
13
  * in the transaction failing because the account will have no storage capacity.
14
- *
14
+ *
15
15
  */
16
16
 
17
17
  import "FungibleToken"
18
18
  import "FlowToken"
19
19
 
20
- pub contract FlowStorageFees {
20
+ access(all) contract FlowStorageFees {
21
21
 
22
22
  // Emitted when the amount of storage capacity an account has per reserved Flow token changes
23
- pub event StorageMegaBytesPerReservedFLOWChanged(_ storageMegaBytesPerReservedFLOW: UFix64)
23
+ access(all) event StorageMegaBytesPerReservedFLOWChanged(_ storageMegaBytesPerReservedFLOW: UFix64)
24
24
 
25
25
  // Emitted when the minimum amount of Flow tokens that an account needs to have reserved for storage capacity changes.
26
- pub event MinimumStorageReservationChanged(_ minimumStorageReservation: UFix64)
26
+ access(all) event MinimumStorageReservationChanged(_ minimumStorageReservation: UFix64)
27
27
 
28
28
  // Defines how much storage capacity every account has per reserved Flow token.
29
- // definition is written per unit of flow instead of the inverse,
30
- // so there is no loss of precision calculating storage from flow,
29
+ // definition is written per unit of flow instead of the inverse,
30
+ // so there is no loss of precision calculating storage from flow,
31
31
  // but there is loss of precision when calculating flow per storage.
32
- pub var storageMegaBytesPerReservedFLOW: UFix64
32
+ access(all) var storageMegaBytesPerReservedFLOW: UFix64
33
33
 
34
34
  // Defines the minimum amount of Flow tokens that every account needs to have reserved for storage capacity.
35
35
  // If an account has less then this amount reserved by the end of any transaction it participated in, the transaction will fail.
36
- pub var minimumStorageReservation: UFix64
36
+ access(all) var minimumStorageReservation: UFix64
37
37
 
38
38
  // An administrator resource that can change the parameters of the FlowStorageFees smart contract.
39
- pub resource Administrator {
39
+ access(all) resource Administrator {
40
40
 
41
41
  // Changes the amount of storage capacity an account has per accounts' reserved storage FLOW.
42
- pub fun setStorageMegaBytesPerReservedFLOW(_ storageMegaBytesPerReservedFLOW: UFix64) {
42
+ access(all) fun setStorageMegaBytesPerReservedFLOW(_ storageMegaBytesPerReservedFLOW: UFix64) {
43
43
  if FlowStorageFees.storageMegaBytesPerReservedFLOW == storageMegaBytesPerReservedFLOW {
44
44
  return
45
45
  }
@@ -48,7 +48,7 @@ pub contract FlowStorageFees {
48
48
  }
49
49
 
50
50
  // Changes the minimum amount of FLOW an account has to have reserved.
51
- pub fun setMinimumStorageReservation(_ minimumStorageReservation: UFix64) {
51
+ access(all) fun setMinimumStorageReservation(_ minimumStorageReservation: UFix64) {
52
52
  if FlowStorageFees.minimumStorageReservation == minimumStorageReservation {
53
53
  return
54
54
  }
@@ -63,19 +63,19 @@ pub contract FlowStorageFees {
63
63
  ///
64
64
  /// Returns megabytes
65
65
  /// If the account has no default balance it is counted as a balance of 0.0 FLOW
66
- pub fun calculateAccountCapacity(_ accountAddress: Address): UFix64 {
66
+ access(all) fun calculateAccountCapacity(_ accountAddress: Address): UFix64 {
67
67
  var balance = 0.0
68
- if let balanceRef = getAccount(accountAddress)
69
- .getCapability<&FlowToken.Vault{FungibleToken.Balance}>(/public/flowTokenBalance)!
70
- .borrow() {
71
- balance = balanceRef.balance
68
+ let acct = getAccount(accountAddress)
69
+
70
+ if let balanceRef = acct.capabilities.borrow<&FlowToken.Vault>(/public/flowTokenBalance) {
71
+ balance = balanceRef.getBalance()
72
72
  }
73
73
 
74
74
  return self.accountBalanceToAccountStorageCapacity(balance)
75
75
  }
76
76
 
77
77
  /// calculateAccountsCapacity returns the storage capacity of a batch of accounts
78
- pub fun calculateAccountsCapacity(_ accountAddresses: [Address]): [UFix64] {
78
+ access(all) fun calculateAccountsCapacity(_ accountAddresses: [Address]): [UFix64] {
79
79
  let capacities: [UFix64] = []
80
80
  for accountAddress in accountAddresses {
81
81
  let capacity = self.calculateAccountCapacity(accountAddress)
@@ -86,52 +86,52 @@ pub contract FlowStorageFees {
86
86
 
87
87
  // getAccountsCapacityForTransactionStorageCheck returns the storage capacity of a batch of accounts
88
88
  // This is used to check if a transaction will fail because of any account being over the storage capacity
89
- // The payer is an exception as its storage capacity is derived from its balance minus the maximum possible transaction fees
89
+ // The payer is an exception as its storage capacity is derived from its balance minus the maximum possible transaction fees
90
90
  // (transaction fees if the execution effort is at the execution efort limit, a.k.a.: computation limit, a.k.a.: gas limit)
91
- pub fun getAccountsCapacityForTransactionStorageCheck(accountAddresses: [Address], payer: Address, maxTxFees: UFix64): [UFix64] {
91
+ access(all) fun getAccountsCapacityForTransactionStorageCheck(accountAddresses: [Address], payer: Address, maxTxFees: UFix64): [UFix64] {
92
92
  let capacities: [UFix64] = []
93
93
  for accountAddress in accountAddresses {
94
94
  var balance = 0.0
95
- if let balanceRef = getAccount(accountAddress)
96
- .getCapability<&FlowToken.Vault{FungibleToken.Balance}>(/public/flowTokenBalance)!
97
- .borrow() {
98
- if accountAddress == payer {
99
- // if the account is the payer, deduct the maximum possible transaction fees from the balance
100
- balance = balanceRef.balance.saturatingSubtract(maxTxFees)
101
- } else {
102
- balance = balanceRef.balance
103
- }
95
+ let acct = getAccount(accountAddress)
96
+
97
+ if let balanceRef = acct.capabilities.borrow<&FlowToken.Vault>(/public/flowTokenBalance) {
98
+ if accountAddress == payer {
99
+ // if the account is the payer, deduct the maximum possible transaction fees from the balance
100
+ balance = balanceRef.getBalance().saturatingSubtract(maxTxFees)
101
+ } else {
102
+ balance = balanceRef.getBalance()
103
+ }
104
104
  }
105
105
 
106
- capacities.append(self.accountBalanceToAccountStorageCapacity(balance))
106
+ capacities.append(self.accountBalanceToAccountStorageCapacity(balance))
107
107
  }
108
108
  return capacities
109
109
  }
110
110
 
111
111
  // accountBalanceToAccountStorageCapacity returns the storage capacity
112
112
  // an account would have with given the flow balance of the account.
113
- pub fun accountBalanceToAccountStorageCapacity(_ balance: UFix64): UFix64 {
113
+ access(all) view fun accountBalanceToAccountStorageCapacity(_ balance: UFix64): UFix64 {
114
114
  // get address token balance
115
115
  if balance < self.minimumStorageReservation {
116
116
  // if < then minimum return 0
117
117
  return 0.0
118
118
  }
119
119
 
120
- // return balance multiplied with megabytes per flow
120
+ // return balance multiplied with megabytes per flow
121
121
  return self.flowToStorageCapacity(balance)
122
122
  }
123
123
 
124
124
  // Amount in Flow tokens
125
125
  // Returns megabytes
126
- pub fun flowToStorageCapacity(_ amount: UFix64): UFix64 {
126
+ access(all) view fun flowToStorageCapacity(_ amount: UFix64): UFix64 {
127
127
  return amount.saturatingMultiply(FlowStorageFees.storageMegaBytesPerReservedFLOW)
128
128
  }
129
129
 
130
130
  // Amount in megabytes
131
131
  // Returns Flow tokens
132
- pub fun storageCapacityToFlow(_ amount: UFix64): UFix64 {
133
- if FlowStorageFees.storageMegaBytesPerReservedFLOW == 0.0 as UFix64 {
134
- return 0.0 as UFix64
132
+ access(all) view fun storageCapacityToFlow(_ amount: UFix64): UFix64 {
133
+ if FlowStorageFees.storageMegaBytesPerReservedFLOW == 0.0 {
134
+ return 0.0
135
135
  }
136
136
  // possible loss of precision
137
137
  // putting the result back into `flowToStorageCapacity` might not yield the same result
@@ -139,9 +139,9 @@ pub contract FlowStorageFees {
139
139
  }
140
140
 
141
141
  // converts storage used from UInt64 Bytes to UFix64 Megabytes.
142
- pub fun convertUInt64StorageBytesToUFix64Megabytes(_ storage: UInt64): UFix64 {
142
+ access(all) view fun convertUInt64StorageBytesToUFix64Megabytes(_ storage: UInt64): UFix64 {
143
143
  // safe convert UInt64 to UFix64 (without overflow)
144
- let f = UFix64(storage % 100000000 as UInt64) * 0.00000001 as UFix64 + UFix64(storage / 100000000 as UInt64)
144
+ let f = UFix64(storage % 100000000) * 0.00000001 + UFix64(storage / 100000000)
145
145
  // decimal point correction. Megabytes to bytes have a conversion of 10^-6 while UFix64 minimum value is 10^-8
146
146
  let storageMb = f.saturatingMultiply(100.0)
147
147
  return storageMb
@@ -151,14 +151,13 @@ pub contract FlowStorageFees {
151
151
  ///
152
152
  /// The available balance of an account is its default token balance minus what is reserved for storage.
153
153
  /// If the account has no default balance it is counted as a balance of 0.0 FLOW
154
- pub fun defaultTokenAvailableBalance(_ accountAddress: Address): UFix64 {
154
+ access(all) fun defaultTokenAvailableBalance(_ accountAddress: Address): UFix64 {
155
155
  //get balance of account
156
156
  let acct = getAccount(accountAddress)
157
157
  var balance = 0.0
158
- if let balanceRef = acct
159
- .getCapability(/public/flowTokenBalance)
160
- .borrow<&FlowToken.Vault{FungibleToken.Balance}>() {
161
- balance = balanceRef.balance
158
+
159
+ if let balanceRef = acct.capabilities.borrow<&FlowToken.Vault>(/public/flowTokenBalance) {
160
+ balance = balanceRef.getBalance()
162
161
  }
163
162
 
164
163
  // get how much should be reserved for storage
@@ -171,9 +170,9 @@ pub contract FlowStorageFees {
171
170
  ///
172
171
  /// The reserved balance of an account is its storage used multiplied by the storage cost per flow token.
173
172
  /// The reserved balance is at least the minimum storage reservation.
174
- pub fun defaultTokenReservedBalance(_ accountAddress: Address): UFix64 {
173
+ access(all) view fun defaultTokenReservedBalance(_ accountAddress: Address): UFix64 {
175
174
  let acct = getAccount(accountAddress)
176
- var reserved = self.storageCapacityToFlow(self.convertUInt64StorageBytesToUFix64Megabytes(acct.storageUsed))
175
+ var reserved = self.storageCapacityToFlow(self.convertUInt64StorageBytesToUFix64Megabytes(acct.storage.used))
177
176
  // at least self.minimumStorageReservation should be reserved
178
177
  if reserved < self.minimumStorageReservation {
179
178
  reserved = self.minimumStorageReservation
@@ -187,7 +186,6 @@ pub contract FlowStorageFees {
187
186
  self.minimumStorageReservation = 0.0 // or 0 kb of minimum storage reservation
188
187
 
189
188
  let admin <- create Administrator()
190
- self.account.save(<-admin, to: /storage/storageFeesAdmin)
189
+ self.account.storage.save(<-admin, to: /storage/storageFeesAdmin)
191
190
  }
192
191
  }
193
-
@@ -3,31 +3,31 @@ import "MetadataViews"
3
3
  import "FungibleTokenMetadataViews"
4
4
  import "ViewResolver"
5
5
 
6
- pub contract FlowToken: FungibleToken, ViewResolver {
6
+ access(all) contract FlowToken: ViewResolver {
7
7
 
8
8
  // Total supply of Flow tokens in existence
9
- pub var totalSupply: UFix64
9
+ access(all) var totalSupply: UFix64
10
10
 
11
11
  // Event that is emitted when the contract is created
12
- pub event TokensInitialized(initialSupply: UFix64)
12
+ access(all) event TokensInitialized(initialSupply: UFix64)
13
13
 
14
14
  // Event that is emitted when tokens are withdrawn from a Vault
15
- pub event TokensWithdrawn(amount: UFix64, from: Address?)
15
+ access(all) event TokensWithdrawn(amount: UFix64, from: Address?)
16
16
 
17
17
  // Event that is emitted when tokens are deposited to a Vault
18
- pub event TokensDeposited(amount: UFix64, to: Address?)
18
+ access(all) event TokensDeposited(amount: UFix64, to: Address?)
19
19
 
20
20
  // Event that is emitted when new tokens are minted
21
- pub event TokensMinted(amount: UFix64)
21
+ access(all) event TokensMinted(amount: UFix64)
22
22
 
23
23
  // Event that is emitted when tokens are destroyed
24
- pub event TokensBurned(amount: UFix64)
24
+ access(all) event TokensBurned(amount: UFix64)
25
25
 
26
26
  // Event that is emitted when a new minter resource is created
27
- pub event MinterCreated(allowedAmount: UFix64)
27
+ access(all) event MinterCreated(allowedAmount: UFix64)
28
28
 
29
29
  // Event that is emitted when a new burner resource is created
30
- pub event BurnerCreated()
30
+ access(all) event BurnerCreated()
31
31
 
32
32
  // Vault
33
33
  //
@@ -41,16 +41,39 @@ pub contract FlowToken: FungibleToken, ViewResolver {
41
41
  // out of thin air. A special Minter resource needs to be defined to mint
42
42
  // new tokens.
43
43
  //
44
- pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance, MetadataViews.Resolver {
44
+ access(all) resource Vault: FungibleToken.Vault, FungibleToken.Provider, FungibleToken.Receiver, ViewResolver.Resolver {
45
45
 
46
46
  // holds the balance of a users tokens
47
- pub var balance: UFix64
47
+ access(all) var balance: UFix64
48
+
49
+ access(all) view fun getBalance(): UFix64 {
50
+ return self.balance
51
+ }
48
52
 
49
53
  // initialize the balance at resource creation time
50
54
  init(balance: UFix64) {
51
55
  self.balance = balance
52
56
  }
53
57
 
58
+ /// getSupportedVaultTypes optionally returns a list of vault types that this receiver accepts
59
+ access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
60
+ return {self.getType(): true}
61
+ }
62
+
63
+ access(all) view fun isSupportedVaultType(type: Type): Bool {
64
+ if (type == self.getType()) { return true } else { return false }
65
+ }
66
+
67
+ /// Returns the storage path where the vault should typically be stored
68
+ access(all) view fun getDefaultStoragePath(): StoragePath? {
69
+ return /storage/flowTokenVault
70
+ }
71
+
72
+ /// Returns the public path where this vault should have a public capability
73
+ access(all) view fun getDefaultPublicPath(): PublicPath? {
74
+ return /public/flowTokenReceiver
75
+ }
76
+
54
77
  // withdraw
55
78
  //
56
79
  // Function that takes an integer amount as an argument
@@ -60,7 +83,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
60
83
  // created Vault to the context that called so it can be deposited
61
84
  // elsewhere.
62
85
  //
63
- pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
86
+ access(FungibleToken.Withdrawable) fun withdraw(amount: UFix64): @{FungibleToken.Vault} {
64
87
  self.balance = self.balance - amount
65
88
  emit TokensWithdrawn(amount: amount, from: self.owner?.address)
66
89
  return <-create Vault(balance: amount)
@@ -73,7 +96,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
73
96
  // It is allowed to destroy the sent Vault because the Vault
74
97
  // was a temporary holder of the tokens. The Vault's balance has
75
98
  // been consumed and therefore can be destroyed.
76
- pub fun deposit(from: @FungibleToken.Vault) {
99
+ access(all) fun deposit(from: @{FungibleToken.Vault}) {
77
100
  let vault <- from as! @FlowToken.Vault
78
101
  self.balance = self.balance + vault.balance
79
102
  emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
@@ -81,18 +104,12 @@ pub contract FlowToken: FungibleToken, ViewResolver {
81
104
  destroy vault
82
105
  }
83
106
 
84
- destroy() {
85
- if self.balance > 0.0 {
86
- FlowToken.totalSupply = FlowToken.totalSupply - self.balance
87
- }
88
- }
89
-
90
107
  /// Get all the Metadata Views implemented by FlowToken
91
108
  ///
92
109
  /// @return An array of Types defining the implemented views. This value will be used by
93
110
  /// developers to know which parameter to pass to the resolveView() method.
94
111
  ///
95
- pub fun getViews(): [Type]{
112
+ access(all) view fun getViews(): [Type]{
96
113
  return FlowToken.getViews()
97
114
  }
98
115
 
@@ -101,9 +118,13 @@ pub contract FlowToken: FungibleToken, ViewResolver {
101
118
  /// @param view: The Type of the desired view.
102
119
  /// @return A structure representing the requested view.
103
120
  ///
104
- pub fun resolveView(_ view: Type): AnyStruct? {
121
+ access(all) fun resolveView(_ view: Type): AnyStruct? {
105
122
  return FlowToken.resolveView(view)
106
123
  }
124
+
125
+ access(all) fun createEmptyVault(): @{FungibleToken.Vault} {
126
+ return <-create Vault(balance: 0.0)
127
+ }
107
128
  }
108
129
 
109
130
  // createEmptyVault
@@ -113,14 +134,15 @@ pub contract FlowToken: FungibleToken, ViewResolver {
113
134
  // and store the returned Vault in their storage in order to allow their
114
135
  // account to be able to receive deposits of this token type.
115
136
  //
116
- pub fun createEmptyVault(): @FungibleToken.Vault {
137
+ access(all) fun createEmptyVault(): @FlowToken.Vault {
117
138
  return <-create Vault(balance: 0.0)
118
139
  }
119
140
 
120
- pub fun getViews(): [Type] {
141
+ access(all) view fun getViews(): [Type] {
121
142
  return [Type<FungibleTokenMetadataViews.FTView>(),
122
143
  Type<FungibleTokenMetadataViews.FTDisplay>(),
123
- Type<FungibleTokenMetadataViews.FTVaultData>()]
144
+ Type<FungibleTokenMetadataViews.FTVaultData>(),
145
+ Type<FungibleTokenMetadataViews.TotalSupply>()]
124
146
  }
125
147
 
126
148
  /// Get a Metadata View from FlowToken
@@ -128,7 +150,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
128
150
  /// @param view: The Type of the desired view.
129
151
  /// @return A structure representing the requested view.
130
152
  ///
131
- pub fun resolveView(_ view: Type): AnyStruct? {
153
+ access(all) fun resolveView(_ view: Type): AnyStruct? {
132
154
  switch view {
133
155
  case Type<FungibleTokenMetadataViews.FTView>():
134
156
  return FungibleTokenMetadataViews.FTView(
@@ -138,7 +160,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
138
160
  case Type<FungibleTokenMetadataViews.FTDisplay>():
139
161
  let media = MetadataViews.Media(
140
162
  file: MetadataViews.HTTPFile(
141
- url: "https://assets.website-files.com/5f6294c0c7a8cdd643b1c820/5f6294c0c7a8cda55cb1c936_Flow_Wordmark.svg"
163
+ url: FlowToken.getLogoURI()
142
164
  ),
143
165
  mediaType: "image/svg+xml"
144
166
  )
@@ -146,7 +168,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
146
168
  return FungibleTokenMetadataViews.FTDisplay(
147
169
  name: "FLOW Network Token",
148
170
  symbol: "FLOW",
149
- description: "FLOW is the protocol token that is required for transaction fees, storage fees, staking, and many applications built on the Flow Blockchain",
171
+ description: "FLOW is the native token for the Flow blockchain. It is required for securing the network, transaction fees, storage fees, staking, FLIP voting and may be used by applications built on the Flow Blockchain",
150
172
  externalURL: MetadataViews.ExternalURL("https://flow.com"),
151
173
  logos: medias,
152
174
  socials: {
@@ -159,23 +181,25 @@ pub contract FlowToken: FungibleToken, ViewResolver {
159
181
  receiverPath: /public/flowTokenReceiver,
160
182
  metadataPath: /public/flowTokenBalance,
161
183
  providerPath: /private/flowTokenVault,
162
- receiverLinkedType: Type<&FlowToken.Vault{FungibleToken.Receiver, FungibleToken.Balance, MetadataViews.Resolver}>(),
163
- metadataLinkedType: Type<&FlowToken.Vault{FungibleToken.Balance, MetadataViews.Resolver}>(),
164
- providerLinkedType: Type<&FlowToken.Vault{FungibleToken.Provider}>(),
165
- createEmptyVaultFunction: (fun (): @FungibleToken.Vault {
184
+ receiverLinkedType: Type<&FlowToken.Vault>(),
185
+ metadataLinkedType: Type<&FlowToken.Vault>(),
186
+ providerLinkedType: Type<&FlowToken.Vault>(),
187
+ createEmptyVaultFunction: (fun (): @{FungibleToken.Vault} {
166
188
  return <-FlowToken.createEmptyVault()
167
189
  })
168
190
  )
191
+ case Type<FungibleTokenMetadataViews.TotalSupply>():
192
+ return FungibleTokenMetadataViews.TotalSupply(totalSupply: FlowToken.totalSupply)
169
193
  }
170
194
  return nil
171
195
  }
172
196
 
173
- pub resource Administrator {
197
+ access(all) resource Administrator {
174
198
  // createNewMinter
175
199
  //
176
200
  // Function that creates and returns a new minter resource
177
201
  //
178
- pub fun createNewMinter(allowedAmount: UFix64): @Minter {
202
+ access(all) fun createNewMinter(allowedAmount: UFix64): @Minter {
179
203
  emit MinterCreated(allowedAmount: allowedAmount)
180
204
  return <-create Minter(allowedAmount: allowedAmount)
181
205
  }
@@ -184,7 +208,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
184
208
  //
185
209
  // Function that creates and returns a new burner resource
186
210
  //
187
- pub fun createNewBurner(): @Burner {
211
+ access(all) fun createNewBurner(): @Burner {
188
212
  emit BurnerCreated()
189
213
  return <-create Burner()
190
214
  }
@@ -194,17 +218,17 @@ pub contract FlowToken: FungibleToken, ViewResolver {
194
218
  //
195
219
  // Resource object that token admin accounts can hold to mint new tokens.
196
220
  //
197
- pub resource Minter {
221
+ access(all) resource Minter {
198
222
 
199
223
  // the amount of tokens that the minter is allowed to mint
200
- pub var allowedAmount: UFix64
224
+ access(all) var allowedAmount: UFix64
201
225
 
202
226
  // mintTokens
203
227
  //
204
228
  // Function that mints new tokens, adds them to the total supply,
205
229
  // and returns them to the calling context.
206
230
  //
207
- pub fun mintTokens(amount: UFix64): @FlowToken.Vault {
231
+ access(all) fun mintTokens(amount: UFix64): @FlowToken.Vault {
208
232
  pre {
209
233
  amount > UFix64(0): "Amount minted must be greater than zero"
210
234
  amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
@@ -224,7 +248,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
224
248
  //
225
249
  // Resource object that token admin accounts can hold to burn tokens.
226
250
  //
227
- pub resource Burner {
251
+ access(all) resource Burner {
228
252
 
229
253
  // burnTokens
230
254
  //
@@ -233,42 +257,55 @@ pub contract FlowToken: FungibleToken, ViewResolver {
233
257
  // Note: the burned tokens are automatically subtracted from the
234
258
  // total supply in the Vault destructor.
235
259
  //
236
- pub fun burnTokens(from: @FungibleToken.Vault) {
237
- let vault <- from as! @FlowToken.Vault
238
- let amount = vault.balance
239
- destroy vault
260
+ access(all) fun burnTokens(from: @FlowToken.Vault) {
261
+ FlowToken.burnTokens(from: <-from)
262
+ }
263
+ }
264
+
265
+ access(all) fun burnTokens(from: @FlowToken.Vault) {
266
+ let vault <- from as! @FlowToken.Vault
267
+ let amount = vault.balance
268
+ destroy vault
269
+ if amount > 0.0 {
270
+ FlowToken.totalSupply = FlowToken.totalSupply - amount
240
271
  emit TokensBurned(amount: amount)
241
272
  }
242
273
  }
243
274
 
244
- init(adminAccount: AuthAccount) {
275
+ /// Gets the Flow Logo XML URI from storage
276
+ access(all) fun getLogoURI(): String {
277
+ return FlowToken.account.storage.copy<String>(from: /storage/flowTokenLogoURI) ?? ""
278
+ }
279
+
280
+ init(adminAccount: auth(Storage, Capabilities) &Account) {
245
281
  self.totalSupply = 0.0
246
282
 
247
283
  // Create the Vault with the total supply of tokens and save it in storage
248
284
  //
249
285
  let vault <- create Vault(balance: self.totalSupply)
250
- adminAccount.save(<-vault, to: /storage/flowTokenVault)
286
+
287
+ // Example of how to resolve a metadata view for a Vault
288
+ let ftView = vault.resolveView(Type<FungibleTokenMetadataViews.FTView>())
289
+
290
+ adminAccount.storage.save(<-vault, to: /storage/flowTokenVault)
251
291
 
252
292
  // Create a public capability to the stored Vault that only exposes
253
293
  // the `deposit` method through the `Receiver` interface
254
294
  //
255
- adminAccount.link<&FlowToken.Vault{FungibleToken.Receiver, FungibleToken.Balance, MetadataViews.Resolver}>(
256
- /public/flowTokenReceiver,
257
- target: /storage/flowTokenVault
258
- )
295
+ let receiverCapability = adminAccount.capabilities.storage.issue<&FlowToken.Vault>(/storage/flowTokenVault)
296
+ adminAccount.capabilities.publish(receiverCapability, at: /public/flowTokenReceiver)
259
297
 
260
298
  // Create a public capability to the stored Vault that only exposes
261
299
  // the `balance` field through the `Balance` interface
262
300
  //
263
- adminAccount.link<&FlowToken.Vault{FungibleToken.Balance, MetadataViews.Resolver}>(
264
- /public/flowTokenBalance,
265
- target: /storage/flowTokenVault
266
- )
301
+ let balanceCapability = adminAccount.capabilities.storage.issue<&FlowToken.Vault>(/storage/flowTokenVault)
302
+ adminAccount.capabilities.publish(balanceCapability, at: /public/flowTokenBalance)
267
303
 
268
304
  let admin <- create Administrator()
269
- adminAccount.save(<-admin, to: /storage/flowTokenAdmin)
305
+ adminAccount.storage.save(<-admin, to: /storage/flowTokenAdmin)
270
306
 
271
307
  // Emit an event that shows that the contract was initialized
272
308
  emit TokensInitialized(initialSupply: self.totalSupply)
309
+
273
310
  }
274
311
  }