From c6b17929a6d00538add2545d76856fa980ea8237 Mon Sep 17 00:00:00 2001 From: bwty Date: Thu, 30 Sep 2021 20:47:51 +0800 Subject: [PATCH] fixes: #58 fixes --- cadence-contracts/IPackNFT.cdc | 4 +- cadence-contracts/PDS.cdc | 49 ++++++++----------- cadence-contracts/PackNFT.cdc | 44 ++++++----------- cadence-scripts/pds/get_current_dist_id.cdc | 4 +- .../deploy/deploy-packNFT-with-auth.cdc | 1 - .../deploy/deploy-pds-with-auth.cdc | 1 - cadence-transactions/pds/mint_packNFT.cdc | 7 ++- cadence-transactions/pds/open_packNFT.cdc | 7 ++- go-contracts/contracts_test.go | 5 +- go-contracts/packnft/packnft.go | 3 ++ 10 files changed, 55 insertions(+), 70 deletions(-) diff --git a/cadence-contracts/IPackNFT.cdc b/cadence-contracts/IPackNFT.cdc index 73b2eac..3393a31 100644 --- a/cadence-contracts/IPackNFT.cdc +++ b/cadence-contracts/IPackNFT.cdc @@ -44,12 +44,12 @@ pub contract interface IPackNFT{ // TODO Pack resource pub resource interface IOperator { - pub fun mint(distId: UInt64, commitHash: String, issuer: Address) + pub fun mint(distId: UInt64, commitHash: String, issuer: Address): @NFT pub fun reveal(id: UInt64, nfts: [{Collectible}], salt: String) pub fun open(id: UInt64) } pub resource PackNFTOperator: IOperator { - pub fun mint(distId: UInt64, commitHash: String, issuer: Address) + pub fun mint(distId: UInt64, commitHash: String, issuer: Address): @NFT pub fun reveal(id: UInt64, nfts: [{Collectible}], salt: String) pub fun open(id: UInt64) } diff --git a/cadence-contracts/PDS.cdc b/cadence-contracts/PDS.cdc index 16428c4..b4d4f0c 100644 --- a/cadence-contracts/PDS.cdc +++ b/cadence-contracts/PDS.cdc @@ -11,7 +11,7 @@ pub contract PDS{ pub let distCreatorPrivPath: PrivatePath pub let distManagerStoragePath: StoragePath - pub var DistId: UInt64 + pub var nextDistId: UInt64 access(contract) let Distributions: @{UInt64: SharedCapabilities} pub struct Collectible: IPackNFT.Collectible { @@ -57,14 +57,14 @@ pub contract PDS{ return <- c.withdraw(withdrawID: withdrawID) } - // TODO: maybe we do not need to specify the issuer here, should be the creator of the SharedCapabilities - // this is also used in storing inside the NFT though - pub fun mintPackNFT(distId: UInt64, commitHashes: [String], issuer: Address){ + pub fun mintPackNFT(distId: UInt64, commitHashes: [String], issuer: Address, recvCap: &{NonFungibleToken.CollectionPublic} ){ var i = 0 let c = self.operatorCap.borrow() ?? panic("no such cap") while i < commitHashes.length{ - c.mint(distId: distId, commitHash: commitHashes[i], issuer: issuer) + let nft <- c.mint(distId: distId, commitHash: commitHashes[i], issuer: issuer) i = i + 1 + let n <- nft as! @NonFungibleToken.NFT + recvCap.deposit(token: <- n) } } @@ -73,11 +73,11 @@ pub contract PDS{ c.reveal(id: packId, nfts: nfts, salt: salt) } - pub fun openPackNFT(packId: UInt64, nftIds: [UInt64], owner: Address, collectionProviderPath: PrivatePath, recvCollectionPublicPath: PublicPath) { + pub fun openPackNFT(packId: UInt64, nftIds: [UInt64], recvCap: &{NonFungibleToken.CollectionPublic}, collectionProviderPath: PrivatePath) { let c = self.operatorCap.borrow() ?? panic("no such cap") // This checks and sets the status of the pack before releasing escrow c.open(id: packId) - PDS.releaseEscrow(nftIds: nftIds, owner: owner, collectionProviderPath: collectionProviderPath, recvCollectionPublicPath: recvCollectionPublicPath) + PDS.releaseEscrow(nftIds: nftIds, recvCap: recvCap , collectionProviderPath: collectionProviderPath) } @@ -125,9 +125,9 @@ pub contract PDS{ pub resource DistributionCreator: IDistCreator { pub fun createNewDist(sharedCap: @SharedCapabilities) { - let currentId = PDS.DistId + let currentId = PDS.nextDistId PDS.Distributions[currentId] <-! sharedCap - PDS.DistId = currentId + 1 + PDS.nextDistId = currentId + 1 emit DistributionCreated(DistId: currentId) } } @@ -146,10 +146,10 @@ pub contract PDS{ PDS.Distributions[distId] <-! d } - pub fun mintPackNFT(distId: UInt64, commitHashes: [String], issuer: Address){ + pub fun mintPackNFT(distId: UInt64, commitHashes: [String], issuer: Address, recvCap: &{NonFungibleToken.CollectionPublic}){ assert(PDS.Distributions.containsKey(distId), message: "No such distribution") let d <- PDS.Distributions.remove(key: distId)! - d.mintPackNFT(distId: distId, commitHashes: commitHashes, issuer: issuer) + d.mintPackNFT(distId: distId, commitHashes: commitHashes, issuer: issuer, recvCap: recvCap) PDS.Distributions[distId] <-! d } @@ -172,10 +172,10 @@ pub contract PDS{ PDS.Distributions[distId] <-! d } - pub fun openPackNFT(distId: UInt64, packId: UInt64, nftIds: [UInt64], owner: Address, collectionProviderPath: PrivatePath, recvCollectionPublicPath: PublicPath){ + pub fun openPackNFT(distId: UInt64, packId: UInt64, nftIds: [UInt64], recvCap: &{NonFungibleToken.CollectionPublic}, collectionProviderPath: PrivatePath){ assert(PDS.Distributions.containsKey(distId), message: "No such distribution") let d <- PDS.Distributions.remove(key: distId)! - d.openPackNFT(packId: packId, nftIds: nftIds, owner: owner, collectionProviderPath: collectionProviderPath, recvCollectionPublicPath: recvCollectionPublicPath) + d.openPackNFT(packId: packId, nftIds: nftIds, recvCap: recvCap, collectionProviderPath: collectionProviderPath) PDS.Distributions[distId] <-! d } @@ -183,24 +183,16 @@ pub contract PDS{ access(contract) fun getManagerCollectionCap(escrowCollectionPublic: PublicPath): Capability<&{NonFungibleToken.CollectionPublic}> { let pdsCollection = self.account.getCapability<&{NonFungibleToken.CollectionPublic}>(escrowCollectionPublic) - if !pdsCollection.check(){ - panic("Please ensure PDS has created and linked a Collection for recieving escrows") - } + assert(pdsCollection.check(), message: "Please ensure PDS has created and linked a Collection for recieving escrows") return pdsCollection } - access(contract) fun releaseEscrow(nftIds: [UInt64], owner: Address, collectionProviderPath: PrivatePath, recvCollectionPublicPath: PublicPath) { + access(contract) fun releaseEscrow(nftIds: [UInt64], recvCap: &{NonFungibleToken.CollectionPublic}, collectionProviderPath: PrivatePath ) { let pdsCollection = self.account.getCapability(collectionProviderPath).borrow<&{NonFungibleToken.Provider}>() ?? panic("Unable to borrow PDS collection provider capability from private path") - let recvAcct = getAccount(owner) - let recv = recvAcct.getCapability(recvCollectionPublicPath).borrow<&{NonFungibleToken.CollectionPublic}>() - ?? panic("Unable to borrow Collection Public reference for recipient") - log("releasing escrow") - log(nftIds) var i = 0 while i < nftIds.length { - log(nftIds[i]) - recv.deposit(token: <- pdsCollection.withdraw(withdrawID: nftIds[i])) + recvCap.deposit(token: <- pdsCollection.withdraw(withdrawID: nftIds[i])) i = i + 1 } } @@ -221,7 +213,6 @@ pub contract PDS{ init( - adminAccount: AuthAccount, packIssuerStoragePath: StoragePath, packIssuerCapRecv: PublicPath, distCreatorStoragePath: StoragePath, @@ -229,7 +220,7 @@ pub contract PDS{ distManagerStoragePath: StoragePath, version: String ) { - self.DistId = 0 + self.nextDistId = 0 self.Distributions <- {} self.packIssuerStoragePath = packIssuerStoragePath self.packIssuerCapRecv = packIssuerCapRecv @@ -240,11 +231,11 @@ pub contract PDS{ // Create a distributionCreator to share create capability with PackIssuer let d <- create DistributionCreator() - adminAccount.save(<-d, to: self.distCreatorStoragePath) - adminAccount.link<&DistributionCreator{PDS.IDistCreator}>(self.distCreatorPrivPath, target: self.distCreatorStoragePath) + self.account.save(<-d, to: self.distCreatorStoragePath) + self.account.link<&DistributionCreator{PDS.IDistCreator}>(self.distCreatorPrivPath, target: self.distCreatorStoragePath) // Create a distributionManager to manager distributions (withdraw for escrow, mint PackNFT todo: reveal / transfer) let m <- create DistributionManager() - adminAccount.save(<-m, to: self.distManagerStoragePath) + self.account.save(<-m, to: self.distManagerStoragePath) } } diff --git a/cadence-contracts/PackNFT.cdc b/cadence-contracts/PackNFT.cdc index 9486254..39ebdfa 100644 --- a/cadence-contracts/PackNFT.cdc +++ b/cadence-contracts/PackNFT.cdc @@ -26,18 +26,14 @@ pub contract PackNFT: NonFungibleToken, IPackNFT { pub resource PackNFTOperator: IPackNFT.IOperator { - pub fun mint(distId: UInt64, commitHash: String, issuer: Address) { + pub fun mint(distId: UInt64, commitHash: String, issuer: Address): @NFT{ let id = PackNFT.totalSupply let nft <- create NFT(initID: id, commitHash: commitHash, issuer: issuer) PackNFT.totalSupply = id + 1 - let recvAcct = getAccount(issuer) - let recv = recvAcct.getCapability(PackNFT.collectionPublicPath).borrow<&{NonFungibleToken.CollectionPublic}>() - ?? panic("Unable to borrow Collection Public reference for recipient") - - recv.deposit(token: <- nft) let p <-create Pack(commitHash: commitHash, issuer: issuer) PackNFT.packs[id] <-! p emit Mint(id: id, commitHash: commitHash, distId: distId) + return <- nft } pub fun reveal(id: UInt64, nfts: [{IPackNFT.Collectible}], salt: String) { @@ -66,14 +62,11 @@ pub contract PackNFT: NonFungibleToken, IPackNFT { var hashString = self.salt! hashString = hashString.concat(",").concat(nftString) let hash = HashAlgorithm.SHA2_256.hash(hashString.utf8) - if self.commitHash != String.encodeHex(hash) { - return false - } else { - return true - } + assert(self.commitHash == String.encodeHex(hash), message: "CommitHash was not verified") + return true } - access(self) fun _verify(nfts: [{IPackNFT.Collectible}], salt: String, commitHash: String): String? { + access(self) fun _verify(nfts: [{IPackNFT.Collectible}], salt: String, commitHash: String): String { var hashString = salt var nftString = nfts[0].hashString() var i = 1 @@ -85,16 +78,13 @@ pub contract PackNFT: NonFungibleToken, IPackNFT { hashString = hashString.concat(",").concat(nftString) log(hashString) let hash = HashAlgorithm.SHA2_256.hash(hashString.utf8) - if commitHash != String.encodeHex(hash) { - return nil - } else { - return nftString - } + assert(self.commitHash == String.encodeHex(hash), message: "CommitHash was not verified") + return nftString } access(contract) fun reveal(id: UInt64, nfts: [{IPackNFT.Collectible}], salt: String) { assert(self.status == "Sealed", message: "Pack status is not Sealed") - let v = self._verify(nfts: nfts, salt: salt, commitHash: self.commitHash) ?? panic("commitHash was not verified") + let v = self._verify(nfts: nfts, salt: salt, commitHash: self.commitHash) self.salt = salt self.status = "Revealed" emit Revealed(id: id, salt: salt, nfts: v) @@ -153,9 +143,7 @@ pub contract PackNFT: NonFungibleToken, IPackNFT { pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) - let nonfungibleToken <- token - - return <- nonfungibleToken + return <- token } // deposit takes a NFT and adds it to the collections dictionary @@ -214,12 +202,10 @@ pub contract PackNFT: NonFungibleToken, IPackNFT { } pub fun createEmptyCollection(): @NonFungibleToken.Collection { - let c <- create Collection() - return <- c + return <- create Collection() } init( - adminAccount: AuthAccount, collectionStoragePath: StoragePath, collectionPublicPath: PublicPath, collectionIPackNFTPublicPath: PublicPath, @@ -238,14 +224,14 @@ pub contract PackNFT: NonFungibleToken, IPackNFT { // Create a collection to receive Pack NFTs let collection <- create Collection() - adminAccount.save(<-collection, to: self.collectionStoragePath) - adminAccount.link<&Collection{NonFungibleToken.CollectionPublic}>(self.collectionPublicPath, target: self.collectionStoragePath) - adminAccount.link<&Collection{IPackNFT.IPackNFTCollectionPublic}>(self.collectionIPackNFTPublicPath, target: self.collectionStoragePath) + self.account.save(<-collection, to: self.collectionStoragePath) + self.account.link<&Collection{NonFungibleToken.CollectionPublic}>(self.collectionPublicPath, target: self.collectionStoragePath) + self.account.link<&Collection{IPackNFT.IPackNFTCollectionPublic}>(self.collectionIPackNFTPublicPath, target: self.collectionStoragePath) // Create a operator to share mint capability with proxy let operator <- create PackNFTOperator() - adminAccount.save(<-operator, to: self.operatorStoragePath) - adminAccount.link<&PackNFTOperator{IPackNFT.IOperator}>(self.operatorPrivPath, target: self.operatorStoragePath) + self.account.save(<-operator, to: self.operatorStoragePath) + self.account.link<&PackNFTOperator{IPackNFT.IOperator}>(self.operatorPrivPath, target: self.operatorStoragePath) } } diff --git a/cadence-scripts/pds/get_current_dist_id.cdc b/cadence-scripts/pds/get_current_dist_id.cdc index 34fe5da..f977879 100644 --- a/cadence-scripts/pds/get_current_dist_id.cdc +++ b/cadence-scripts/pds/get_current_dist_id.cdc @@ -1,5 +1,5 @@ import PDS from 0x{{.PDS}} pub fun main(): UInt64 { - return PDS.DistId -} \ No newline at end of file + return PDS.nextDistId +} diff --git a/cadence-transactions/deploy/deploy-packNFT-with-auth.cdc b/cadence-transactions/deploy/deploy-packNFT-with-auth.cdc index be72a0f..fbd38ab 100644 --- a/cadence-transactions/deploy/deploy-packNFT-with-auth.cdc +++ b/cadence-transactions/deploy/deploy-packNFT-with-auth.cdc @@ -18,7 +18,6 @@ transaction( owner.contracts.add( name: contractName, code: code.decodeHex(), - owner, collectionStoragePath: collectionStoragePath, collectionPublicPath: collectionPublicPath, collectionIPackNFTPublicPath: collectionIPackNFTPublicPath, diff --git a/cadence-transactions/deploy/deploy-pds-with-auth.cdc b/cadence-transactions/deploy/deploy-pds-with-auth.cdc index c134c4d..e35df08 100644 --- a/cadence-transactions/deploy/deploy-pds-with-auth.cdc +++ b/cadence-transactions/deploy/deploy-pds-with-auth.cdc @@ -18,7 +18,6 @@ transaction( owner.contracts.add( name: contractName, code: code.decodeHex(), - owner, packIssuerStoragePath: packIssuerStoragePath, packIssuerCapRecv: packIssuerCapRecv, distCreatorStoragePath: distCreatorStoragePath, diff --git a/cadence-transactions/pds/mint_packNFT.cdc b/cadence-transactions/pds/mint_packNFT.cdc index 38bc921..961cb44 100644 --- a/cadence-transactions/pds/mint_packNFT.cdc +++ b/cadence-transactions/pds/mint_packNFT.cdc @@ -1,9 +1,14 @@ import PDS from 0x{{.PDS}} +import PackNFT from 0x{{.PackNFT}} +import NonFungibleToken from 0x{{.NonFungibleToken}} transaction (distId: UInt64, commitHashes: [String], issuer: Address ) { prepare(pds: AuthAccount) { + let recvAcct = getAccount(issuer) + let recv = recvAcct.getCapability(PackNFT.collectionPublicPath).borrow<&{NonFungibleToken.CollectionPublic}>() + ?? panic("Unable to borrow Collection Public reference for recipient") let cap = pds.borrow<&PDS.DistributionManager>(from: PDS.distManagerStoragePath) ?? panic("pds does not have Dist manager") - cap.mintPackNFT(distId: distId, commitHashes: commitHashes, issuer: issuer) + cap.mintPackNFT(distId: distId, commitHashes: commitHashes, issuer: issuer, recvCap: recv) } } diff --git a/cadence-transactions/pds/open_packNFT.cdc b/cadence-transactions/pds/open_packNFT.cdc index 445cc19..b4854ed 100644 --- a/cadence-transactions/pds/open_packNFT.cdc +++ b/cadence-transactions/pds/open_packNFT.cdc @@ -1,16 +1,19 @@ import PDS from 0x{{.PDS}} import ExampleNFT from 0x{{.ExampleNFT}} +import NonFungibleToken from 0x{{.NonFungibleToken}} transaction (distId: UInt64, packId: UInt64, nftIds: [UInt64], owner: Address) { prepare(pds: AuthAccount) { let cap = pds.borrow<&PDS.DistributionManager>(from: PDS.distManagerStoragePath) ?? panic("pds does not have Dist manager") + let recvAcct = getAccount(owner) + let recv = recvAcct.getCapability(ExampleNFT.CollectionPublicPath).borrow<&{NonFungibleToken.CollectionPublic}>() + ?? panic("Unable to borrow Collection Public reference for recipient") cap.openPackNFT( distId: distId, packId: packId, nftIds: nftIds, - owner: owner, + recvCap: recv, collectionProviderPath: ExampleNFT.CollectionProviderPrivPath, - recvCollectionPublicPath: ExampleNFT.CollectionPublicPath ) } } diff --git a/go-contracts/contracts_test.go b/go-contracts/contracts_test.go index bc9ac44..7a6f0b0 100644 --- a/go-contracts/contracts_test.go +++ b/go-contracts/contracts_test.go @@ -153,7 +153,7 @@ func TestPDSMintPackNFTs(t *testing.T){ AddField("id", strconv.Itoa(int(expectedId))). AddField("commitHash", hash). AddField("distId", strconv.Itoa(int(nextDistId - 1))). - AssertEqual(t, events[1]) + AssertEqual(t, events[0]) nextPackNFTId, err := packnft.GetTotalPacks(g) assert.NoError(t, err) @@ -419,6 +419,5 @@ func TestPublicVerify(t *testing.T) { notNfts:= "A." + addr + ".ExampleNFT.2,A."+ addr +".ExampleNFT.4" v, err = packnft.Verify(g, currentPack, notNfts) - assert.NoError(t, err) - assert.Equal(t, false, v) + assert.Error(t, err) } diff --git a/go-contracts/packnft/packnft.go b/go-contracts/packnft/packnft.go index d768a2b..f7d16dd 100644 --- a/go-contracts/packnft/packnft.go +++ b/go-contracts/packnft/packnft.go @@ -45,6 +45,9 @@ func Verify( txScript:= "../cadence-scripts/packNFT/verify.cdc" code:= util.ParseCadenceTemplate(txScript) d, err := g.ScriptFromFile(txScript, code).UInt64Argument(id).StringArgument(nftString).RunReturns() + if err != nil { + return + } verified = d.ToGoValue().(bool) return }