Hello World Pt. 2 - Local Development
The Flow Command Line Interface (CLI) is a set of tools that developers can use to interact with the Flow blockchain by managing accounts, sending transactions, deploying smart contracts, running the emulator, and more. This quickstart will get you familiar with its main concepts and functionality.
Installation
The first thing you'll need to do is install the Flow CLI. If you have homebrew installed you can run:
_10brew install flow-cli
For other ways of installing, please refer to the installation guide.
Configuration
Lets first create the scaffolded project:
_10flow setup cli-quickstart
And then let's navigate to our new directory:
_10cd cli-quickstart
If you look at flow.json now, you'll see its listed access nodes for networks and accounts. The default emulator-account create will come in handy when we want to run the emulator.
_71{_71  "contracts": {_71    "FlowToken": {_71      "source": "cadence/contracts/utility/FlowToken.cdc",_71      "aliases": {_71        "emulator": "0ae53cb6e3f42a79",_71        "testnet": "7e60df042a9c0868",_71        "mainnet": "1654653399040a61"_71      }_71    },_71    "FungibleToken": {_71      "source": "cadence/contracts/utility/FungibleToken.cdc",_71      "aliases": {_71        "emulator": "ee82856bf20e2aa6",_71        "testnet": "9a0766d93b6608b7",_71        "mainnet": "f233dcee88fe0abe"_71      }_71    },_71    "FungibleTokenMetadataViews": {_71      "source": "cadence/contracts/utility/FungibleTokenMetadataViews.cdc",_71      "aliases": {_71        "emulator": "ee82856bf20e2aa6",_71        "testnet": "9a0766d93b6608b7",_71        "mainnet": "f233dcee88fe0abe"_71      }_71    },_71    "MetadataViews": {_71      "source": "cadence/contracts/utility/MetadataViews.cdc",_71      "aliases": {_71        "emulator": "f8d6e0586b0a20c7",_71        "testnet": "631e88ae7f1d7c20",_71        "mainnet": "1d7e57aa55817448"_71      }_71    },_71    "RandomBeaconHistory": {_71      "source": "cadence/contracts/utility/RandomBeaconHistory.cdc",_71      "aliases": {_71        "emulator": "f8d6e0586b0a20c7",_71        "testnet": "8c5303eaa26202d6",_71        "mainnet": "e467b9dd11fa00df"_71      }_71    },_71    "ViewResolver": {_71      "source": "cadence/contracts/utility/ViewResolver.cdc",_71      "aliases": {_71        "emulator": "f8d6e0586b0a20c7",_71        "testnet": "631e88ae7f1d7c20",_71        "mainnet": "1d7e57aa55817448"_71      }_71    },_71    "NonFungibleToken": {_71      "source": "cadence/contracts/kitty-items/NonFungibleToken.cdc",_71      "aliases": {_71        "emulator": "f8d6e0586b0a20c7",_71        "testnet": "631e88ae7f1d7c20",_71        "mainnet": "1d7e57aa55817448"_71      }_71    }_71  },_71  "networks": {_71    "emulator": "127.0.0.1:3569",_71    "mainnet": "access.mainnet.nodes.onflow.org:9000",_71    "testnet": "access.devnet.nodes.onflow.org:9000"_71  },_71  "accounts": {_71    "emulator-account": {_71      "address": "f8d6e0586b0a20c7",_71      "key": "6d12eebfef9866c9b6fa92b97c6e705c26a1785b1e7944da701fc545a51d4673"_71    }_71  }_71}
For additional details on how flow.json is configured, read here.
Running Scripts
On Flow, scripts are used to read data from the Flow blockchain. There is no state modification. In our case, we are going to read a greeting from a contract deployed to testnet called HelloWorld. (You can view the contract here)
Let's create a script file:
_10touch script.cdc
Then in the script file, let's put the following code:
_10import HelloWorld from 0x9dca641e9a4b691b_10_10pub fun main(): String {_10  return HelloWorld.greeting_10}
In the above example, 0x9dca641e9a4b691b is the address where the HelloWorld contract has been deployed to on testnet. (Note: if you'll like to learn more about writing scripts, please read here).
To run the script, we'll run this from the CLI:
_10flow scripts execute script.cdc --network testnet
You should see the result of the greeting. Result: "Hello, world!"
Running the Contract Locally on Emulator
The Flow Emulator is a local, lightweight, and standalone version of the Flow blockchain. It's designed to provide developers with a local environment for testing and development purposes without having to interact with the mainnet or testnet. This makes it easier and faster to develop, test, and debug smart contracts and apps.
In order to use it, let's update our project configuration.
Let's create a local version of the HelloWorld contract. We'll deploy it to the emulator, Run:
_10touch HelloWorld.cdc
Copy the contract to HelloWorld.cdc.
_12pub contract HelloWorld {_12_12  pub var greeting: String_12_12  pub fun changeGreeting(newGreeting: String) {_12    self.greeting = newGreeting_12  }_12_12  init() {_12    self.greeting = "Hello, World!"_12  }_12}
Next we'll add a contracts section to our flow.json configuration that will describe our project setup. We'll state the contract file location lives with source and then define aliases for the addresses of the deployed contracts.
_14// flow.json_14_14{_14..._14"contracts": {_14  "HelloWorld": {_14    "source": "HelloWorld.cdc",_14    "aliases": {_14      "testnet": "0x9dca641e9a4b691b"_14    }_14  }_14}_14..._14}
We're also going to change the imports of our script so that there are no hardcoded network specific addresses. The CLI can figure out how to interact with the network (i.e. emulator, testnet or mainnet) based on our configuration.
_10// script.cdc_10_10import "HelloWorld"_10_10pub fun main(): String {_10  return HelloWorld.greeting_10}
Next, we'll add a deployments section to flow.json and define what account we'd like what contract deployed to and on what network. In this case, let's deploy the HelloWorld contract to the emulator network and on emulator-account provided.
_10// flow.json_10_10{_10..._10"deployments": {_10  "emulator": {_10    "emulator-account": ["HelloWorld"]_10}_10..._10}
Next let's run the emulator in a new terminal with:
_10flow emulator start
And then deploy the contract with:
_10flow project deploy
Now if we run the following script we should see the result of the script against our emulator deployed contract.
_10flow scripts execute script.cdc --network emulator
Creating an Account and Running a Transaction
To change state on the Flow Blockchain, you need to run a transaction. Let's create a simple transaction file. We can use to modify the greeting on the HelloWorld contract.
First, create a file called transaction.cdc from the root of your project:
_10touch transaction.cdc
Then copy the following code:
_12import "HelloWorld"_12_12transaction(greeting: String) {_12_12  prepare(acct: AuthAccount) {_12    log(acct.address)_12  }_12_12  execute {_12    HelloWorld.changeGreeting(newGreeting: greeting)_12  }_12}
This will log the account signing the transaction, call the changeGreeting method of the HelloWorld contract, and pass in the new greeting. (If you want to learn more about writing transactions, please read here).
In order to run a transaction, the signing account needs to pay for it. We could run a transaction on emulator using the default emulator-account account. Let's learn one more command for creating accounts.
The easiest way to create an account using CLI is by running (remember, your emulator should still be running at this point in another terminal):
_10flow accounts create
Once that runs, select Emulator as the network and give your account the name emulator-tester. You'll now see this account in your flow.json.
To run a transaction with this new account, you can run the following:
_10flow transactions send ./transaction.cdc "Hello, me" --signer emulator-tester --network emulator
You've just modified the state of the Flow Blockchain!
Next Steps
Dive deeper by checking out the scaffolds generated by the Flow CLI. They can serve as a great starting point for any project you're trying to create. See how to create a scaffold here.