时间:2023-06-21|浏览:209
我们创建合约、铸造代币、构建应用程序以查看通过该合约生成的NFT以及创建市场以将NFT转移给其他用户的示例。让我们从合约的创建和代币铸造开始。
设置工具
在您的系统上安装FlowCLI。根据不同的操作系统,有不同的命令用于安装CLI。
例如,要在macOS上安装FlowCLI,请使用以下命令: ``` brew install flow-cli ```
在Windows上: ``` iex "$(irm 'https://storage.googleapis.com/flow-cli/install.ps1')" ```
在Linux上: ``` sh -ci "$(curl -fsSL https://storage.googleapis.com/flow-cli/install.sh)" ```
资产文件将存储在IPFS上。在这个例子中,我们将使用Pinata来存储文件。您可以在此处注册免费帐户并获取API密钥。安装NodeJS和文本编辑器以突出显示Flow智能合约代码也很重要。
第二步是使用命令为项目创建目录: ``` mkdir pinata-party ``` 初始化一个新的Flow项目并将其更改为该目录: ``` cd pinata-party ```
现在,在代码编辑器中打开项目,让我们开始工作。首先,创建一个名为cadence的文件夹。在该文件夹中添加另一个名为contracts的文件夹。最后,在名为PinataPartyContract.cdc的合同文件夹中创建一个文件。
在继续之前,有必要指出我们对Flow区块链平台所做的一切。为模拟器环境设置文件,然后我们就可以开始编写合约了。我们需要使用以下代码更新flow.json中的合约对象: ``` "contracts": { "PinataPartyContract": "./cadence/contracts/PinataPartyContract.cdc" } ``` 使用以下代码更新该文件中的部署对象: ``` "deployments": { "emulator": { "emulator-account": [ "PinataPartyContract" ] } } ``` 它将使FlowCLI能够使用模拟器来部署我们的合约。该代码还引用了我们即将编写的帐户和合约。
合约
我们需要创建用于铸造NFT的合约,将元数据与NFT相关联,并确保元数据指向存储在IPFS上的基础资产。
打开PinataPartyContract.cdc并执行以下代码: ``` contract PinataPartyContract { pub resource NFT { pub let id: UInt64
init(initID: UInt64) { self.id = initID } } } ``` 第一步是定义合同。让我们从定义PinataPartyContract开始并在其中创建一个资源。资源是保存在用户帐户中的项目,可通过访问控制措施访问。NFT需要可识别,并且id属性允许您识别令牌。
然后,创建一个资源接口来定义哪些功能可供其他人使用。 ``` pub resource interface NFTReceiver { pub fun deposit(token: @NFT, metadata: {String: String}) pub fun getIDs: [UInt64] pub fun idExists(id: UInt64): Bool pub fun getMetadata(id: UInt64): {String: String} } ``` 将上述代码放在NFT资源代码下方。NFTReceiver资源接口表示资源可以调用以下方法: - 获取ID - 身份存在 - 存款 - 获取元数据
然后,我们必须定义令牌收集接口。将其视为存储所有用户的NFT的钱包。 ``` pub resource collection: NFTReceiver { pub var ownedNFTs: @{UInt64: NFT} pub var metadataObjs: {UInt64: {String: String}}
init { self.ownedNFTs = {} self.metadataObjs = {} }
pub fun deposit(token: @NFT, metadata: {String: String}) { self.metadataObjs[token.id] = metadata self.ownedNFTs[token.id] <- token }
pub fun idExists(id: UInt64): Bool { return self.ownedNFTs[id] != nil }
// ... } ``` 变量ownedNFTs跟踪用户可以从接触者拥有的所有NFT。一个名为metadataObjs的变量是独一无二的,因为我们正在扩展FlowNFT合约功能以存储每个NFT的元数据映射。它将令牌id映射到其相关的元数据,这意味着在我们设置之前需要令牌id。变量被初始化以在Flow中的资源中定义它们。
最后,我们将拥有NFT集合资源所需的所有可用功能。默认NFT合约被扩展为包含metadataObjs映射的方式,我们将扩展默认存款函数以采用额外的元数据参数。这样做是为了确保只有令牌铸币者才能将元数据添加到令牌中。我们将最初添加的元数据限制在铸币执行中,以保持其私密性。在Collection资源下添加以下代码: ``` pub resource NFTMinter { pub var idCount: UInt64
init { self.idCount = 1 }
pub fun mintNFT(): @NFT { let newNFT <- create NFT(initID: self.idCount) self.idCount = self.idCount + 1 as UInt64 return <-newNFT } } ``` 首先,我们将有一个函数在调用时创建一个空的NFT集合。与合约交互的用户将拥有一个映射定义的Collection资源的存储位置。之后我们将再创建一个资源。没有它,我们就无法铸造代币。NFTMinter包含一个每次都会增加的idCount,以确保我们没有NFT的重复id。它还包含创建NFT的功能。在NFTMinter资源下方添加主合约初始化程序: ``` init { self.account.save(<-self.createEmptyCollection, to: /storage/NFTCollection) self.account.link<&NFTReceiver>(/public/NFTReceiver, target: /storage/NFTCollection) self.account.save(<-self.createNFTMinter, to: /storage/NFTMinter) } ``` 初始化函数仅在部署合约时调用。它执行三件事: - 为集合部署者创建一个空集合,以便所有者合约可以从合约中创建和拥有NFT。 - NFTMinter资源存储在合约创建者的