Skip to content

Commit 741a22a

Browse files
committed
use identifier for generic transactions
1 parent 7fcd583 commit 741a22a

File tree

13 files changed

+157
-339
lines changed

13 files changed

+157
-339
lines changed

contracts/MetadataViews.cdc

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,32 @@ import "ViewResolver"
1414
///
1515
access(all) contract MetadataViews {
1616

17+
/// Function to resolve a contract view based on a type identifier String
18+
/// and view type. Borrows the contract as &{ViewResolver} and
19+
/// then calls resolveContractView for the specified type and view.
20+
///
21+
/// @param resourceType: An optional resource type to return views for
22+
/// @param viewType: The Type of the desired view.
23+
/// @return A structure representing the requested view. If anything failed, returns nil
24+
///
25+
access(all) fun resolveContractViewFromTypeIdentifier(
26+
resourceTypeIdentifier: String,
27+
viewType: Type
28+
): AnyStruct? {
29+
if let resourceType = CompositeType(resourceTypeIdentifier) {
30+
if let viewResolverRef = getAccount(resourceType.address!).contracts.borrow<&{ViewResolver}>(
31+
name: resourceType.contractName!
32+
) {
33+
return viewResolverRef.resolveContractView(resourceType: resourceType, viewType: viewType)
34+
} else {
35+
return nil
36+
}
37+
} else {
38+
return nil
39+
}
40+
}
41+
42+
1743
/// Display is a basic view that includes the name, description and
1844
/// thumbnail for an object. Most objects should implement this view.
1945
///
@@ -119,10 +145,10 @@ access(all) contract MetadataViews {
119145
///
120146
access(all) view fun uri(): String {
121147
if let path = self.path {
122-
return "ipfs://".concat(self.cid).concat("/").concat(path)
148+
return "ipfs://\(self.cid)/\(path)"
123149
}
124150

125-
return "ipfs://".concat(self.cid)
151+
return "ipfs://\(self.cid)"
126152
}
127153
}
128154

@@ -280,8 +306,7 @@ access(all) contract MetadataViews {
280306
pre {
281307
cut >= 0.0 && cut <= 1.0 :
282308
"MetadataViews.Royalty.init: Cannot initialize the Royalty Metadata View! "
283-
.concat("The provided royalty cut value of ").concat(cut.toString())
284-
.concat(" is invalid. ")
309+
.concat("The provided royalty cut value of \(cut) is invalid. ")
285310
.concat("It should be within the valid range between 0 and 1. i.e [0,1]")
286311
}
287312
self.receiver = receiver
@@ -309,9 +334,7 @@ access(all) contract MetadataViews {
309334
totalCut <= 1.0,
310335
message:
311336
"MetadataViews.Royalties.init: Cannot initialize Royalties Metadata View! "
312-
.concat(" The sum of cutInfos multipliers is ")
313-
.concat(totalCut.toString())
314-
.concat(" but it should not be greater than 1.0")
337+
.concat(" The sum of cutInfos multipliers is \(totalCut) but it should not be greater than 1.0")
315338
)
316339
// Assign the cutInfos
317340
self.cutInfos = cutInfos
@@ -469,11 +492,7 @@ access(all) contract MetadataViews {
469492
number <= max!,
470493
message:
471494
"MetadataViews.Edition.init: Cannot intialize the Edition Metadata View! "
472-
.concat("The provided edition number of ")
473-
.concat(number.toString())
474-
.concat(" cannot be greater than the max edition number of ")
475-
.concat(max!.toString())
476-
.concat(".")
495+
.concat("The provided edition number of \(number) cannot be greater than the max edition number of \(max!).")
477496
)
478497
}
479498
self.name = name
@@ -556,8 +575,7 @@ access(all) contract MetadataViews {
556575
view init(score: UFix64?, max: UFix64?, description: String?) {
557576
if score == nil && description == nil {
558577
panic("MetadataViews.Rarity.init: Cannot initialize the Rarity Metadata View! "
559-
.concat("The provided score and description are both `nil`. ")
560-
.concat(" A Rarity needs to set score, description, or both"))
578+
.concat("The provided score and description are both `nil`. A Rarity needs to set score, description, or both"))
561579
}
562580

563581
self.score = score
@@ -672,9 +690,7 @@ access(all) contract MetadataViews {
672690
pre {
673691
publicLinkedType.isSubtype(of: Type<&{NonFungibleToken.Collection}>()):
674692
"MetadataViews.NFTCollectionData.init: Cannot initialize the NFTCollectionData Metadata View! "
675-
.concat("The Public linked type <")
676-
.concat(publicLinkedType.identifier)
677-
.concat("> is incorrect. It must be a subtype of the NonFungibleToken.Collection interface.")
693+
.concat("The Public linked type <\(publicLinkedType.identifier)> is incorrect. It must be a subtype of the NonFungibleToken.Collection interface.")
678694
}
679695
self.storagePath=storagePath
680696
self.publicPath=publicPath

flow.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"source": "contracts/CrossVMMetadataViews.cdc",
55
"aliases": {
66
"emulator": "f8d6e0586b0a20c7",
7-
"testing": "0000000000000007"
7+
"mainnet": "1d7e57aa55817448",
8+
"testing": "0000000000000007",
9+
"testnet": "631e88ae7f1d7c20"
810
}
911
},
1012
"ExampleNFT": {
@@ -22,6 +24,8 @@
2224
"MetadataViews": {
2325
"source": "./contracts/MetadataViews.cdc",
2426
"aliases": {
27+
"emulator": "f8d6e0586b0a20c7",
28+
"mainnet": "1d7e57aa55817448",
2529
"testing": "0000000000000007",
2630
"testnet": "631e88ae7f1d7c20"
2731
}
@@ -62,7 +66,7 @@
6266
},
6367
"EVM": {
6468
"source": "mainnet://e467b9dd11fa00df.EVM",
65-
"hash": "5c69921fa06088b477e2758e122636b39d3d3eb5316807c206c5680d9ac74c7e",
69+
"hash": "df2065d3eebc1e690e0b52a3f293bdf6c22780c7a9e7ef48a708a651b87abdf0",
6670
"aliases": {
6771
"emulator": "f8d6e0586b0a20c7",
6872
"mainnet": "e467b9dd11fa00df",
@@ -80,7 +84,7 @@
8084
},
8185
"FungibleToken": {
8286
"source": "mainnet://f233dcee88fe0abe.FungibleToken",
83-
"hash": "050328d01c6cde307fbe14960632666848d9b7ea4fef03ca8c0bbfb0f2884068",
87+
"hash": "23c1159cf99b2b039b6b868d782d57ae39b8d784045d81597f100a4782f0285b",
8488
"aliases": {
8589
"emulator": "ee82856bf20e2aa6",
8690
"mainnet": "f233dcee88fe0abe",

lib/go/contracts/internal/assets/assets.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/go/templates/internal/assets/assets.go

Lines changed: 12 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/go/templates/transaction_templates.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const (
1616
filenameMintNFT = "transactions/mint_nft.cdc"
1717
filenameTransferNFT = "transactions/transfer_nft.cdc"
1818
filenameTransferNFTWithPaths = "transactions/generic_transfer_with_paths.cdc"
19-
filenameTransferNFTWithAddress = "transactions/generic_transfer_with_address.cdc"
2019
filenameTransferNFTWithAddressAndType = "transactions/generic_transfer_with_address_and_type.cdc"
2120
filenameDestroyNFT = "transactions/destroy_nft.cdc"
2221
filenameSetupRoyalty = "transactions/setup_account_to_receive_royalty.cdc"
@@ -81,11 +80,9 @@ func GenerateTransferGenericNFTWithPathsScript(nftAddress string) []byte {
8180
return []byte(code)
8281
}
8382

84-
// GenerateTransferGenericNFTWithAddressScript returns a script that withdraws a generic NFT token
85-
// from a collection and deposits it into another collection.
86-
// The sender needs to send the contract address and name of the token being transferred
83+
// No longer recommended to be used
8784
func GenerateTransferGenericNFTWithAddressScript(nftAddress, metadataViewsAddress string) []byte {
88-
code := assets.MustAssetString(filenameTransferNFTWithAddress)
85+
code := assets.MustAssetString(filenameTransferNFTWithAddressAndType)
8986

9087
code = strings.ReplaceAll(
9188
code,

lib/go/test/nft_test.go

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,8 @@ func TestTransferNFT(t *testing.T) {
118118
script := templates.GenerateSetupAccountFromAddressScript(nftAddress.String(), metadataAddress.String())
119119
tx := createTxWithTemplateAndAuthorizer(b, script, joshAddress)
120120

121-
// Specify ExampleNFT contract address & name
122-
tx.AddArgument(cadence.NewAddress(exampleNFTAddress))
123-
tx.AddArgument(cadence.String("ExampleNFT"))
121+
// Specify ExampleNFT type identifier
122+
tx.AddArgument(cadence.String("A." + exampleNFTAddress.Hex() + ".ExampleNFT.NFT"))
124123

125124
signAndSubmit(
126125
t, b, tx,
@@ -147,16 +146,15 @@ func TestTransferNFT(t *testing.T) {
147146
script := templates.GenerateTransferNFTScript(nftAddress, exampleNFTAddress, metadataAddress, viewResolverAddress)
148147
tx := createTxWithTemplateAndAuthorizer(b, script, exampleNFTAddress)
149148

150-
// Specify ExampleNFT contract address & name
151-
tx.AddArgument(cadence.NewAddress(exampleNFTAddress))
152-
tx.AddArgument(cadence.String("ExampleNFT"))
153-
154149
// Transfer it to joshAddress
155150
tx.AddArgument(cadence.NewAddress(joshAddress))
156151

157152
// This ID does not exist in the authorizer's collection, so this will fail
158153
tx.AddArgument(cadence.NewUInt64(3))
159154

155+
// Specify ExampleNFT type identifier
156+
tx.AddArgument(cadence.String("A." + exampleNFTAddress.Hex() + ".ExampleNFT.NFT"))
157+
160158
signAndSubmit(
161159
t, b, tx,
162160
[]flow.Address{
@@ -199,15 +197,14 @@ func TestTransferNFT(t *testing.T) {
199197
script := templates.GenerateTransferNFTScript(nftAddress, exampleNFTAddress, metadataAddress, viewResolverAddress)
200198
tx := createTxWithTemplateAndAuthorizer(b, script, exampleNFTAddress)
201199

202-
// Specify ExampleNFT contract address & name
203-
tx.AddArgument(cadence.NewAddress(exampleNFTAddress))
204-
tx.AddArgument(cadence.String("ExampleNFT"))
205-
206200
// Add the recipient's address
207201
tx.AddArgument(cadence.NewAddress(joshAddress))
208202
// The ID does exist in the authorizer's transaction, so the transfer will succeed
209203
tx.AddArgument(mintedID)
210204

205+
// Specify ExampleNFT type identifier
206+
tx.AddArgument(cadence.String("A." + exampleNFTAddress.Hex() + ".ExampleNFT.NFT"))
207+
211208
signAndSubmit(
212209
t, b, tx,
213210
[]flow.Address{
@@ -244,17 +241,16 @@ func TestTransferNFT(t *testing.T) {
244241
)
245242

246243
// Use the generic transfer transaction with contract address and name
247-
script = templates.GenerateTransferGenericNFTWithAddressScript(nftAddress.String(), metadataAddress.String())
244+
script = templates.GenerateTransferGenericNFTWithAddressAndTypeScript(nftAddress.String(), metadataAddress.String())
248245
tx = createTxWithTemplateAndAuthorizer(b, script, joshAddress)
249246

250247
// Add the recipient's address
251248
tx.AddArgument(cadence.NewAddress(exampleNFTAddress))
252249
// The ID does exist in the authorizer's transaction, so the transfer will succeed
253250
tx.AddArgument(mintedID)
254251

255-
// Specify ExampleNFT contract address & name
256-
tx.AddArgument(cadence.NewAddress(exampleNFTAddress))
257-
tx.AddArgument(cadence.String("ExampleNFT"))
252+
// Specify ExampleNFT type identifier
253+
tx.AddArgument(cadence.String("A." + exampleNFTAddress.Hex() + ".ExampleNFT.NFT"))
258254

259255
signAndSubmit(
260256
t, b, tx,

tests/example_nft_test.cdc

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fun testSetupAccount() {
5353
let newAccount = Test.createAccount()
5454
txResult = executeTransaction(
5555
"../transactions/setup_account_from_address.cdc",
56-
[admin.address, "ExampleNFT"],
56+
["A.0000000000000007.ExampleNFT.NFT"],
5757
newAccount
5858
)
5959
Test.expect(txResult, Test.beSucceeded())
@@ -113,9 +113,8 @@ fun testTransferNFT() {
113113
"../transactions/transfer_nft.cdc",
114114
[
115115
admin.address,
116-
"ExampleNFT",
117-
admin.address,
118-
nftID
116+
nftID,
117+
"A.0000000000000007.ExampleNFT.NFT"
119118
],
120119
recipient
121120
)
@@ -156,34 +155,33 @@ fun testTransferNFT() {
156155
"../transactions/transfer_nft.cdc",
157156
[
158157
admin.address,
159-
"ExampleNFT",
160-
admin.address,
161-
nftID
158+
nftID,
159+
"A.0000000000000007.ExampleNFT.NFT"
162160
],
163161
recipient
164162
)
165163
Test.expect(txResult, Test.beSucceeded())
166164

167165
// Other generic transfer transactions should succeed
168166
txResult = executeTransaction(
169-
"../transactions/generic_transfer_with_address.cdc",
170-
[recipient.address, nftID, admin.address, "ExampleNFT"],
167+
"../transactions/generic_transfer_with_address_and_type.cdc",
168+
[recipient.address, nftID, "A.0000000000000007.ExampleNFT.NFT"],
171169
admin
172170
)
173171
Test.expect(txResult, Test.beSucceeded())
174172

175173
txResult = executeTransaction(
176174
"../transactions/generic_transfer_with_address_and_type.cdc",
177-
[admin.address, nftID, admin.address, "ExampleNFT", "NFT"],
175+
[admin.address, nftID, "A.0000000000000007.ExampleNFT.NFT"],
178176
recipient
179177
)
180178
Test.expect(txResult, Test.beSucceeded())
181179

182180
// Should not be able to transfer an NFT from a malicious contract
183181
// that tries to trick the generic transaction
184182
txResult = executeTransaction(
185-
"../transactions/generic_transfer_with_address.cdc",
186-
[recipient.address, nftID, admin.address, "MaliciousNFT"],
183+
"../transactions/generic_transfer_with_address_and_type.cdc",
184+
[recipient.address, nftID, "A.0000000000000007.MaliciousNFT.NFT"],
187185
admin
188186
)
189187
Test.expect(txResult, Test.beFailed())
@@ -194,7 +192,7 @@ fun testTransferNFT() {
194192

195193
txResult = executeTransaction(
196194
"../transactions/generic_transfer_with_address_and_type.cdc",
197-
[recipient.address, nftID, admin.address, "MaliciousNFT", "NFT"],
195+
[recipient.address, nftID, "A.0000000000000007.MaliciousNFT.NFT"],
198196
admin
199197
)
200198
Test.expect(txResult, Test.beFailed())
@@ -210,9 +208,8 @@ fun testTransferMissingNFT() {
210208
"../transactions/transfer_nft.cdc",
211209
[
212210
admin.address,
213-
"ExampleNFT",
214-
admin.address,
215-
10 as UInt64
211+
10 as UInt64,
212+
"A.0000000000000007.ExampleNFT.NFT"
216213
],
217214
recipient
218215
)
@@ -455,7 +452,7 @@ fun testBurnNFT() {
455452
txResult = executeTransaction(
456453
"../transactions/generic_destroy_nft.cdc",
457454
[
458-
admin.address, "ExampleNFT", "NFT", collectionIDs
455+
"A.0000000000000007.ExampleNFT.NFT", collectionIDs
459456
],
460457
admin
461458
)

tests/nft_forwarding_test.cdc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ access(all) fun testChangeForwarderRecipient() {
127127
let transferSuccess: Bool = txExecutor(
128128
"transfer_nft.cdc",
129129
[recipient],
130-
[admin.address, "ExampleNFT", forwarder.address, transferID],
130+
[forwarder.address, transferID, "A.0000000000000007.ExampleNFT.NFT"],
131131
nil,
132132
nil
133133
)

0 commit comments

Comments
 (0)