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

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.
@@ -0,0 +1,44 @@
1
+ /// Burner is a contract that can facilitate the destruction of any resource on flow.
2
+ ///
3
+ /// Contributors
4
+ /// - Austin Kline - https://twitter.com/austin_flowty
5
+ /// - Deniz Edincik - https://twitter.com/bluesign
6
+ /// - Bastian Müller - https://twitter.com/turbolent
7
+ access(all) contract Burner {
8
+ /// When Crescendo (Cadence 1.0) is released, custom destructors will be removed from cadece.
9
+ /// Burnable is an interface meant to replace this lost feature, allowing anyone to add a callback
10
+ /// method to ensure they do not destroy something which is not meant to be,
11
+ /// or to add logic based on destruction such as tracking the supply of a FT Collection
12
+ ///
13
+ /// NOTE: The only way to see benefit from this interface
14
+ /// is to always use the burn method in this contract. Anyone who owns a resource can always elect **not**
15
+ /// to destroy a resource this way
16
+ access(all) resource interface Burnable {
17
+ access(contract) fun burnCallback()
18
+ }
19
+
20
+ /// burn is a global method which will destroy any resource it is given.
21
+ /// If the provided resource implements the Burnable interface,
22
+ /// it will call the burnCallback method and then destroy afterwards.
23
+ access(all) fun burn(_ r: @AnyResource) {
24
+ if let s <- r as? @{Burnable} {
25
+ s.burnCallback()
26
+ destroy s
27
+ } else if let arr <- r as? @[AnyResource] {
28
+ while arr.length > 0 {
29
+ let item <- arr.removeFirst()
30
+ self.burn(<-item)
31
+ }
32
+ destroy arr
33
+ } else if let dict <- r as? @{HashableStruct: AnyResource} {
34
+ let keys = dict.keys
35
+ while keys.length > 0 {
36
+ let item <- dict.remove(key: keys.removeFirst())!
37
+ self.burn(<-item)
38
+ }
39
+ destroy dict
40
+ } else {
41
+ destroy r
42
+ }
43
+ }
44
+ }
@@ -17,29 +17,29 @@
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
29
  // definition is written per unit of flow instead of the inverse,
30
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.balance
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)
@@ -88,19 +88,19 @@ pub contract FlowStorageFees {
88
88
  // This is used to check if a transaction will fail because of any account being over the storage capacity
89
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.balance.saturatingSubtract(maxTxFees)
101
+ } else {
102
+ balance = balanceRef.balance
103
+ }
104
104
  }
105
105
 
106
106
  capacities.append(self.accountBalanceToAccountStorageCapacity(balance))
@@ -110,7 +110,7 @@ pub contract FlowStorageFees {
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
@@ -123,15 +123,15 @@ pub contract FlowStorageFees {
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,13 +151,12 @@ 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}>() {
158
+
159
+ if let balanceRef = acct.capabilities.borrow<&FlowToken.Vault>(/public/flowTokenBalance) {
161
160
  balance = balanceRef.balance
162
161
  }
163
162
 
@@ -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
-
@@ -1,33 +1,27 @@
1
1
  import "FungibleToken"
2
2
  import "MetadataViews"
3
3
  import "FungibleTokenMetadataViews"
4
- import "ViewResolver"
4
+ import "Burner"
5
5
 
6
- pub contract FlowToken: FungibleToken, ViewResolver {
6
+ access(all) contract FlowToken: FungibleToken {
7
7
 
8
8
  // Total supply of Flow tokens in existence
9
- pub var totalSupply: UFix64
10
-
11
- // Event that is emitted when the contract is created
12
- pub event TokensInitialized(initialSupply: UFix64)
9
+ access(all) var totalSupply: UFix64
13
10
 
14
11
  // Event that is emitted when tokens are withdrawn from a Vault
15
- pub event TokensWithdrawn(amount: UFix64, from: Address?)
12
+ access(all) event TokensWithdrawn(amount: UFix64, from: Address?)
16
13
 
17
14
  // Event that is emitted when tokens are deposited to a Vault
18
- pub event TokensDeposited(amount: UFix64, to: Address?)
15
+ access(all) event TokensDeposited(amount: UFix64, to: Address?)
19
16
 
20
17
  // Event that is emitted when new tokens are minted
21
- pub event TokensMinted(amount: UFix64)
22
-
23
- // Event that is emitted when tokens are destroyed
24
- pub event TokensBurned(amount: UFix64)
18
+ access(all) event TokensMinted(amount: UFix64)
25
19
 
26
20
  // Event that is emitted when a new minter resource is created
27
- pub event MinterCreated(allowedAmount: UFix64)
21
+ access(all) event MinterCreated(allowedAmount: UFix64)
28
22
 
29
23
  // Event that is emitted when a new burner resource is created
30
- pub event BurnerCreated()
24
+ access(all) event BurnerCreated()
31
25
 
32
26
  // Vault
33
27
  //
@@ -41,16 +35,38 @@ pub contract FlowToken: FungibleToken, ViewResolver {
41
35
  // out of thin air. A special Minter resource needs to be defined to mint
42
36
  // new tokens.
43
37
  //
44
- pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance, MetadataViews.Resolver {
38
+ access(all) resource Vault: FungibleToken.Vault {
45
39
 
46
40
  // holds the balance of a users tokens
47
- pub var balance: UFix64
41
+ access(all) var balance: UFix64
48
42
 
49
43
  // initialize the balance at resource creation time
50
44
  init(balance: UFix64) {
51
45
  self.balance = balance
52
46
  }
53
47
 
48
+ /// Called when a fungible token is burned via the `Burner.burn()` method
49
+ access(contract) fun burnCallback() {
50
+ if self.balance > 0.0 {
51
+ FlowToken.totalSupply = FlowToken.totalSupply - self.balance
52
+ }
53
+ self.balance = 0.0
54
+ }
55
+
56
+ /// getSupportedVaultTypes optionally returns a list of vault types that this receiver accepts
57
+ access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
58
+ return {self.getType(): true}
59
+ }
60
+
61
+ access(all) view fun isSupportedVaultType(type: Type): Bool {
62
+ if (type == self.getType()) { return true } else { return false }
63
+ }
64
+
65
+ /// Asks if the amount can be withdrawn from this vault
66
+ access(all) view fun isAvailableToWithdraw(amount: UFix64): Bool {
67
+ return amount <= self.balance
68
+ }
69
+
54
70
  // withdraw
55
71
  //
56
72
  // Function that takes an integer amount as an argument
@@ -60,7 +76,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
60
76
  // created Vault to the context that called so it can be deposited
61
77
  // elsewhere.
62
78
  //
63
- pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
79
+ access(FungibleToken.Withdraw) fun withdraw(amount: UFix64): @{FungibleToken.Vault} {
64
80
  self.balance = self.balance - amount
65
81
  emit TokensWithdrawn(amount: amount, from: self.owner?.address)
66
82
  return <-create Vault(balance: amount)
@@ -73,7 +89,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
73
89
  // It is allowed to destroy the sent Vault because the Vault
74
90
  // was a temporary holder of the tokens. The Vault's balance has
75
91
  // been consumed and therefore can be destroyed.
76
- pub fun deposit(from: @FungibleToken.Vault) {
92
+ access(all) fun deposit(from: @{FungibleToken.Vault}) {
77
93
  let vault <- from as! @FlowToken.Vault
78
94
  self.balance = self.balance + vault.balance
79
95
  emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
@@ -81,19 +97,13 @@ pub contract FlowToken: FungibleToken, ViewResolver {
81
97
  destroy vault
82
98
  }
83
99
 
84
- destroy() {
85
- if self.balance > 0.0 {
86
- FlowToken.totalSupply = FlowToken.totalSupply - self.balance
87
- }
88
- }
89
-
90
100
  /// Get all the Metadata Views implemented by FlowToken
91
101
  ///
92
102
  /// @return An array of Types defining the implemented views. This value will be used by
93
103
  /// developers to know which parameter to pass to the resolveView() method.
94
104
  ///
95
- pub fun getViews(): [Type]{
96
- return FlowToken.getViews()
105
+ access(all) view fun getViews(): [Type]{
106
+ return FlowToken.getContractViews(resourceType: nil)
97
107
  }
98
108
 
99
109
  /// Get a Metadata View from FlowToken
@@ -101,8 +111,12 @@ pub contract FlowToken: FungibleToken, ViewResolver {
101
111
  /// @param view: The Type of the desired view.
102
112
  /// @return A structure representing the requested view.
103
113
  ///
104
- pub fun resolveView(_ view: Type): AnyStruct? {
105
- return FlowToken.resolveView(view)
114
+ access(all) fun resolveView(_ view: Type): AnyStruct? {
115
+ return FlowToken.resolveContractView(resourceType: nil, viewType: view)
116
+ }
117
+
118
+ access(all) fun createEmptyVault(): @{FungibleToken.Vault} {
119
+ return <-create Vault(balance: 0.0)
106
120
  }
107
121
  }
108
122
 
@@ -113,14 +127,16 @@ pub contract FlowToken: FungibleToken, ViewResolver {
113
127
  // and store the returned Vault in their storage in order to allow their
114
128
  // account to be able to receive deposits of this token type.
115
129
  //
116
- pub fun createEmptyVault(): @FungibleToken.Vault {
130
+ access(all) fun createEmptyVault(vaultType: Type): @FlowToken.Vault {
117
131
  return <-create Vault(balance: 0.0)
118
132
  }
119
133
 
120
- pub fun getViews(): [Type] {
134
+ /// Gets a list of the metadata views that this contract supports
135
+ access(all) view fun getContractViews(resourceType: Type?): [Type] {
121
136
  return [Type<FungibleTokenMetadataViews.FTView>(),
122
137
  Type<FungibleTokenMetadataViews.FTDisplay>(),
123
- Type<FungibleTokenMetadataViews.FTVaultData>()]
138
+ Type<FungibleTokenMetadataViews.FTVaultData>(),
139
+ Type<FungibleTokenMetadataViews.TotalSupply>()]
124
140
  }
125
141
 
126
142
  /// Get a Metadata View from FlowToken
@@ -128,17 +144,17 @@ pub contract FlowToken: FungibleToken, ViewResolver {
128
144
  /// @param view: The Type of the desired view.
129
145
  /// @return A structure representing the requested view.
130
146
  ///
131
- pub fun resolveView(_ view: Type): AnyStruct? {
132
- switch view {
147
+ access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
148
+ switch viewType {
133
149
  case Type<FungibleTokenMetadataViews.FTView>():
134
150
  return FungibleTokenMetadataViews.FTView(
135
- ftDisplay: self.resolveView(Type<FungibleTokenMetadataViews.FTDisplay>()) as! FungibleTokenMetadataViews.FTDisplay?,
136
- ftVaultData: self.resolveView(Type<FungibleTokenMetadataViews.FTVaultData>()) as! FungibleTokenMetadataViews.FTVaultData?
151
+ ftDisplay: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTDisplay>()) as! FungibleTokenMetadataViews.FTDisplay?,
152
+ ftVaultData: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTVaultData>()) as! FungibleTokenMetadataViews.FTVaultData?
137
153
  )
138
154
  case Type<FungibleTokenMetadataViews.FTDisplay>():
139
155
  let media = MetadataViews.Media(
140
156
  file: MetadataViews.HTTPFile(
141
- url: "https://assets.website-files.com/5f6294c0c7a8cdd643b1c820/5f6294c0c7a8cda55cb1c936_Flow_Wordmark.svg"
157
+ url: FlowToken.getLogoURI()
142
158
  ),
143
159
  mediaType: "image/svg+xml"
144
160
  )
@@ -146,7 +162,7 @@ pub contract FlowToken: FungibleToken, ViewResolver {
146
162
  return FungibleTokenMetadataViews.FTDisplay(
147
163
  name: "FLOW Network Token",
148
164
  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",
165
+ 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
166
  externalURL: MetadataViews.ExternalURL("https://flow.com"),
151
167
  logos: medias,
152
168
  socials: {
@@ -154,57 +170,50 @@ pub contract FlowToken: FungibleToken, ViewResolver {
154
170
  }
155
171
  )
156
172
  case Type<FungibleTokenMetadataViews.FTVaultData>():
173
+ let vaultRef = FlowToken.account.storage.borrow<auth(FungibleToken.Withdraw) &FlowToken.Vault>(from: /storage/flowTokenVault)
174
+ ?? panic("Could not borrow reference to the contract's Vault!")
157
175
  return FungibleTokenMetadataViews.FTVaultData(
158
176
  storagePath: /storage/flowTokenVault,
159
177
  receiverPath: /public/flowTokenReceiver,
160
178
  metadataPath: /public/flowTokenBalance,
161
- 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 {
166
- return <-FlowToken.createEmptyVault()
179
+ receiverLinkedType: Type<&{FungibleToken.Receiver, FungibleToken.Vault}>(),
180
+ metadataLinkedType: Type<&{FungibleToken.Balance, FungibleToken.Vault}>(),
181
+ createEmptyVaultFunction: (fun (): @{FungibleToken.Vault} {
182
+ return <-vaultRef.createEmptyVault()
167
183
  })
168
184
  )
185
+ case Type<FungibleTokenMetadataViews.TotalSupply>():
186
+ return FungibleTokenMetadataViews.TotalSupply(totalSupply: FlowToken.totalSupply)
169
187
  }
170
188
  return nil
171
189
  }
172
190
 
173
- pub resource Administrator {
191
+ access(all) resource Administrator {
174
192
  // createNewMinter
175
193
  //
176
194
  // Function that creates and returns a new minter resource
177
195
  //
178
- pub fun createNewMinter(allowedAmount: UFix64): @Minter {
196
+ access(all) fun createNewMinter(allowedAmount: UFix64): @Minter {
179
197
  emit MinterCreated(allowedAmount: allowedAmount)
180
198
  return <-create Minter(allowedAmount: allowedAmount)
181
199
  }
182
-
183
- // createNewBurner
184
- //
185
- // Function that creates and returns a new burner resource
186
- //
187
- pub fun createNewBurner(): @Burner {
188
- emit BurnerCreated()
189
- return <-create Burner()
190
- }
191
200
  }
192
201
 
193
202
  // Minter
194
203
  //
195
204
  // Resource object that token admin accounts can hold to mint new tokens.
196
205
  //
197
- pub resource Minter {
206
+ access(all) resource Minter {
198
207
 
199
208
  // the amount of tokens that the minter is allowed to mint
200
- pub var allowedAmount: UFix64
209
+ access(all) var allowedAmount: UFix64
201
210
 
202
211
  // mintTokens
203
212
  //
204
213
  // Function that mints new tokens, adds them to the total supply,
205
214
  // and returns them to the calling context.
206
215
  //
207
- pub fun mintTokens(amount: UFix64): @FlowToken.Vault {
216
+ access(all) fun mintTokens(amount: UFix64): @FlowToken.Vault {
208
217
  pre {
209
218
  amount > UFix64(0): "Amount minted must be greater than zero"
210
219
  amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
@@ -220,55 +229,34 @@ pub contract FlowToken: FungibleToken, ViewResolver {
220
229
  }
221
230
  }
222
231
 
223
- // Burner
224
- //
225
- // Resource object that token admin accounts can hold to burn tokens.
226
- //
227
- pub resource Burner {
228
-
229
- // burnTokens
230
- //
231
- // Function that destroys a Vault instance, effectively burning the tokens.
232
- //
233
- // Note: the burned tokens are automatically subtracted from the
234
- // total supply in the Vault destructor.
235
- //
236
- pub fun burnTokens(from: @FungibleToken.Vault) {
237
- let vault <- from as! @FlowToken.Vault
238
- let amount = vault.balance
239
- destroy vault
240
- emit TokensBurned(amount: amount)
241
- }
232
+ /// Gets the Flow Logo XML URI from storage
233
+ access(all) fun getLogoURI(): String {
234
+ return FlowToken.account.storage.copy<String>(from: /storage/flowTokenLogoURI) ?? ""
242
235
  }
243
236
 
244
- init(adminAccount: AuthAccount) {
237
+ init(adminAccount: auth(Storage, Capabilities) &Account) {
245
238
  self.totalSupply = 0.0
246
239
 
247
240
  // Create the Vault with the total supply of tokens and save it in storage
248
241
  //
249
242
  let vault <- create Vault(balance: self.totalSupply)
250
- adminAccount.save(<-vault, to: /storage/flowTokenVault)
243
+
244
+ adminAccount.storage.save(<-vault, to: /storage/flowTokenVault)
251
245
 
252
246
  // Create a public capability to the stored Vault that only exposes
253
247
  // the `deposit` method through the `Receiver` interface
254
248
  //
255
- adminAccount.link<&FlowToken.Vault{FungibleToken.Receiver, FungibleToken.Balance, MetadataViews.Resolver}>(
256
- /public/flowTokenReceiver,
257
- target: /storage/flowTokenVault
258
- )
249
+ let receiverCapability = adminAccount.capabilities.storage.issue<&FlowToken.Vault>(/storage/flowTokenVault)
250
+ adminAccount.capabilities.publish(receiverCapability, at: /public/flowTokenReceiver)
259
251
 
260
252
  // Create a public capability to the stored Vault that only exposes
261
253
  // the `balance` field through the `Balance` interface
262
254
  //
263
- adminAccount.link<&FlowToken.Vault{FungibleToken.Balance, MetadataViews.Resolver}>(
264
- /public/flowTokenBalance,
265
- target: /storage/flowTokenVault
266
- )
255
+ let balanceCapability = adminAccount.capabilities.storage.issue<&FlowToken.Vault>(/storage/flowTokenVault)
256
+ adminAccount.capabilities.publish(balanceCapability, at: /public/flowTokenBalance)
267
257
 
268
258
  let admin <- create Administrator()
269
- adminAccount.save(<-admin, to: /storage/flowTokenAdmin)
259
+ adminAccount.storage.save(<-admin, to: /storage/flowTokenAdmin)
270
260
 
271
- // Emit an event that shows that the contract was initialized
272
- emit TokensInitialized(initialSupply: self.totalSupply)
273
261
  }
274
262
  }