最近、Flowを勉強してCadenceを触っているので、そのメモとして、FlowとCadenceの概要について整理。
(試しに同じ内容をWeb3のブログプラットフォームである mirror.xyz にも投稿してみてます → FlowとCadenceへの入門 — sagantaf)
目次
Flow の特徴
- BitcointやEthereumのようなブロックチェーンの1つ
- ブロックチェーンの専門家ではなく、一般人に向けて開発されている
- デジタルアイテムの「所有」を実現したいというモチベーションで開発がスタートした
- リソース指向の言語で開発できる
4種類のノードが存在する
- Collection, Consensus, Execution, Verification
- マシンスペックに応じて、4種類の役割を分担することで、効率的な処理を実現している
- Etherium は1種類のノードで全ての役割を担っている
エンドユーザーが使うアプリケーションからのアクセスは最初に Access Node が受け、その後、4種類のノードにトランザクションが送られる仕組み
概要を知れるTED Talk
cadence の特徴
Flowを扱うためのプログラミング言語
強力な静的型付け言語
- Swift や Kotlin、TypeScript など最近の構文を取り入れている
リソース指向プログラミング
- リソースが一度に一箇所にしか存在できない、コピーできない、削除されない、といった特徴がある
- これによってデジタルの所有権をモデリングしやすくなっている
関数とトランザクションの前後条件
- 関数とトランザクションの前後に条件を記述して、テストができる
更新可能
- 一定の条件下でコントラクトをアップデート可能
最小権限の原則
- オブジェクトへのアクセスは所有者と参照を持つものに制限される
Cadence を使う上で理解しておくべき用語
用語 | 概要 |
---|---|
アセット | ブロックチェーンを使って所有権を主張したいモノそのもの。 |
アカウント | ユーザーが持っているコントラクトとストレージ。通常はウォレットに格納して利用する。 |
コントラクト | リソースやインターフェース、関数を定義したプログラム。アカウントにデプロイすることで利用できる。 |
リソース | 独自に定義されたフィールドと関数を持つ複合型のプログラム。 |
トランザクション/スクリプト | コントラクトのリソースや関数を使って、オンチェーンで取引や参照などのロジックを実行するプログラム。 |
Capability | アカウントストレージにアクセスするためのリファレンス。 |
アカウント
- 公式解説ページ: Accounts | Flow Blockchain
- アカウントとは、Flow ブロックチェーンを扱う上での個人個人が管理する対象のこと
- Flow では秘密鍵を複数持てる(multi sig)
- Flow ではアカウント内に2つの領域がある
- コントラクト領域
- ファイルシステム領域
- アカウントが所有するオブジェクトと capability(実行可能な関数へのリファレンス)を格納する領域
- トランザクションやスクリプトからアクセスできる
- どのアカウントもファイルシステムの root には
storage
private
public
という3つのドメインだけが存在するstorage
: 全てのオブジェクト(token や NFT など)を保存する。アカウントの所有者のみがアクセスできるprivate
: storage に保存したオブジェクトへの capability を保存する。アカウントの所有者とアクセス権を持っている人だけがアクセスできるpublic
: ネットワーク内の誰もがアカウントの情報を参照できるような capability を保存する
コントラクト
- 公式解説ページ:Contracts | Flow Blockchain
- コントラクトはアカウントのオーナーが追加、更新、削除できるコード
- 変数、関数、リソース、インターフェース、Capability などを定義する
コントラクトのサンプル:
pub contract HelloWorld { pub let greeting: String // 変数定義 pub fun hello(): String { // 関数定義 return self.greeting } init() { // 初期化処理 self.greeting = "Hello World!" } }
- ただし変数や関数にはアクセス制御がされている
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 を参照
init()関数はデプロイ時のみ稼働する。デプロイ後はデプロイしたアカウントであっても利用できない
import HelloWorld from 0x02 log(HelloWorld.hello()) // prints "Hello World!" log(HelloWorld.greeting) // prints "Hello World!" HelloWorld.init() // Error
リソース
公式解説ページ: Resources | Flow Blockchain
リソースとは、データと関数の集まりであり、構造体や Class に似ている cadence 独自の考え方。
- 構造体や Class との違いはコピーができない点
- コピーができないことで、所有権を表現することに使える
- リソースは以下のルールに従うよう作られている
- 1つの場所にだけ存在できる(コピーして同時に複数の場所に存在することはできない)
- 場所とは、アカウントのストレージや、関数実行中の変数などを指す
- リソースは取り出された時、確実にある場所から他の場所への移動しなければならない
- リソースはスコープの外側には移動できず、そのスコープ内で最後にはどこかに保存するか、破壊するかを明示しなければならない
- 1つの場所にだけ存在できる(コピーして同時に複数の場所に存在することはできない)
- 上記ルールに従うことで、コーディングミスによるリソースの紛失やリソースのコピーを防ぎ、所有権の主張ができる状態を生み出している
- インスタンス化したリソースは、アカウントのストレージに保存し、リソースの所有権をアカウントに直接結びつけている
- トランザクションが稼働するマシンのストレージを使わないため、アカウント間で自由にリソースを転送できる
トランザクション
公式解説ページ: Transactions | Flow Blockchain
トランザクションとしてオンチェーンで実行させたいプログラム
- データの変更が伴う処理に利用され、そのためにはそのデータの更新権限を取得する必要がある
- データの更新権限を取得するには、トランザクションのプログラムに対して対象データを保存しているアカウントが秘密鍵で署名する必要がある
- トランザクション実行にはガス代がかかる
トランザクションコードの例:
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 公式が用意している
テストネット
Flow のテストネット
Flow Testnet | Flow Blockchain
Flow CLI
参考にできるソースコード
- cadence で書かれた NFT マーケットプレイスのサンプルプロジェクト