Skip to main content

How to Create and Deploy a Smart Contract with Cadence on Flow

Updated on
Dec 11, 2023

10 min read

Overview

Developing on Ethereum can get expensive, but what if there was a more accessible and efficient alternative?

Flow is a blockchain technology that operates on the Layer-1 protocol, enabling it to achieve high scalability without sharding. Its unique multi-role architecture sets it apart from other blockchains and allows it to scale vertically. While features like upgradeable smart contracts and built-in logging support are attractive for developers, the smart user accounts feature, which eliminates the problem of losing the seed phrase is crucial to make the user experience better and safer.

In this guide, you will learn about Flow, an innovative blockchain platform that redefines simplicity and scalability. Here, you'll discover how to create a HelloWorld smart contract and interact with it using Flow's intuitive programming language, Cadence, and the robust tools QuickNode and Flow CLI.

While our exploratory journey takes place in Flow Testnet's sandbox, rest assured that the skills you'll acquire are completely transferable to Flow Mainnet. Let's turn the tides and transform the complex into simplicity together!

What You Will Need

You can download and install each dependency by clicking the links above and following their instructions.

Dependencies Used in this Guide

DependencyVersion
node.js18.16.0
flow-cli1.1.1

What You Will Do

  • Learn about the Flow blockchain
  • Learn about the Cadence programming language
  • Create a Flow wallet using Flow CLI
  • Build a simple HelloWorld smart contract
  • Deploy the smart contract on the Flow blockchain
  • Interact with the smart contract

What Makes Flow Different?

Pipelining

Flow proposes a new solution to improve scalability, decentralization, and security without increasing complexity for developers. Thanks to their multi-node architecture, this is achieved through specialized node types that handle different tasks along the transaction pipeline.

Flow employs pipelining techniques by splitting a validator node's tasks into four distinct roles—collection, consensus, execution, and verification.

Flow Pipelining Pipelining, Image Sources: Stanford CS Department

Upgradability

Most smart contracts are immutable and cannot be changed unless complicated upgradeable proxy design patterns are used in deployment. However, Flow blockchain has an option called beta state, allowing developers to update their smart contracts easily. While interacting with the contract, users are informed that it is in beta and have the option of waiting until the code is complete. The contract is immutable after the beta state.

Smart Contract Programming Language - Cadence

Cadence, a resource-oriented programming language, is used for smart contract deployment in Flow.

If you are a Solidity developer, you may feel uncomfortable with Cadence's novel approach to smart contract creation. There are significant variations in platform, attitude, and some new language features that Solidity doesn't support. Reviewing Guide for Solidity developers may be useful since it is prepared to onboard Solidity developers to Flow blockchain.

Developer Set Up

Accessing Flow with QuickNode

In this guide, gRPC API endpoints are used. However, it is highly recommended to use QuickNode's endpoints when using the REST API.

To build on Flow, you'll need an API endpoint to connect with the network. You're welcome to use public nodes or deploy and manage your own infrastructure; however, if you'd like 8x faster response times, you can leave the heavy lifting to us. See why over 50% of projects on Flow choose QuickNode and sign up for a free account here.

QuickNode Endpoints

Setting Up the Project

You need a terminal emulator (i.e., Terminal, Windows PowerShell) and code editor (i.e., Visual Studio Code) to set up the project.

Run the following code in your terminal to set up the project. Our project folder's name will be helloWorld, but you can modify the name as you wish. The --scaffold flag is for using provided scaffolds, which are project templates you can use to bootstrap your development.

flow setup helloWorld --scaffold

If the terminal needs your input for scaffold number, you can select the first option [1] Empty Cadence Project. It creates a basic folder structure and flow.json configuration file, a config file with networks, accounts, deployments, and contracts properties inside the helloWorld folder.

Run the command to change your directory.

cd helloWorld

With the project folder created, you can now move on to creating a Flow wallet.

Creating a Flow Wallet

You must create an account on the Flow blockchain using Flow CLI to deploy a smart contract. Luckily, Flow CLI has a useful command to create a wallet and fund it automatically.

To set up the wallet, run the following code in your terminal.

flow accounts create

Then, enter an account name and select the network. We type "testnet-account" as the account name and select "Testnet" as the network.

The console output should be like the one below.

🎉 New account created with address 0x66105514db20bf0d and name testnet-account on Testnet network.

Here's a summary of all the actions that were taken:
- Added the new account to flow.json.
- Saved the private key to testnet-account.pkey.
- Added testnet-account.pkey to .gitignore.

As mentioned in the output, this command performs these actions:


  • Adds the new account to the flow.json file
  • Saves the private key to the pkey file
  • Adds the pkey file to the .gitignore file

After this step, your account is created and funded.

Checking the Configuration File

Flow configuration file (flow.json) is used to define networks (i.e., mainnet, testnet), accounts, deployment targets, and contracts that will be deployed. Thus, the following properties should be included in the configuration file:


  • networks which pre-defines the Flow emulator, testnet, and mainnet connection configuration
  • accounts which pre-defines the Flow emulator account and your newly created account
  • deployments where all deployment targets can be defined
  • contracts where all contracts that will be used in the project can be defined

The file's default state may not have all mentioned properties. If so, you can add missing properties, as in the example below. Also, if there are already some contract definitions in the contracts property, you can delete them since they are not used in this guide.

Open the flow.json file with your text editor and make sure that you modify it to be similar to the sample file below.

{
"networks": {
"emulator": "127.0.0.1:3569",
"mainnet": "access.mainnet.nodes.onflow.org:9000",
"testnet": "access.devnet.nodes.onflow.org:9000"
},
"accounts": {
"emulator-account": {
"address": "f8d6e0586b0a20c7",
"key": "6d12eebfef9866c9b6fa92b97c6e705c26a1785b1e7944da701fc545a51d4673"
},
"YOUR_ACCOUNT_NAME": {
"address": "YOUR_ACCOUNT_ADDRESS",
"key": {
"type": "file",
"location": "YOUR_WALLET_PKEY_FILE"
}
}
},
"deployments": {},
"contracts": {}
}

When we created a wallet using the flow accounts create command previously, our account was added to this config file automatically. However, if you had wallet credentials you wanted to import, you would add them here. (See Flow CLI Configuration documentation for details.)

Below you will see your account credentials outlined in the accounts object.

The placeholders YOUR_ACCOUNT_NAME, YOUR_ACCOUNT_ADDRESS, and YOUR_WALLET_PKEY_FILE above represent your account name, account address, and private key (pkey) file.

  • YOUR_ACCOUNT_NAME is the account name that you choose during the account creation.

  • YOUR_ACCOUNT_ADDRESS is the address that is given after creating the account. The account address will be different in your file.

  • YOUR_WALLET_PKEY_FILE is the private key file that contains the private key of your account. Private key is imported from the pkey file. The file name may differ if your account name is different.

Once the helloWorld smart contract is created, you must configure the deployments and contracts objects within flow.json. This will be explained in the following sections.

Creating the Smart Contract

In this guide, a simple Hello World smart contract will be used. The coding part is shared and explained in detail here.

Go to the ./cadence/contracts directory and create a file named HelloWorld.cdc in it by running the commands below.

cd cadence/contracts
echo > HelloWorld.cdc

So far, the folder structure should be like the one below.

├── README.md
├── cadence
│ ├── contracts
│ │ └── HelloWorld.cdc
│ ├── scripts
│ ├── tests
│ └── transactions
├── flow.json
└── testnet-account.pkey

Then, open the HelloWorld.cdc file with your code editor. Copy the code below and paste it into the file.

The smart contract declares a public field of String type called greeting, and defines it as "Hello, World" during the initialization of the smart contract. Also, the hello function returns the greeting value.

// HelloWorld.cdc
//
pub contract HelloWorld {

// Declare a public field of type String.
//
// All fields must be initialized in the init() function.
pub let greeting: String

// The init() function is required if the contract contains any fields.
init() {
self.greeting = "Hello, World!"
}

// Public function that returns our friendly greeting!
pub fun hello(): String {
return self.greeting
}
}

Preparing for Deployment

As you may have noticed, deployments and contracts properties in the sample config have been blank up to now. You need to modify it according to the smart contracts.

In the contracts property, the name and path of all smart contracts are defined, respectively.


  • HelloWorld is the name of the smart contract,
  • ./cadence/contracts/HelloWorld.cdc is the path of the smart contract.

In the deployments property, account name, and all smart contracts are defined.


  • testnet is the network name, which refers the testnet value we have configured in the network object
  • testnet-account is the account name that you chose when creating the Flow wallet, which refers the testnet-account object in the account object
  • [HelloWorld] is the array that includes smart contract names, which are defined in the contract object, to be deployed

You can review the latest config file and the image to clarify all definitions. See the arrows in the image to understand references well.

Also, please be ensure that the account name, account address, and pkey file name are associated with your account. The image below shows our account credentials.

The emulator account's private key is public and should be used only for local development. So, this is why its key is unhidden.

Config File Config file

{
"networks": {
"emulator": "127.0.0.1:3569",
"mainnet": "access.mainnet.nodes.onflow.org:9000",
"testnet": "access.devnet.nodes.onflow.org:9000"
},
"accounts": {
"emulator-account": {
"address": "f8d6e0586b0a20c7",
"key": "6d12eebfef9866c9b6fa92b97c6e705c26a1785b1e7944da701fc545a51d4673"
},
"YOUR_ACCOUNT_NAME": {
"address": "YOUR_ACCOUNT_ADDRESS",
"key": {
"type": "file",
"location": "YOUR_WALLET_PKEY_FILE"
}
}
},
"deployments": {
"testnet": {
"YOUR_ACCOUNT_NAME": ["HelloWorld"]
}
},
"contracts": {
"HelloWorld": "./cadence/contracts/HelloWorld.cdc"
}
}

Deployment

Everything is ready to deploy a smart contract to Flow testnet. Make sure that you are in the main directory (helloWorld) in your terminal. If you are in the cadence/contracts folder, run the following code to change your directory.

cd ../..

Run the following code in your terminal to deploy the HelloWorld smart contract.

flow project deploy --network=testnet

The console output should be like the one below if everything goes well.

Deploying 1 contracts for accounts: testnet-account

HelloWorld -> 0x66105514db20bf0d (3b601c2d8eba20f7066f10d69208a13463d2a5e97488dae55940edbfae87e5a7)

🎉 All contracts deployed successfully

You can check your account balance, smart contracts, and transactions on the Flow block explorer.


Interact with the Smart Contract

Now, let's learn how to interact with the smart contract using Flow CLI.

Create a script file called getHello.cdc under the cadence/scripts folder by running the commands below.

cd cadence/scripts
echo > getHello.cdc

Paste the code below into the script file. The script calls the hello() function of the HelloWorld smart contract.

import "HelloWorld"

pub fun main(): String {
return HelloWorld.hello()
}

Run the following code to go to the main directory (helloWorld).

cd ../..

Run the command below to run the script file.

flow scripts execute ./cadence/scripts/getHello.cdc --network=testnet

The console output should be like the one below. As you notice, it returns a value of greeting when calling the hello function of the HelloWorld smart contract.

Result: "Hello, World!"

Congratulations! You just deployed your first smart contract on Flow Testnet and learned how to interact with it!

Flow Ecosystem

Check out the following links to get more information on Flow:

Conclusion

That's it! By now, you should have a clear understanding of how to create and deploy smart contracts on Flow using Cadence. We've guided you every step of the way. First, we helped you understand the basics of Flow and Cadence. Then, we moved on to creating and funding a wallet. Finally, we went through the process of writing a smart contract and deploying it onto the Flow network.

Remember, learning is a process, and practice is essential to become proficient in any new skill. So, don't stop at just understanding; start creating and deploying your smart contracts!

If you encounter any problems or have any questions, we'd love to help you! Find us on Discord or Twitter.

We ❤️ Feedback!

Let us know if you have any feedback or requests for new topics. We'd love to hear from you.

Share this guide