sagantaf

メモレベルの技術記事を書くブログ。

Cadence を実行できるローカル環境の構築と Flow CLI の使い方

概要

以下の2つを利用してローカルにCadenceを実行できる環境を構築する。

OS は MacOS Monterey Version 12.6

環境を構築する

  • Flow CLI をインストールし初期化

まずは CLI をインストールし、初期化する。初期化するとその場に flow.json が生成されるため、実行する前に目的のディレクトリに移動しておくこと。

brew install flow-cli
flow init

無事初期化できると以下のようなアウトプットが表示される。

Configuration initialized
Service account: 0xf8d6e0586b0a20c7

Start emulator by running: 'flow emulator'
Reset configuration using: 'flow init --reset'

また、コマンドを実行したディレクトリに生成された flow.json には emulator やメインネットのネットワーク情報や、上記アカウント名や鍵などのアカウント情報が記載されている。ここに記載されているアカウントはエミュレーターのデフォルトアカウントとしてコントラクトのデプロイ時に利用される。

続いてエミュレーターを起動する。

flow emulator -v

-vlog()の結果を出力するためのオプション。

そのほか、ポート番号など指定できるパラメータは flow emulator -h で確認できる。

起動すると以下のようなアウトプットが表示される。

INFO[0000] ⚙️   Using service account 0xf8d6e0586b0a20c7  serviceAddress=f8d6e0586b0a20c7 serviceHashAlgo=SHA3_256 servicePrivKey=省略 servicePubKey=省略 serviceSigAlgo=ECDSA_P256
INFO[0000] 📜  Flow contract                              FlowServiceAccount=0xf8d6e0586b0a20c7
INFO[0000] 📜  Flow contract                              FlowToken=0x0ae53cb6e3f42a79
INFO[0000] 📜  Flow contract                              FungibleToken=0xee82856bf20e2aa6
INFO[0000] 📜  Flow contract                              FlowFees=0xe5a8b7f23e8b548f
INFO[0000] 📜  Flow contract                              FlowStorageFees=0xf8d6e0586b0a20c7
INFO[0000] 🌱  Starting gRPC server on port 3569          port=3569
INFO[0000] 🌱  Starting REST API on port 8888             port=8888
INFO[0000] 🌱  Starting admin server on port 8080         port=8080
INFO[0000] ✅  Started REST API server on port 8888       port=8888
INFO[0000] ✅  Started gRPC server on port 3569           port=3569
INFO[0000] ✅  Started admin server on port 8080          port=8080

これで準備は整った。エミュレーターを実行したターミナルはそのままにしておき、別ターミナルで以降を実行する。

なお、以降の Cadence のソースコードFlow Playground のものを一部編集して利用している。

コントラクトをデプロイしてみる

contracts ディレクトリを作成し、そこに HelloWorld.cdc を作成する。

mkdir -p ./cadence/contracts/
# HelloWorld.cdc
pub contract HelloWorld {
    pub let greeting: String
    init() {
        self.greeting = "Hello, World!"
    }
    pub fun hello(): String {
        return self.greeting
    }
}

上記ファイルを生成したら、flow.jsonに contracts と deployment の情報を追記する。

{
  (省略)
  "contracts": {
    "HelloWorld": "./cadence/contracts/HelloWorld.cdc"
  },
  "deployments": {
    "emulator": {
      "emulator-account": ["HelloWorld"]
    }
  }
}

デプロイを実行する。

flow project deploy

問題なくデプロイできると以下のように表示される。

Deploying 1 contracts for accounts: emulator-account

HelloWorld -> 0xf8d6e0586b0a20c7 (afa75f0edef80cd5ed4a7cc8871691fe4fb1981f35977605963f1c308dce921e)


🎉 All contracts deployed successfully

エミュレーターを起動しているターミナルには以下のようなログが出力される。

INFO[1333] ⭐  Transaction executed                       computationUsed=4 txID=afa75f0edef80cd5ed4a7cc8871691fe4fb1981f35977605963f1c308dce921e

また、アカウントの情報を以下のコマンドで取得することができる。

flow accounts get 0xf8d6e0586b0a20c7

以下のようなアウトプットが表示され、HelloWorld のコントラクトが含まれていることを確認できる。

Address  0xf8d6e0586b0a20c7
Balance  999999999.99700000
Keys     1

Key 0   Public Key               cb16b02519dd957d04e321cb6cd74e219243ea50b73c77617bf3036fa27bfaea3996da2559e2e1baf010890ad6293ee6a90a85e3d37baf44e51b110071d67539
        Weight                   1000
        Signature Algorithm      ECDSA_P256
        Hash Algorithm           SHA3_256
        Revoked                  false
        Sequence Number          1
        Index                    0

Contracts Deployed: 11
Contract: 'FlowStorageFees'
Contract: 'FlowContractAudits'
Contract: 'StakingProxy'
Contract: 'FlowEpoch'
Contract: 'FlowIDTableStaking'
Contract: 'FlowClusterQC'
Contract: 'HelloWorld'
Contract: 'FlowServiceAccount'
Contract: 'FlowStakingCollection'
Contract: 'LockedTokens'
Contract: 'FlowDKG'


Contracts (hidden, use --include contracts)

トランザクションを実行する

デプロイしたコントラクトを使ってトランザクションを実行してみる。

transactions ディレクトリを作成し、そこに say_hello.cdc を作成する。

mkdir -p ./cadence/transactions/
# say_hello.cdc
import HelloWorld from "../contracts/HelloWorld.cdc"
transaction {
  prepare(acct: AuthAccount) {}
  execute {
    log(HelloWorld.hello())
  }
}

本来はアカウントのアドレスを指定して import するが、エミュレーターではファイルを直接指定して稼働させる。アカウントのアドレスを指定できるようにする方法は後述。

ではトランザクションを実行する。

flow transactions send ./cadence/transactions/say_hello.cdc

実行に成功すると以下のようなアウトプットが表示される。

Transaction ID: 34a095de0f3bbca07d28ee59ef2973ea4a7d2cf08ca4433b8e287b85205479e6

Status          ✅ SEALED
ID              34a095de0f3bbca07d28ee59ef2973ea4a7d2cf08ca4433b8e287b85205479e6
Payer           f8d6e0586b0a20c7
Authorizers     [f8d6e0586b0a20c7]

Proposal Key:
    Address     f8d6e0586b0a20c7
    Index       0
    Sequence    1

No Payload Signatures

Envelope Signature 0: f8d6e0586b0a20c7
Signatures (minimized, use --include signatures)

Events:  None


Code (hidden, use --include code)

Payload (hidden, use --include payload)

エミュレーターを起動しているターミナルにも DEBU[0172] LOG [3542ba] "Hello, World!"と表示される。

スクリプトを実行する

デプロイしたコントラクトを使ってスクリプトを実行してみる。

scripts ディレクトリを作成し、そこに greeting.cdc を作成する。

mkdir -p ./cadence/scripts/
# greeting.cdc
import HelloWorld from "../contracts/HelloWorld.cdc"

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

ファイルを作成したら以下のコマンドで実行する。

flow scripts execute cadence/scripts/greeting.cdc

以下のようなアウトプットが表示されれば成功。

Result: "Hello, World!"

アカウントを作る

まずは鍵情報を生成する。

flow keys generate

出力はセキュアな情報なので省略。Private KeyPublic Keyはメモっておく。

表示された Public Key を使ってアカウントを作ることができる。

flow accounts create --key <上記コマンドで表示されたPublic Key>

成功するとアドレスが表示される。

Transaction ID: 98f14051bd6d19d771934f4ed73876b1f3bb970589c8cfb6e7bcb06e3079a4e1

Address  0x01cf0e2f2f715450
Balance  0.00100000
Keys     1

(省略)

flow.json にアカウントの情報を追加する。address部分には上記で表示されたAddressの 接頭値0xを除いた文字列を記載する。key部分にはflow keys generateを実行したときに表示されたPrivate Keyを記載する。また、deploymentsにてアカウント名を変更し、created-account にデプロイされるようにしている。

{
  (省略)
  "accounts": {
    "emulator-account": {
      (省略)
    },
    "created-account": {
      "address": "01cf0e2f2f715450",
      "key": "<Private Key>"
    }
  },
  "deployments": {
    "emulator": {
      "created-account": ["HelloWorld"]
    }
  }
}

flow.json を更新したらコントラクトをもう一度デプロイする。

flow project deploy

アカウントの情報を確認すると、HelloWorld のコントラクトを確認できる。

flow accounts get 0x01cf0e2f2f715450
Contracts Deployed: 1
Contract: 'HelloWorld'

アカウントのアドレス指定して import 可能にする

flow.json の contracts 部分を以下のように記載することでコントラクトに対するエイリアスが生成される。これでトランザクションスクリプトでの import 時にエイリアスに指定したアドレスを利用できる。

"contracts": {
    "HelloWorld": {
      "source": "./cadence/contracts/HelloWorld.cdc",
      "aliases": {
        "emulator": "01cf0e2f2f715450"
      }
    }
  },

トランザクションは以下のようになる。アドレスの頭に 0x をつけていることに注意。

# say_hello.cdc
import HelloWorld from 0x01cf0e2f2f715450
transaction {
  prepare(acct: AuthAccount) {}
  execute {
    log(HelloWorld.hello())
  }
}

その他

Flow-CLI の設定ファイルである flow.json のより詳細な使い方は、flow-cli/configuration に書いてある。

FlowとCadenceの入門的な情報をまとめた記事はこちら:

sagantaf.hatenablog.com