実録!Uniqys KitでのDApps開発記 第2回 「CryptOsushi全体の構成」

Shouhei Yoshida
8 min readSep 12, 2018

--

前回はサンプルアプリケーション「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) || 8080
const 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がどのように繋がっているかを紹介しました。

動かしてみてなにか気づいた点がありましたら、お気軽にissuesgitterなどでご連絡ください。

次回は「CryptOsushiのバックエンド(app)」について説明します。ご期待ください!

Uniqysプロジェクトについてはこちらをご覧ください。

もしこの記事をお楽しみいただけたら、私たちのGitHubTwitterのフォローをお願いします。Uniqysの最新情報をお届けしています。 また、Uniqys KitのPreview版は既にGitHubで公開されているので、是非お試しください!

--

--