# FlowとCadenceへの入門

By [sagantaf](https://paragraph.com/@sagantaf) · 2022-10-26

---

最近、Flowを勉強してCadenceを触っているので、そのメモとして、FlowとCadenceの概要について整理。

Flow の特徴
--------

*   BitcointやEthereumのようなブロックチェーンの１つ
    
*   ブロックチェーンの専門家ではなく、一般人に向けて開発されている
    
*   デジタルアイテムの「所有」を実現したいというモチベーションで開発がスタートした
    
*   リソース指向の言語で開発できる
    
*   ４種類のノードが存在する
    
    *   Collection, Consensus, Execution, Verification
        
    *   マシンスペックに応じて、４種類の役割を分担することで、効率的な処理を実現している
        
    *   Etherium は１種類のノードで全ての役割を担っている
        
*   エンドユーザーが使うアプリケーションからのアクセスは最初に Access Node が受け、その後、４種類のノードにトランザクションが送られる仕組み
    
*   概要を知れるTED Talk
    
    [![]({{DOMAIN}}/editor/youtube/play.png)](https://www.youtube.com/watch?v=u894J50AqOs)
    

cadence の特徴
-----------

*   Flowを扱うためのプログラミング言語
    
*   強力な静的型付け言語
    
    *   Swift や Kotlin、TypeScript など最近の構文を取り入れている
        
*   リソース指向プログラミング
    
    *   リソースが一度に一箇所にしか存在できない、コピーできない、削除されない、といった特徴がある
        
    *   これによってデジタルの所有権をモデリングしやすくなっている - 関数とトランザクションの前後条件
        
*   関数とトランザクションの前後に条件を記述して、テストができる
    
*   更新可能
    
    *   一定の条件下でコントラクトをアップデート可能
        
*   最小権限の原則
    
    *   オブジェクトへのアクセスは所有者と参照を持つものに制限される
        

Cadence を使う上で理解しておくべき用語
-----------------------

*   アセット：ブロックチェーンを使って所有権を主張したいモノそのもの。
    
*   アカウント：ユーザーが持っているコントラクトとストレージ。通常はウォレットに格納して利用する。
    
*   コントラクト：リソースやインターフェース、関数を定義したプログラム。アカウントにデプロイすることで利用できる。
    
*   リソース：独自に定義されたフィールドと関数を持つ複合型のプログラム。
    
*   トランザクション/スクリプト：コントラクトのリソースや関数を使って、オンチェーンで取引や参照などのロジックを実行するプログラム。
    
*   Capability：アカウントストレージにアクセスするためのリファレンス。
    

### アカウント

*   公式解説ページ：
    
    [https://developers.flow.com/cadence/language/accounts](https://developers.flow.com/cadence/language/accounts)
    
*   アカウントとは、Flow ブロックチェーンを扱う上での個人個人が管理する対象のこと
    
    *   コントラクトやリソース、秘密鍵などが含まれる
        
*   Flow では秘密鍵を複数持てる（multi sig)
    
*   Flow ではアカウント内に２つの領域がある
    
    *   コントラクト領域
        
        *   スマートコントラクトのプログラムを格納する領域
            
        *   アカウントの所有者はここにコントラクトをデプロイし、管理する
            
        *   トランザクションやスクリプトはこの領域には直接アクセスできない（ストレージを経由してコントラクトを利用することになる）
            
        *   他のコントラクトからコントラクトを利用するためには専用のインターフェースを定義する必要がある
            
    *   ファイルシステム領域
        
        *   アカウントが所有するオブジェクトと capability（実行可能な関数へのリファレンス）を格納する領域
            
        *   トランザクションやスクリプトからアクセスできる
            
        *   どのアカウントもファイルシステムの root には `storage` `private` `public`という３つのドメインだけが存在する
            
            *   `storage`: 全てのオブジェクト（token や NFT など）を保存する。アカウントの所有者のみがアクセスできる
                
            *   `private`: storage に保存したオブジェクトへの capability を保存する。アカウントの所有者とアクセス権を持っている人だけがアクセスできる
                
            *   `public`: ネットワーク内の誰もがアカウントの情報を参照できるような capability を保存する
                

### コントラクト

*   公式解説ページ：
    
    [https://developers.flow.com/cadence/language/contracts](https://developers.flow.com/cadence/language/contracts)
    
*   コントラクトはアカウントのオーナーが追加、更新、削除できるコード
    
*   変数、関数、リソース、インターフェース、Capability などを定義する
    
*   コントラクトのサンプル：
    
        pub contract HelloWorld {
            pub let greeting: String // 変数定義
            pub fun hello(): String { // 関数定義
                return self.greeting
            }
            init() { //　初期化処理
                self.greeting = "Hello World!"
            }
        }
        
    
*   各アカウントのコントラクトは、トランザクションや他のアカウントから `import` することによって利用できる。
    
*   ただし変数や関数にはアクセス制御がされている
    
    *   `pub/access(all)`は誰でも利用可能
        
    *   `access(account)`はコントラクトの作成者のみ利用可能
        
    *   `access(contract)`はそのコントラクト内でのみ利用可能
        
    *   `priv/access(self)`は現在のスコープ以下のみ利用可能
        
    *   `pub/access(all)` > `access(account)` > `access(contract)` > `priv/access(self)` の順にスコープが狭くなる
        
    *   詳細は [https://developers.flow.com/cadence/language/access-control](https://developers.flow.com/cadence/language/access-control) を参照
        
*   init()関数はデプロイ時のみ稼働する。デプロイ後はデプロイしたアカウントであっても利用できない
    
        import HelloWorld from 0x02
        log(HelloWorld.hello())    // prints "Hello World!"
        log(HelloWorld.greeting)   // prints "Hello World!"
        HelloWorld.init()    // Error
        
    

### リソース

*   公式解説ページ：
    
    [https://developers.flow.com/cadence/language/resources](https://developers.flow.com/cadence/language/resources)
    
*   リソースとは、データと関数の集まりであり、構造体や Class に似ている cadence 独自の考え方。
    
*   構造体や Class との違いはコピーができない点
    
    *   コピーができないことで、所有権を表現することに使える
        
*   リソースは以下のルールに従うよう作られている
    
    *   １つの場所にだけ存在できる（コピーして同時に複数の場所に存在することはできない）
        
        *   場所とは、アカウントのストレージや、関数実行中の変数などを指す
            
    *   リソースは取り出された時、確実にある場所から他の場所への移動しなければならない
        
    *   リソースはスコープの外側には移動できず、そのスコープ内で最後にはどこかに保存するか、破壊するかを明示しなければならない
        
*   上記ルールに従うことで、コーディングミスによるリソースの紛失やリソースのコピーを防ぎ、所有権の主張ができる状態を生み出している
    
*   インスタンス化したリソースは、アカウントのストレージに保存し、リソースの所有権をアカウントに直接結びつけている
    
*   トランザクションが稼働するマシンのストレージを使わないため、アカウント間で自由にリソースを転送できる
    
    *   イーサリアムなどでは、所有権がスマートコントラクトに保存されるため、リソースの追跡のために全てのスマートコントラクト（つまりトランザクション）を検索する必要がある
        

### トランザクション

*   公式解説ページ：
    
    [https://developers.flow.com/cadence/language/transactions](https://developers.flow.com/cadence/language/transactions)
    
*   トランザクションとしてオンチェーンで実行させたいプログラム
    
*   データの変更が伴う処理に利用され、そのためにはそのデータの更新権限を取得する必要がある
    
*   データの更新権限を取得するには、トランザクションのプログラムに対して対象データを保存しているアカウントが秘密鍵で署名する必要がある
    
    *   署名したアカウントは Authorizers や Signers と呼ばれる
        
    *   例えば アカウント A と アカウント B で NFT の所有者を変更したい時には、アカウント A と B でトランザクションを承認(sign)することになる
        
*   トランザクション実行にはガス代がかかる
    
*   トランザクションコードの例：
    
        import HelloWorld from 0x01
        transaction {
          prepare(acct: AuthAccount) {}
          execute {
              log(HelloWorld.hello())
              log(HelloWorld.greeting)
          }
        }
        
    

### スクリプト

*   トランザクションとは異なり、データの変更が発生しない、情報を参照するだけの処理のことを指す
    
*   そのため、署名のプロセスは発生しない
    
*   ガス代はかからない
    

開発する時には
-------

### 開発の流れ

*   スマートコントラクトを実装する
    
    *   実装
        
    *   エミュレータ環境でテスト
        
    *   テストネット環境にデプロイして動作確認
        
    *   メインネット環境にデプロイして動作確認
        
*   フロントエンド/バックエンドを実装する
    
    *   Flow Client Library（JavaScript）や Flow Go SDK を利用
        

### cadence のプレイグラウンド

スマートコントラクトを実際に書いて試せる Palyground を Flow 公式が用意している

[https://play.onflow.org/local-project:embed](https://play.onflow.org/local-project:embed)

### テストネット

Flow のテストネット

[https://docs.onflow.org/concepts/accessing-testnet/](https://docs.onflow.org/concepts/accessing-testnet/)

### Flow CLI

エミュレータ、テストネット、メインネットでの開発に使えるコマンド

*   `flow emulator`でエミュレータを起動したり
    
*   `flow deply`でコントラクトをデプロイしたり
    

といった使い方ができる

参考にできるソースコード
------------

*   cadence で書かれた NFT マーケットプレイスのサンプルプロジェクト
    
    [https://github.com/onflow/kitty-items](https://github.com/onflow/kitty-items)
    
*   NBA Top Shot のコントラクトの実装
    
    [https://github.com/dapperlabs/nba-smart-contracts](https://github.com/dapperlabs/nba-smart-contracts)

---

*Originally published on [sagantaf](https://paragraph.com/@sagantaf/flow-cadence)*
