NFT特化flowブロックチェーンに入門するためにcadence言語を学ぶ[Hello World編]

この記事は筆者の[ソロ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/panda) 19日目の記事です。

今回からはweb3領域の記事としてflowチェーン上にデプロイするスマートコントラクトを記述するためのcadenceについて学んでみたのでその備忘録として書いていきたいと思います。

[NFT特化flowブロックチェーンに入門するためにcadence言語を学ぶ[Hello World編]](https://qiita.com/JY8752/private/3f8c742409598d18630b) <- 今ここ
[NFT特化flowブロックチェーンに入門するためにcadence言語を学ぶ[リソース編]](https://qiita.com/JY8752/items/e3027344e5607ee9e7f0)
[NFT特化flowブロックチェーンに入門するためにcadence言語を学ぶ[capability リンクの参照とスクリプト]](https://qiita.com/JY8752/items/3850784684da9b888c05)
[NFT特化flowブロックチェーンに入門するためにcadence言語を学ぶ[Non Fungible Tokens(NFT)編1]](https://qiita.com/JY8752/items/a53322bcbdeabe4cc820)
[NFT特化flowブロックチェーンに入門するためにcadence言語を学ぶ[Non Fungible Tokens(NFT)編2]](https://qiita.com/JY8752/items/0e2195c296c0f026bcf8)
[NFT特化flowブロックチェーンに入門するためにcadence言語を学ぶ[Fungible Tokens(FT)編]](https://qiita.com/JY8752/items/9760c6238b21e19151a0)

# flowとは
https://flow.com/

flowとはethereumなどと同じL1のブロックチェーンであり、flowを開発しているのは、NBA Top ShotやCryptoKittiesといった大きなムーブメントを起こしたNFTプロジェクトを生み出したDapper Labsという組織です。Dapper Labsはデジタルデータが一般人にとって当たり前となる世界を信じており、今のweb3界隈のクリプトユーザーではなくブロックチェーンやweb3を知らない層をターゲットとしているよう。NBA Top Shotがクレジット購入ができたりしたのもそういった非クリプト層を取り込もうという狙いがあったからなのかもしれない。

また、NBA Top Shotと並んでよく耳にするCryptoKitiesはめちゃくちゃ売れた結果、Ethereumの取引速度に影響を与えたらしい。公式のFAQには以下のようにある

> Is it true Cryptokitties broke the the Ethereum blockchain?
> CryptoKitties rendered Etheruem unusable in December 2017. Read more [here](https://www.bbc.com/news/technology-42237162).

このCryptoKittiesがNFTという言葉の発祥らしい。CryptoPunksの方が早いらしいけどCryptoPunksはERC721で実装されていないためERC721で実装された元祖NFTはこのCryptoKittiesらしい。

これらの有名NFTプロジェクトを成功させてきたDapper Labsが開発したチェーンがflowであり、このflow上にデプロイするスマートコントラクトはCadenceというこれまた独自開発された言語を使用して実装する。

# なぜやるのか
筆者のweb3歴としては現職の業務でブロックチェーンゲームの開発を担当することとなり、直接のコントラクトの実装などはないにしろブロックチェーンやweb3についてのキャッチアップが必要となり、今年の4月あたりからsolidityでスマートコントラクトを書いてみたりなどのキャッチアップを始めたのでだいたい半年ちょっとくらいです。

とりあえず、何もわからない状態から始めたのでOpenSea, alchemyあたりのチュートリアルを一通りやったのと一冊ブロックチェーン入門書を購入してgethを使ってプライベートチェーン構築してみたりとかやったりしていました。

https://zenn.dev/jy8752/articles/a33b6a58ee638b

で、ざっくりweb3まわりの基礎知識と基礎技術を学んだので何かdappsをメインネットにデプロイしてみようとしたときに全然アイデアが出てこなくて、web2の時もそうなのですがキャッチアップした技術をアウトプットしていくために何か作ろうと思った時にアイデアが何も出てこないんですよね。特にweb3になるとトークンを発行するのであれば、トークンを発行する意味とか、トークンを発行して何をしようとか、これはわざわざコントラクトでやる必要があるのかとか、いろいろ考えてしまってブロックチェーン上にどういうアプリケーションをデプロイすればいいのだろうみたいなことを考えてしまって。

なので巷で話題のweb3について基礎的な部分はキャッチアップできたから一旦web3関係はいいかなと思ってたんですが、参加したweb3関係のイベントで知ったflowの思想がとても共感できていいなと思っていたので最後にflowを触ってみようかなというのがモチベーションです。

# Hello Worldしてみる
公式チュートリアルを参考にHelloWorldしてみます。flowは[playground](https://play.flow.com/local-project)が用意されているのでこのplaygroundを使用していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551753/24a8cdaf-d84e-86cc-b3a9-ca7d3ac55328.png)

playgroundを開くと上記のようにアカウントが5つ用意されておりそれぞれHelloWorldコントラクトが実装されている。とりあえず、これを実行するにはTransaction Templatesに以下のような実行コードが用意されているのでこれを実行すればいいのだがエラーが出ている場合はコントラクトをデプロイする必要がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551753/53424d55-b887-e93d-8d42-5e602e12f202.png)

コントラクトをデプロイするには```0x01```のアカウントを開きDeployボタンをタップしデプロイする。デプロイが完了し実行可能な状態となると以下のようになるはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551753/5e41f397-a24b-27b5-050d-916cf9e98145.png)

Sendボタンをクリックするとコントラクトのhello関数が実行され以下のように画面下部の出力にHello Worldが出力される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551753/5d2288e0-3c91-207f-151d-c83aed946196.png)

# コントラクトのコードを見てみる
CadenceはKotlinやSwift, Rustなどから影響を受けて開発された言語のようなのでどれかしらの言語を触ったことがある方は馴染みやすい言語かもしれない。HelloWorldコントラクトのコードは以下のようなコードとなっています。
```typescript:HelloWorld.cdc
access(all) contract HelloWorld {

    // Declare a public field of type String.
    //
    // All fields must be initialized in the init() function.
    access(all) 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!
    access(all) fun hello(): String {
        return self.greeting
    }
}
```
flowではアカウントに対してコントラクトの実装をするようですがsolidityなどと同様```contract <コントラクト名> {}```のような形式でコントラクトを宣言しています。先頭にある```access(all）```はアクセス修飾子でpublicな宣言となっています。これは```pub contract HelloWorld ```としても同様。

```access(all) let greeting: String```この行ではString型のgreetingフィールドをpublicに宣言しています。Cadenceでは```let```での変数宣言は定数宣言で値を変更できない。値を後から変更したい場合は```var```で宣言する。

```init()```では初期化時の処理となっており、ここでgreetingフィールドに値を設定している。

そして、```hello()```ではhello関数の宣言をしており、自身のフィールドに設定された文字列の値を返すように定義されている。

# トランザクション作成のコードを見てみる
トランザクションを作成するコードは以下のようになっている。
```typescript
import HelloWorld from 0x01

transaction {

  prepare(acct: AuthAccount) {}

  execute {
    log(HelloWorld.hello())
  }
}
```

まず最初に```0x01```アドレスからコントラクトをインポートします。インポートの形式は以下のような形式でインポートする。
```typescript
// Replace {ContractName} with the name of the contract you want to import
// and {Address} with the account you want to import it from
import {ContractName} from {Address}
```

トランザクションは```prepare```と```execute```の2つに大きく分けられる。```prepare```は必須ですが今回は```execute```の方を見ていきます。ここではインポートしたHelloWorldコントラクトのhello関数を呼び出し、log関数を使用して戻り値を出力しています。

このトランザクションをplaygroundで実行するのに署名者としてアカウントを選択しましたが、flowではトランザクションが実行されるのに特定のアカウントの認可が必要となる。認可されたトランザクションは承認者のprivateなフィールドやコントラクトの関数を呼び出したりすることができる。

HelloWorldコントラクトの関数を実行するのには```0x01```アカウントでこのトランザクションに署名することでトランザクションがHelloWorldコントラクトのhello関数を呼び出すことが可能となっている。

# まとめ
今回は以下のことについて紹介いたしました。
- flowチェーンとそのコントラクト開発言語である　Cadenceについて
- コントラクトの最低限の実装について
- flowにおけるトランザクションの実行と作成について

まだ、触りだけですがflowは非常にドキュメントや開発のためのエコシステムが充実していて開発者フレンドリーというのは聞いていましたが、本当にその通りでHelloWorldしただけですが非常に楽しいです。次の記事ではCadenceについてもう少し掘り下げて学んでみたいと思います。今回は以上です！