credit: Peter Trimming

Getting Started with the Flow Blockchain

Elizabeth Engelman
Red Squirrel
Published in
8 min readApr 7, 2022

--

I recently got the opportunity to help build a Non-Fungible Token using the Flow Blockchain. This was a whole new blockchain for me! Getting up and running with a new technology is always a challenge, and I find that sometimes figuring out where to start is the hardest part. I learn by doing — getting my hands on the keyboard as soon as possible to interact with the new technology and reading the docs as I go to understand more deeply what my hands just did. So, this post follows that mindset and aims to get your hands on the keyboard to deploy a Cadence smart contract to a local emulator and interact with it as soon as possible.

Step 0: Installing Dependencies

Before we get started, let’s get our dependencies installed:

  • RedSquirrelNFT example repo: Each step of this blog post has its own branch in the repository, in case you’d like to follow along step-by-step. Or, to follow along with the completed project, please refer to the main branch: git clone git@github.com:RedSquirrelTech/red-squirrel-nft.git.
  • Flow CLI: The Flow CLI is a powerful tool that not only comes with a blockchain emulator but also allows for deploying contracts, creating account keys, and executing transactions.
  • Go: This project uses Go to test the smart contract that we create, as there isn’t a testing framework for the smart contract language, Cadence, just yet.

Step 1: Scaffolding

The structure of this scaffolding is based on this blog post by Joshua Hannan, a smart contract engineer at Dapper Labs. It contains two main directories: cadence and lib:

  • cadence: This directory is where the smart contract code lives, as well as scripts to interact with those contracts. You’ll note that there are two contracts already in the standard directory — these are standard Flow contracts that our RedSquirrelNFT contract will depend on.
  • lib: This is where we can write any code that wraps the interactions with the smart contract, using one of the Flow SDKs. This directory is also where we add tests to exercise the functionality of the smart contract.

Step 2: Creating a smart contract

Cadence, Flow’s smart contract language, is resource-oriented. In this context, a resource is a data structure that has special rules about its ownership and access, including being able to exist in only one place at a time. These rules are enforced by the language itself.

The intricate details of Cadence and writing a smart contract is out of scope for this blog post, but here we’ll walk through some of the main resources that make up our RedSquirrelNFT smart contract. I also recommend reading Flow’s Non-Fungible Tokens tutorial which will walk you through the specifics of a basic smart contract using the Flow Playground (instead of deploying to an emulator).

NFT Resource

The NFT resource is the fundamental object that we’ll be working with in the RedSquirrelNFT contract. This is where we store the name, description, and link to the image that makes up the RedSquirrelNFT. The NFT resource implements two interfaces:

Implementing both interfaces is highly recommended so that your NFT can be treated like all of the other NFTs on the Flow blockchain, which will set you up well for future compatibility in the ecosystem.

Collection Resource

The Collection resource is essentially a wrapper around a dictionary that is made to specifically store our RedSquirrelNFTs, while also allowing us to control what functions public users are able to access. The collection resource implements several interfaces from theNonFungibleToken and MetadataViews standards — these interfaces define functions that allow the owner of the collection to move their NFTs to and from the collection, and to share a reference to their collection for public visibility of the NFTs’ ids.

We also define our own interface to combine all of the public functions we’d like to expose, and include a borrowRedSquirrelNFT function, so that public users are able to borrow a RedSquirrelNFT reference specifically. This allows public users to access the RedSquirrelNFT's metadata. If we only included the borrowNFT function, the NFTs’ id would be exposed but public users would miss out on all of that rich metadata because that isn’t included in the NonFungibleToken.INFT interface.

NFTMinter Resource

We also include a NFTMinter resource, which is only accessible to the owner of the RedSquirrelNFT contract — so in this case you! The NFTMinter resource is created and added to the contract’s account storage when the contract is initialized. This is the only way that we have allowed a minter to be created, so we can be sure that no one else will be able to get access to the minter, and create new RedSquirrelNFTs without our consent.

Step 3: Deploying to the emulator

Before starting up the emulator, we’ll need to initialize the new Flow project. In a terminal window, from the root of the project, run flow init. This will generate a new flow.json file that includes configuration for connecting to the emulator network. The flow.json file includes an emulator-account address and private key. The address for the emulator service account is f8d6e0586b0a20c7 — this is the account that will sign all of our transactions to our emulator by default. My team decided that since this private key was used for local development, on an emulator whose state is wiped clean on each restart we felt confident checking this file into source control. But when generating private keys for testnet and mainnet, please use caution and do not check those into source control.

Next, we’ll need to include the contracts in the flow.json file, so that they can be deployed. We add each contract name and the path to its source code in the empty contract object:

"contracts": {
"NonFungibleToken":
"./cadence/contracts/standard/NonFungibleToken.cdc",
"MetadataViews":
"./cadence/contracts/standard/MetadataViews.cdc",
"RedSquirrelNFT": "./cadence/contracts/RedSquirrelNFT.cdc"
}

Then we’ll define the deployments specifying which network and account the contracts should be deployed to. The following is specifying that all three contracts (NonFungibleToken, MetadataViews and RedSquirrelNFT) will be deployed to our emulator account, on the emulator network.

"deployments": {
"emulator": {
"emulator-account":
["NonFungibleToken", "MetadataViews", "RedSquirrelNFT"]
}
}
  • In a terminal window, from the root of the project, start up the Flow emulator: flow emulator.
  • In another terminal window, deploy the contracts that we’ve configured in flow.json: flow deploy.

If the deployment succeeded, you should see an output similar to this:

Deploying 3 contracts for accounts: emulator-accountNonFungibleToken -> 0xf8d6e0586b0a20c7 (721c3c7c05192b53c0e53f614d2d8b63457c5f48d19a3bbb6007a42ac3a100ff)MetadataViews -> 0xf8d6e0586b0a20c7 (4b4e5dd091f9c1a7ea6dac16012076ef6251618141b511490cffe6eeb96e007d)RedSquirrelNFT -> 0xf8d6e0586b0a20c7 (96374bf0f02c07a456a1df47481a03acb7fc9302cbf277bee580a2418ffed094)✨ All contracts deployed successfully

Step 4: Interacting with the contract

Now that we have our smart contract deployed to our emulator, it’s time to play with it! There are three ways that we’re going to interact with our contract: first, we’ll set up our emulator service account to receive RedSquirrelNFTs, then we’ll mint a new RedSquirrelNFT, and finally, we’ll get the metadata of the RedSquirrelNFT we’ve just minted.

Setting up the account

Before we can mint a RedSquirrelNFT, let’s create an empty collection in our account to hold future NFTs. We can use the Flow CLI tool to run a transaction that will create an empty collection in our emulator account’s storage. Make sure that the emulator is running, and in another terminal window run:

flow transactions send ./cadence/transactions/set_up_account.cdc

The transaction code that we’re executing from set_up_account.cdc is written in Cadence, and has three main steps:

  1. Creates an empty collection.
  2. Saves the collection in the signing account’s storage (i.e. our emulator service account’s storage).
  3. Creates a publicly accessible link to the collection that’s held in storage.

Minting a new NFT

Now that we have a place to store the RedSquirrelNFTs, let’s start minting! We again use the Flow CLI tool to send a transaction. This time we’ll need to pass in several arguments to the transaction. The transaction call will look like this:

flow transactions send ./cadence/transactions/mint.cdc <Owner Account Address> <NFT Name> <NFT Description> <NFT Ipfs CID>

And with arguments added:

flow transactions send ./cadence/transactions/mint.cdc 0xf8d6e0586b0a20c7 "Mr. Fluffy Ears" "A red squirrel with very fluffy ears enjoying an acorn."    "Qmd6ENNCAJs7coQZFrHpXGZzFNiU83V2GwFcMFMYTXHMx1"

The transaction code we’re executing from mint.cdc also has several steps:

  1. Gets the minter and assigns it to self.minter for use in the execute section.
  2. Gets the recipient’s account.
  3. Borrows a reference to the recipient’s empty collection. We created this ability to borrow the reference to the collection in the 3rd step of the set_up_account transaction.
  4. Mints the new RedSquirrelNFT into the recipient’s collection.

Get the NFT’s metadata

flow scripts execute ./cadence/scripts/get_red_squirrel.cdc <Owner Account Address> <RedSquirrelNFT ID>

Since we’ve only minted one NFT so far and the ids start at 0, we can use 0 as the id argument. And our emulator service account address is again used as the owner address:

flow scripts execute ./cadence/scripts/get_red_squirrel.cdc 0xf8d6e0586b0a20c7 0

Since getting metadata is a publicly available action, this code can be run as a script instead of a transaction. The get_red_squirrel.cdc script:

  1. Gets the owner’s account.
  2. Borrows a reference to the account’s RedSquirrelNFT collection.
  3. Borrows the specific NFT from that collection.
  4. Resolves the view of that NFT.
  5. Returns a custom NFT struct to include all of the data that we’d like to return from the script.

And here’s the result, edited to make the formatting a bit easier to read:

Result: s.70fee1e8869bd90e136ce629f0171aa8992f13a3b454929b631652e5266ac0aa.NFT(
redSquirrelID: 0,
resourceID: 25,
owner: 0xf8d6e0586b0a20c7,
type: "A.f8d6e0586b0a20c7.RedSquirrelNFT.NFT",
name: "Mr. Fluffy Ears",
description: "A red squirrel with very fluffy ears enjoying an acorn.",
thumbnail: "ipfs://Qmd6ENNCAJs7coQZFrHpXGZzFNiU83V2GwFcMFMYTXHMx1"
)

You’ll note that because we’ve implemented an IPFSFile display as part of the MetadataView interface, the thumbnail that is displayed has been formatted as an IPFS link. And to view the IPFS thumbnail in the browser visit infura-ipfs.io. Digging into how IPFS works definitely warrants its own blog post, so for now, we’ll leave it at that! 😉

Step 5: Testing

Cadence currently does not have its own testing library, and the suggestion is to use an SDK from the language of your choice to write tests that exercise key components of the smart contract. The RedSquirrelNFT repository uses the Go SDK and has those tests in a lib/go/cadence_test directory.

These tests are focused on the main interactions we expect to have with the contract: setting up the account, minting a new NFT, getting the total supply of NFTs, and getting the metadata of a specific NFT.

To run them, navigate to the lib/go/cadence_test directory and run: go test -v.

Next Steps

The next step after ensuring that your smart contract works as expected on the emulator is to deploy the contract to testnet and eventually mainnet! Flow includes some helpful documentation to walk you through that process. As of April 2022, a security review of all smart contracts is required before deploying to mainnet to ensure that the ecosystem is safe and secure, but there are plans to open up unrestricted deployments in the near future.

In addition to having quite a bit of solid documentation on Flow’s website, I also found reviewing Dapper Lab’s NBA Top Shots contract and their example smart contracts very helpful as well. RedSquirrelNFT is based on ExampleNFT and the Non-Fungible Token that I worked on with my client was based on KittyItems.

Oh and don’t forget to join their discord!

--

--

Responses (2)