2021.10.08

巨大NFT市場をつくった Flow Blockcnain におけるアプリ開発の基礎概念

お疲れさまです。F.S.です。
この度、GMOインターネットグループでは新規にNFT市場に参戦し、Adam byGMOというNFTマーケットプレイスを立ち上げました。

Adam byGMOはEthereum Blockchainに対応していますが、NFTつながりということで、業界では著名なNBA Top ShotのプラットフォームであるFlow Blockchainでのアプリケーション開発について知見を得ていきたいと思います。NBA Top Shotはサービス開始から1年も経たずに750億円を売り上げたという巨大なNFTマーケットです。

Flowアプリケーション開発者向けの公式ドキュメントを追いかけていきます。
Welcome to the Flow Developer Docs – Flow Documentation

1. Flow Blockchainの概要

Flowは2017年暮れにEthereumで流行したCryptoKittiesの開発チームによりゼロから設計、開発されたBlockchainです。
Blockchain上のアセットを扱うアプリケーションを、開発者に優しく、安全に開発できるように考案されています。

Flowの概要はFISCOさんのサイトにまとめられているので参考ください。

2. Flowのアプリ開発面における特徴

2-1. アカウント

FlowのアカウントはBitcoin, Ethereumのように公開鍵から派生したアドレスで決定されるのではなく、Flow Blockchainのオンチェーン関数で発行されます。

以下の特徴があります

  • アカウントと鍵ペア(公開鍵)を分離できる
    アカウントに複数公開鍵、複数アカウントに同一公開鍵を紐づけることができます
  • アカウントを作るのにもトランザクションが必要
    最初のアカウントは自分で作れず、ウォレット業者やサービスプロバイダーに作ってもらうことを期待しているようです

アカウントの作成は、テストネットではFaucetウォレットディスカバリーを組み込んだテストアプリケーションからできます。

メインネットであればBloctoウォレットで作成するか、NBA Top Shotでアカウント登録することでアカウント作成できます。

なお、FlowにはEthereumのEOA、Contractアドレスという区別はありません。
スマートコントラクトは存在するアカウントにデプロイされ、そのアカウントのストレージを使用します。ストレージ容量はアカウントの保有FLOW数に応じて割り当てられます。

2-2. ウォレット

BloctoLedgerなどが使えるようです。
Flowのライブラリで提供されるウォレットディスカバリーでは、Blocto、Ledgerが選択できるようです。testnet用のウォレットディスカバリーでは現時点でDapperウォレットがComing Soonとなっています。NBA Top Shotで使われているアカウントサービスがDapperウォレットに相当するのもと考えれられます。

テストネット用のウォレットディスカバリー

BloctoやNBA Top Shotのウォレットはメールアドレスを登録する形式であり、Webアプリケーションに近い使い勝手となっています。アカウントに紐づく鍵はウォレット業者で管理されているカストディウォレット式のようです。

Bloctoを用いたサインインおよび登録の例

2-3. トランザクション

Ethereumでは基本的にトランザクションの送信者がトランザクションに署名してGasを支払うことでブロックに取り込まれることになります。Flowも同様にトランザクションの署名とGasの支払いは必要になるのですが、トランザクション送信に必要なロールが次の3つにに分かれているのが特徴的です。

  • Proposer
    トランザクションを発行するアカウントです。チェーンの状態変更の提案者という意味でしょうか。
  • Payer
    トランザクション手数料を払うアカウントです。
  • Authorizers
    トランザクションを承認するアカウントです。複数アカウントを指定することができます。

トランザクション署名は、Proposer, Authorizersがペイロードに署名し、Payerがエンベロープ(Payload&Payload署名)に署名するという形式です。

トランザクション署名のイメージ

大抵はProposer = Authorizerで、Payerがプラットフォームやウォレット業者だったりするようです。Ethereumのメタトランザクションのようなイメージであり、トランザクション手数料をアプリケーション業者が代払いすることを見込んだ設計になっているように思えます。(現在はβ版なので手数料無料のようではありますが)

etherscanに似たflowscanでトランザクションの例を見てみると、3つのロールを担ったアカウントが明示されていることが分かります。

NBA Top Shotのトランザクション例
https://flowscan.org/transaction/90b3fa4924f539a2ae47dbf8e72913c6d41f641dadecbebe75311508dc470978/script

2-4. スマートコントラクト

Ethereumと同様に、Flowでもブロックチェーン上のプログラムをスマートコントラクトと言います。スマートコントラクトはCadenceという独自のリソース指向言語で記述します。

リソース指向

Flowのスマートコントラクトではトークン数量のようなアセットとなるものをリソースとして定義します。リソースは中央のコントラクトで管理されるのではなく、個々のアカウントのストレージに保有分のリソースが保持されることになります。この概念はEthereumとは大きく異なる異なる点です。

また、リソースはその時に唯一の場所に存在し、コピーや消失が起こるようなプログラムが書けないように保護されています。

例えば、一般的なトークンでは下記のような情報・機能をもつリソースが使われます。

  • 残高情報
  • 引き出し機能
  • 預け入れ機能
このトークンを送受信するアカウントでは、アカウントごとのストレージにこのリソースを設置することになります。

トークンリソースのソースコードはこのようなイメージです。

pub resource Vault: Provider, Receiver, Balance {

    // Balance of a user's Vault
    // we use unsigned integers for balances because they do not require the
    // concept of a negative number
    pub var balance: UFix64

    init(balance: UFix64) {
        self.balance = balance
    }

    pub fun withdraw(amount: UFix64): @Vault {
        self.balance = self.balance - amount
        return <-create Vault(balance: amount)
    }

    pub fun deposit(from: @Vault) {
        self.balance = self.balance + from.balance
        destroy from
    }
}

デプロイ

前述の通り、スマートコントラクトは既存のアカウントにデプロイすることになります。
スクリプトからコントラクトの機能を利用するには、コントラクトをデプロイしたアカウントアドレスを指定して参照します。

トランザクションスクリプトでアカウント0x01にデプロイされているHelloWorldコントラクトを利用する例です。

import HelloWorld from 0x01

transaction {
    prepare(acct: AuthAccount) {}
    execute {
        log(HelloWorld.hello())
    }
}

デプロイはFlowのCLIを使って行います。
Deploy a Flow Project – Flow Documentation

また、デプロイしたコントラクトは更新して再デプロイすることができます。

機能へのアクセス制御

Flowアカウントにはそれぞれにファイルシステムが割り当てられます。ファイルシステム内には3つのドメインがあります。

  • strage
    アカウントに紐づくすべてのオブジェクトが格納されるドメインで、本人のみがアクセスできます。
  • private
    本人および許可されたアカウントからのみアクセスさせる非公開APIのためのドメインで。トークンの引き出し機能などが該当します。
  • public
    公開APIを設置するドメインです。トークンの預け入れ機能などが該当します。

private, publicはstorageに存在するオブジェクトのメソッドにリンクするインターフェースリソースを設置するような形になります。次の図の例ではstorage内のFoo.BarにアクセスするためのFoo.PublicBarリソースをprivateやpublicに設置するというイメージです。

各ドメインのイメージ

例えば、前述のトークンVaultリソースにリンクするインターフェースリソースとして、下記のリソースをコントラクトに定義しておきます。

    pub resource interface Receiver {
        pub fun deposit(from: @Vault)
    }
    pub resource interface Balance {
        pub var balance: UFix64
    }

FT(ファンジブルトークン)の例

FT(ファンジブルトークン)はトークン種類ごとに数量を持つ、通貨のように扱われるトークンです。Flow Blockchainにおける基軸通貨FLOWもFTとして実装されているようです。

トークンコントラクトは下記のようなイメージで保持されます。

  • FungibleTokenコントラクトはアカウント0x01にデプロイされている
  • アカウント0x01、0x02のstorageにはFungibleTokenのVaultリソースがMainValutとして設置されており、それぞれ残高30を保持している
  • アカウント0x01、0x02のpublicにはVaultリソースの公開APIであるReceiver, BalanceへアクセスできるリソースがMainReceiverとして設置されている

publicにFungigleToken.Receiverリソースを持っていないアカウントへはこのトークンを送信することができません。トランザクションを使って、トークン送信前にアカウントにVaultおよびReceiverリソースの設置が必要になります。一見面倒にも思えますが、この仕組みにより誤ってトークンが扱えないアカウントに送信してしまい資産がロックされるという事故がなくなります。

3. 最後に

Flow BlockchainはEthereumでのDapps開発経験を活かして、アカウントの特性からトランザクション署名方式、コントラクト開発に至るまでアプリケーションが安全に開発しやすくなる思想が見られました。スマートコントラクト、トランザクションスクリプトに独自言語を開発してしまっているのは少し気になりますが、理解に難しくはないので、プラットフォームの成長が期待できれば取り組んでみるのもありかと思います。ステーブルコインUSDCもFlowへの展開を予定しているという記事もありました。

余談

NBA Top Shotのスマートコントラクトに興味があれば、下記から参照することができます。


次世代システム研究室では、ブロックチェーンのように尖った技術を活用したアプリケーションの設計・開発を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。

Pocket

関連記事