Skip to content

Commit

Permalink
fixes: #58 fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
whalelephant committed Oct 4, 2021
1 parent 0e04489 commit c6b1792
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 70 deletions.
4 changes: 2 additions & 2 deletions cadence-contracts/IPackNFT.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
49 changes: 20 additions & 29 deletions cadence-contracts/PDS.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
}

Expand All @@ -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)
}


Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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
}

Expand All @@ -172,35 +172,27 @@ 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
}

}

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
}
}
Expand All @@ -221,15 +213,14 @@ pub contract PDS{


init(
adminAccount: AuthAccount,
packIssuerStoragePath: StoragePath,
packIssuerCapRecv: PublicPath,
distCreatorStoragePath: StoragePath,
distCreatorPrivPath: PrivatePath,
distManagerStoragePath: StoragePath,
version: String
) {
self.DistId = 0
self.nextDistId = 0
self.Distributions <- {}
self.packIssuerStoragePath = packIssuerStoragePath
self.packIssuerCapRecv = packIssuerCapRecv
Expand All @@ -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)
}
}
44 changes: 15 additions & 29 deletions cadence-contracts/PackNFT.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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)
}

}
Expand Down
4 changes: 2 additions & 2 deletions cadence-scripts/pds/get_current_dist_id.cdc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PDS from 0x{{.PDS}}

pub fun main(): UInt64 {
return PDS.DistId
}
return PDS.nextDistId
}
1 change: 0 additions & 1 deletion cadence-transactions/deploy/deploy-packNFT-with-auth.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ transaction(
owner.contracts.add(
name: contractName,
code: code.decodeHex(),
owner,
collectionStoragePath: collectionStoragePath,
collectionPublicPath: collectionPublicPath,
collectionIPackNFTPublicPath: collectionIPackNFTPublicPath,
Expand Down
1 change: 0 additions & 1 deletion cadence-transactions/deploy/deploy-pds-with-auth.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ transaction(
owner.contracts.add(
name: contractName,
code: code.decodeHex(),
owner,
packIssuerStoragePath: packIssuerStoragePath,
packIssuerCapRecv: packIssuerCapRecv,
distCreatorStoragePath: distCreatorStoragePath,
Expand Down
7 changes: 6 additions & 1 deletion cadence-transactions/pds/mint_packNFT.cdc
Original file line number Diff line number Diff line change
@@ -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)
}
}

7 changes: 5 additions & 2 deletions cadence-transactions/pds/open_packNFT.cdc
Original file line number Diff line number Diff line change
@@ -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
)
}
}
Expand Down
5 changes: 2 additions & 3 deletions go-contracts/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
3 changes: 3 additions & 0 deletions go-contracts/packnft/packnft.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit c6b1792

Please sign in to comment.