Flow blockchain NFT development and deployment tutorial [cadence contract]

Brain in new VAT 2021-11-24 15:17:31 阅读数:853

flow blockchain nft development deployment

Flow Blockchain is a famous encryption cat team, especially for NFT New public chain for application development , Its purpose is to solve the problem of Ethereum in NFT There are many problems in development and Application , It has been NBA、UFC Such as the support of several major manufacturers . In this tutorial, we will learn how to create Cadence Smart contracts and in Flow Issued on the blockchain NFT.

Blockchain development tutorial link : The etheric fang | The currency | EOS | Tendermint | Hyperledger Fabric | Omni/USDT | Ripple | Tron

1、Flow Development environment installation

First we need to install Flow CLI, Detailed installation instructions can be viewed Flow Official documents , Here we only list the installation commands under several operating systems :

  • macOS
brew install flow-cli
  • Linux
sh -ci “$(curl -fsSL https://storage.googleapis.com/flow-cli/install.sh)"
  • Windows
iex “& { $(irm ‘https://storage.googleapis.com/flow-cli/install.ps1') }”

We need to save the file to IPFS, We use Pinata. You can sign up for a free account , And then click here obtain API Access key . In the next tutorial, we will use Pinata API.

We also need to install NodeJS And a support Flow Smart contract code syntax highlighted text editor ,Flow Smart contract usage Cadence Language writing .Visual Studio Code Provide Cadence Highlight extension .

Let's create a project directory :

mkdir pinata-party

Enter this directory , Then execute the following command to initialize a new Flow project :

cd pinata-party
flow project init

Now use your favorite code editor ( Like loading Cadence Extended Visual Studio Code) Open project file .

You can see flow.json, We'll use . First create a cadence Folder , And create... In this folder contracts Folder , Last in contracts Create contract file in folder PinataPartyContract.cdc.

Before we move on , It's important to point out that , Our next operation will be in Flow Complete... On the blockchain emulator , To deploy the project to the test chain or main chain , Just update flow.json The configuration parameters in . Now let's be in flow.json Set up the simulation environment in order to write the smart contract code next :

"contracts": {
"PinataPartyContract": "./cadence/contracts/PinataPartyContract.cdc"
}

Next update flow.json Medium deployments object :

"deployments": {
"emulator": {
"emulator-account": ["PinataPartyContract"]
}
}

The above settings are used to tell Flow CLI Use the emulator to deploy the contract , The account number and the contract we will develop next are also declared in the configuration .

2、 To write Cadence Intelligent contract

Flow Provides a way to create NFT An excellent tutorial on smart contracts , This is a good reference , however Flow At the same time, point out , They haven't solved NFT The problem of metadata .Flow The team wants to store metadata on the chain . It's a good idea , They will certainly give a reasonable solution . However, we now want to cast some tokens with metadata , We also want these metadata to be associated with NFT. Metadata is just a part , We also hope to point to the media represented by Tongzheng .

If you are familiar with... On the Ethereum blockchain NFT, You may know this NFT Supported assets are stored in traditional databases and virtual machines . In most cases, this is not a big problem . We discussed the genius of addressable content before , And the problem of storing additional data of blockchain on traditional cloud platform , This points to two main points :

  • Assets should be verifiable
  • It should be easy to transfer maintenance responsibilities

IPFS These problems were solved ,Pinata It provides a simple access layer. We lock the content in IPFS On . This is the solution we want , Am I right? ? We want to make sure that we can prove NFT The ownership of the , Provide NFT The data of , And make sure we can control IPFS The underlying assets on the .

Combine these ideas , Now let's write a smart contract , The contract will be responsible for casting NFT、 Associate the metadata and ensure that the metadata points to stored in IPFS The underlying assets on the .

open PinataPartyContract.cdc file , Enter the following code :

pub contract PinataPartyContract {
pub resource NFT {
pub let id: UInt64
init(initID: UInt64) {
self.id = initID
}
}
}

The first step is to define our contract , And create a resource in the contract . Resources are stored in the user account , The access to it needs to meet the access control conditions .NFT Must be uniquely identified ,id Attribute is used to identify our pass .

Next, we need to create a resource interface to define capabilities that can be used by others , For example, someone other than the contract owner .

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}
}

Put the above code in NFT Below the resource code . This NFTReceiver Interface defines that people with access rights can call the following methods :

  • deposit
  • getIDs
  • idExists
  • getMetadata

Next, we need to implement the token set , You can think of it as saving all of the user's NFT My wallet .

pub resource Collection: NFTReceiver {
pub var ownedNFTs: @{UInt64: NFT}
pub var metadataObjs: {UInt64: { String : String }}
init () {
self.ownedNFTs <- {}
self.metadataObjs = {}
}
pub fun withdraw(withdrawID: UInt64): @NFT {
let token <- self.ownedNFTs.remove(key: withdrawID)!
return <-token
}
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
}
pub fun getIDs(): [UInt64] {
return self.ownedNFTs.keys
}
pub fun updateMetadata(id: UInt64, metadata: {String: String}) {
self.metadataObjs[id] = metadata
}
pub fun getMetadata(id: UInt64): {String : String} {
return self.metadataObjs[id]!
}
destroy() {
destroy self.ownedNFTs
}
}

The above code contains a lot of content , But we will soon understand what it means .

First , We have one called onwedNFTs The variable of , It is responsible for tracking all the information held by a user NFT.

Next , be known as metadataObjs The variable is used to hold each NFT Metadata mapping for , This variable will pass id Mapping to associated metadata , Therefore, we need to have a pass before setting up id.

Then we initialize the variable . stay Flow The variables defined in the resource need to be initialized .

Finally, we realize NFT Set all functions of resources . Note that not all of these functions are exposed externally . Don't forget we were NFTReceiver The resource interface defines functions that anyone can access .

I would also like to point out deposit function . Because we inherited the default Flow NFT Contract to include metadataObjs mapping , We also extend the default deposit Function to receive additional metadata Parameters . Why do you do this ? We need to ensure that only the foundry of the pass can add the metadata of the pass . To keep it private , We limit the initial addition of metadata to the casting process .

Almost finished Cadence Contract code , stay NFT Set resources , Add the following :

pub fun createEmptyCollection(): @Collection {
return <- create Collection()
}
pub resource NFTMinter {
pub var idCount: UInt64
init() {
self.idCount = 1
}
pub fun mintNFT(): @NFT {
var newNFT <- create NFT(initID: self.idCount)
self.idCount = self.idCount + 1 as UInt64
return <-newNFT
}
}

First , We define a function responsible for creating an empty NFT aggregate . This is the implementation code for users who visit our contract for the first time to obtain the storage location .

after , Let's create another resource , It's important , Otherwise, you will not be able to cast a pass .NFTMinter The resource contains incremental idCount To make sure our NFT Of id No repetition . The code also defines a create NFT Function of .

stay NFTMinter Under Resources , Add master contract initialization code :

init() {
self.account.save(<-self.createEmptyCollection(), to: /storage/NFTCollection)
self.account.link<&{NFTReceiver}>(/public/NFTReceiver, target: /storage/NFTCollection)
self.account.save(<-create NFTMinter(), to: /storage/NFTMinter)
}

This initialization function is only called when the contract is deployed . It mainly completes the following work :

  1. Create an empty NFT aggregate , So that the contract owner can cast and hold NFT
  2. Publish a collection resource to a reference NFTReceiver The public location of the interface , It shows that the NFTReceiver Defined methods can be accessed externally
  3. NFTMinter The resource is stored in the account store of the contract Creator , This means that only the contract creator can cast the pass

Can be in here Check the complete contract code .

3、 stay Flow Blockchain deployment Cadence contract

Now we have a contract , Before deployment , Best use Flow Playground To test . Go to Flow Playground And open the first account in the sidebar , Replace the sample contract with our contract code , And then click Deploy. If all goes well , You should see something like this in the log window :

16:48:55 Deployment Deployed Contract To: 0x01

Now we are ready to deploy the contract to a locally running Simulator . Run the following command on the command line :

flow project start-emulator

The simulator runs and flow.json If the configuration is correct , We can execute the following command to deploy the contract :

flow project deploy

If all goes well , You should see the following output :

Deploying 1 contracts for accounts: emulator-account
PinataPartyContract -> 0xf8d6e0586b0a20c7

Now we are Flow There is an active contract on the simulator , Next it's time to cast NFT 了 .

4、 Use Cadence Script casting NFT

In the next tutorial , We're going to create one app And user interface to make the whole casting process more user-friendly . But in this tutorial , To illustrate metadata and NFT stay Flow How it works on , We will use Cadence Script and command line to cast NFT.

Let's create a new directory under the project directory transactions, Then create a file in this directory MintPinataParty.cdc.

In order to write the transaction , We need to use a file to reference the information provided to NFT Metadata . To this end, we will pass Pinata Upload files to IPFS. Click on here Upload your selected video file .

After uploading the file, you will get a IPFS Hash ( It is often referred to as a content identifier or CID). Copy this hash , Because we need it in the casting process .

Now? , In your MintPinataParty.cdc In file , Add the following :

import PinataPartyContract from 0xf8d6e0586b0a20c7
transaction {
let receiverRef: &{PinataPartyContract.NFTReceiver}
let minterRef: &PinataPartyContract.NFTMinter
prepare(acct: AuthAccount) {
self.receiverRef = acct.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)
.borrow()
?? panic("Could not borrow receiver reference")
self.minterRef = acct.borrow<&PinataPartyContract.NFTMinter>(from: /storage/NFTMinter)
?? panic("could not borrow minter reference")
}
execute {
let metadata : {String : String} = {
"name": "The Big Swing",
"swing_velocity": "29",
"swing_angle": "45",
"rating": "5",
"uri": "ipfs://QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6"
}
let newNFT <- self.minterRef.mintNFT()
self.receiverRef.deposit(token: <-newNFT, metadata: metadata)
log("NFT Minted and deposited to Account 2's Collection")
}
}

The deal is simple , Let's explain .

First you'll notice the beginning import sentence . You may remember that we received an account when we deployed the contract , This is what we need to quote . So it will 0xf8d6e0586b0a20c7 Replace with the deployed account address .

Next we define the transaction . The content here is related to the transaction we expect to execute .

The first thing to do in our deal , Is to define two reference variables receiverRef and minterRef. In this case, we are also NFT The recipient and foundry of . These two variables refer to the resources we created in the contract . If the person executing the transaction does not have access to the resource , The deal will fail .

Next, we define a prepare function . This function inputs the account information and performs some verification . We try to borrow in NFTMinter and NFTReceiver Ability defined on , If the executor has no authority , Will fail here .

Finally, it's our execute function . In this function, we call NFT Construct metadata , Casting NFT, Associated metadata , take NFT Deposit into our account . You can see that I created a metadata Variable , Added information about our pass . Because we want to copy as much as possible NBA Top Shot, I also define some statistics in the metadata , Of course, you can enter any meaningful information .

You'll notice , stay metadata I also defined a uri attribute , This points to the... That holds our asset files IPFS Hash . In this example, it is the video we uploaded , You can replace it with the hash you get .

For some consideration, we append... Before hashing ipfs:// Prefix , In this way IPFS Desktop clients and browser extensions can access , It can also be in Brave Direct access to ,Brave Provides IPFS Native support for .

We call mintNFT function , It is responsible for creating the pass . Next you need to call deposit Function to put it into the account .

Finally, a simple log output .

Now we're basically ready to send the transaction 、 Casting NFT 了 . But first we need to prepare an account . On the command line, enter the project root directory , Create a new private key for signing .

flow keys generate

The above command will generate public and private keys . Remember to protect your private key !

We need a private key to sign the transaction , So copy it to flow.json In file . We also need to specify the signature algorithm . In the end, it looks like this :

"accounts": {
"emulator-account": {
"address": "YOUR ACCOUNT ADDRESS",
"privateKey": "YOUR PRIVATE KEY",
"chain": "flow-emulator",
"sigAlgorithm": "ECDSA_P256",
"hashAlgorithm": "SHA3_256"
}
},

If you want to put the project in github Or other remote git Warehouse , Make sure you don't include your private key . You can use .gitignore Avoid flow.json Open . Even if we just use a local emulator , Also remember to protect your private key .

Now send the transaction , Just execute the following command :

flow transactions send --code ./transactions/MintPinataParty.cdc --signer emulator-account

If all goes well , It should look like this :

Getting information for account with address 0xf8d6e0586b0a20c7 ...
Submitting transaction with ID 4a79102747a450f65b6aab06a77161af196c3f7151b2400b3b3d09ade3b69823 ...
Successfully submitted transaction with ID 4a79102747a450f65b6aab06a77161af196c3f7151b2400b3b3d09ade3b69823

5、 Use Cadence Script validation NFT

The last thing to do now , Is to verify the pass and extract metadata . To do this, we will write a simple script and call... On the command line .

Create a new in the project root directory scripts Folder , And create a file in it CheckTokenMetadata.cdc. Add the following to the file :

import PinataPartyContract from 0xf8d6e0586b0a20c7
pub fun main() : {String : String} {
let nftOwner = getAccount(0xf8d6e0586b0a20c7)
// log("NFT Owner")
let capability = nftOwner.getCapability<&{PinataPartyContract.NFTReceiver}>(/public/NFTReceiver)
let receiverRef = capability.borrow()
?? panic("Could not borrow the receiver reference")
return receiverRef.getMetadata(id: 1)
}

The above script can be regarded as a call to the read-only method of Ethereum smart contract , Free and just return data .

In our script , Import contract from deployment address , Then define a main function , And define three variables in this function :

  • nftOwner: hold NFt Account number
  • capability: Resource capability
  • receiverRef: The receiving party

Now call the script :

flow scripts execute ./scripts/CheckTokenMetadata.cdc

You should see something similar below :

{"name": "The Big Swing", "swing_velocity": "29", "swing_angle": "45", "rating": "5", "uri": "ipfs://QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6"}

Congratulations ! You are already in Flow Blockchain successfully deployed Cadence contract 、 Casting NFT And will NFT The associated metadata is saved in IPFS!


Link to the original text :Flow Blockchain NFT Development tutorial — Huizhi. Com

版权声明:本文为[Brain in new VAT]所创,转载请带上原文链接,感谢。 https://netfreeman.com/2021/11/20211108231833905x.html