実録!Uniqys KitでのDApps開発記 第2回 「CryptOsushi全体の構成」
前回はサンプルアプリケーション「CryptOsushi」の概要と、ローカル環境で実行する方法を紹介しました。
今回はCryptOsushi全体の構成について紹介します。
CryptOsushi 全体の構成
CryptOsushiは以下の3つの要素から成り立っています。
- uniqys-node
- app
- frontend
3つの接続関係を簡単に示したのが以下の図です。
これからuniqys-core、app、frontendそれぞれの起動方法と各要素の接続部分の実装について説明します。
uniqys-node
uniqys-nodeは、Chain CoreとEasy Frameworkを同時に動作させるアプリケーションです。
Chain CoreとEasy Frameworkについての詳細は、以前の記事をご確認ください。
uniqys-nodeは、 /server/uniqys-node の下に実装されています。
https://github.com/uniqys/Sample-CryptOsushi/tree/master/server/uniqys-node
Easy Frameworkには3つの特徴的なエンドポイントが存在し、uniqys-nodeの起動と同時に立ち上がります。
Gateway (8080ポート)
- HTTPリクエストを受け付ける
- トランザクションをブロックチェーンに取り込み、署名されたHTTPリクエストがappで実行される
- 署名がない場合、appへプロキシする
Inner Memcached Compatible (56011ポート)
- Memcached互換のインタフェースでブロックチェーン上のデータの操作を行える
Inner API (56010ポート)
- Web APIを提供し、アカウント情報を扱う
app
appはDAppのコアとなる機能を提供するWebサーバです。
appは、 /server/app の下に実装されています。
https://github.com/uniqys/Sample-CryptOsushi/tree/master/server/app
appは任意の言語で実装することが可能です。CryptOsushiではPython3.7で実装し、WebフレームワークにはBottleを使用しました。
以下のコマンドを実行することで起動できます。
$ cd server/app
$ pip install -r requirements.txt
$ python src/main.py
次にappからuniqys-nodeの各エンドポイントに接続する方法を見ていきます。
Gateway ⇄ app
appのポートとGatewayのポートは以下の部分で紐づけられています。
https://github.com/uniqys/Sample-CryptOsushi/blob/master/server/uniqys-node/src/main.ts#L30-L33
const UNIQYS_APP_URL = ‘http://localhost:56080'
const UNIQYS_GATEWAY_PORT = Number(process.env.UNIQYS_GATEWAY_PORT) || 8080const easy = new Easy(new URL(UNIQYS_APP_URL), stateStore, (dapp) =>
new Local(dapp, new Blockchain(new BlockStore(chainStore), genesis), keyPair)
)
easy.gateway().listen(UNIQYS_GATEWAY_PORT)
これにより、56080ポートに対してappを立ち上げることで、Gateway経由でappに接続することができるようになります。
Inner Memcached Compatible ⇄ app
CryptOsushiでは、Easy FrameworkのInner Memcached Compatibleとの通信は、以下のように実装されています。
https://github.com/uniqys/Sample-CryptOsushi/blob/master/server/app/src/dao.py
まず、pymemcacheのクライアントクラスをインポートします。
from pymemcache.client.base import Client
portには、Inner Memcached Compatibleが受け付けている56011ポートを指定します。
def __init__(self, host, port):
self.db = Client(
(host, port),
serializer=self.__json_serializer,
deserializer=self.__json_deserializer
)
あとは、通常のMemcachedサーバと同じ方法でアクセスできます。
def get_osushi(self, id):
osushi = self.db.get(f”osushi:{id}”)
return osushi
Inner API ⇄ app
Inner APIはWeb APIなので、HTTP通信を行うことができます。
実装されているInner APIは以下の通りです。
https://github.com/uniqys/UniqysKit-preview/blob/master/packages/easy-framework/src/api.ts
たとえば、所持しているgariを確認するためには以下のようなHTTPリクエストを行う実装をします。
def refer_gari(address):
api_url = f”{API_BASE}/accounts/{address}/balance”
res = requests.get(api_url)
return res.json()[0] if res else 0
appの具体的な説明は、第3回で行う予定です!
frontend
frontendはユーザがブラウザでアクセスして、CryptOsushiを遊ぶためのWebアプリです。
frontendは、/frontend 以下で実装されています。
https://github.com/uniqys/Sample-CryptOsushi/tree/master/frontend
frontendはSingle Page Applicationとして実装されています。フレームワークにはNuxt.jsを使用しました。以下のコマンドで実行できます。
$ cd frontend
$ yarn
$ yarn dev
@uniqys/easy-client を使用して、Easy FrameworkのGatewayが受け付けている8080ポートに接続します。
@uniqys/easy-client に含まれているEasyClientForBrowserは、axios のインタフェースを実装しているため、以下のように使用できます。
import { EasyClientForBrowser } from ‘@uniqys/easy-client’
const client = new EasyClientForBrowser(‘http://localhost:8080')client.get(‘/sushi/all’)
client.post(‘/sushi/generate’, {}, { sign: true })
リクエストに署名するためには、第三引数に {sign: true}
を与えます。CryptOsushiでは、おすしをにぎる、買う、売るなどの操作で署名をしています。
frontendの具体的な説明は、第4回で行う予定です!
おわりに
この記事では CryptOsushi 全体の構成を説明し、uniqys-node、app、frontendがどのように繋がっているかを紹介しました。
動かしてみてなにか気づいた点がありましたら、お気軽にissuesやgitterなどでご連絡ください。
次回は「CryptOsushiのバックエンド(app)」について説明します。ご期待ください!