実録!Uniqys KitでのDApps開発記 第4回「CryptOsushiのフロントエンド」

Shouhei Yoshida
9 min readSep 14, 2018

--

前回の記事では、CryptOsushiのバックエンドの実装について紹介しました。今回は、CryptOsushiのフロントエンドの実装について詳細に紹介します。

CryptOsushiのページ

CryptOsushiには、3つのページがあります。

マイSushi

マイSushiページは、自分が持っているおすしの一覧を表示するページです。

画面右上のにぎるボタンを押すことで、新しいおすしが生成されマイSushiページのおすし一覧に追加されます。

売るボタンを押すことで自分のおすしを売り出すことができます。また、おすしの売り出しをキャンセルすることも可能です。

Sushiマーケット

Sushiマーケットでは、販売中のおすしを閲覧することができます。

販売されているおすしは所定のgariを支払うことで購入できます。

全てのSushi

すべてのSushiページでは、流通しているすべてのおすしを見ることができます。

もし販売中なら、このページでも購入することが可能です。

Easy Framework との接続

これまでの紹介した機能が、どのようにできているか説明します。

CryptOsushiは、フロントエンドからEasy FrameworkのGatewayを経由してappにREST APIを呼び出すことで、にぎる・売る・買うなどの機能を提供しています。

Easy FrameworkのGatewayと接続するのにもっとも簡単な方法は、Uniqys Kitに含まれるeasy-clientを使うことです。

easy-clientを使用するために、Nuxt.jsのプラグインとして、plugins/easyclient.jsを実装しました。

easy-clientのEasyClientForBrowserをインスタンス化し、アプリケーションのルートに挿入してアプリケーション内から使用できるようにします。

import { EasyClientForBrowser } from '@uniqys/easy-client'const client = new EasyClientForBrowser(process.env.DAPP_ENDPOINT)export default (_, inject) => {  inject('client', client)}

nuxt.config.jsで、以下のようにプラグインを取り込みます。ブラウザでのみの実行するので、 ssr: false とします。

plugins: [  { src: '~plugins/webfontloader', ssr: false },  { src: '~plugins/easyclient', ssr: false },],

これで、アプリケーション内で以下のように使用できるようになりました。

this.$client.post('/sushi/generate', {}, { sign: true })

app側の実装は、こちらを参照ください。

storeの実装

CryptOsushiのアプリケーションの状態を管理するために、Vuex ストアを利用しています。

sushi

おすしの状態は、state/sushi.jsで実装されています。詳しい実装は、ソースコードをご確認ください。

  • fetch
    appから画面上に表示されるおすしの一覧を取得し、状態を更新します。
  • generate
    新しいおすしをにぎり、おすしの一覧に追加します。
  • sell
    選択されたおすしを入力したgariで売り出します。
  • buy
    販売中のおすしをgariを支払い購入します。

gari

gariの状態は、state/gari.jsで実装されています。詳しい実装は、ソースコードをご確認ください。

fetchというアクションは、所持しているgariの残高を更新します。

async fetch(context) {
const address = context.rootGetters.getMyAddress()
const { data } = await this.$client.get(`/gari/refer/${address}`)
const { balance } = data;
context.commit('setBalance', { newBalance: balance })
},

本来、以下の実装で残高を取得することが可能です。

const { balance } = await this.$client.api.account(this.$client.address.toString())

しかしCryptOsushiでは、初回起動時に10,000 gariを付与するという仕様です。Easy FrameworkのREST APIでは残高の初期値は 0 gari です。そのため、ユーザーが最初から 10,000 gariを所有しているように振る舞うREST APIを用意して、フロントエンドから呼び出しています。これは gari.pyrefar_gari 関数で実装されています。

また、 get()メソッドでは送信者のアドレスがappに渡らないため、アドレスをURLに付けて通信しています。

sushiの画像を生成する

おすしの画像はお皿、ネタ、薬味の3つから構成されています。これらの画像はそれぞれ10枚ずつ用意しています。この3つの画像をおすしのDNAを元に選択し重ねています。

なお、シャリは1種類しかありません・・・。

にぎったおすしの例

おすしの画像は、VSushiListItemImage.vueで実装されています。

おすしは256bitのDNAを保持しています。たとえば16進数表示するとこのようなものです。

db37925934a3d3177db64e11f5e0156ceb8a756fee58ded16e549afa607ddb1d

このDNAから4桁ずつ取り出し、パターン数で剰余演算することで、皿、ネタ、薬味の表示する画像を選択しています。

code() {  return {    dish: this.dnaCache.readUInt16BE(0) % this.pattern,    neta: this.dnaCache.readUInt16BE(4) % this.pattern,    spice: this.dnaCache.readUInt16BE(8) % this.pattern,  }}

無限スクロールの実装

CryptOsushiの各寿司一覧ではUI/UXを考慮して無限スクロールを実装しています。これはすべてのおすしを1度のリクエストで取得するとデータが大量になる可能性があるためです。

「全てのSushi」のおすしは追加されるだけですが、「マイSushi」と「Sushiマーケット」のおすしは削除される可能性があります。この削除される可能性を考慮すると、おすしの情報を愚直にKey Value Store (KVS) 上に保存する場合に、断片化が生じてパフォーマンスが悪化してしまいます。

そのためCryptOsushiのバックエンドではKVS上に連結リストを実装しています。これに合わせてフロントエンドで無限スクロールを実装すると、ユーザーにデータの一部を効率よく見せることができます。

完成!

これで、おすしをにぎり、そのおすしを売買できるようになりました!

これがCryptOsushiだ!

実際におすしをにぎってみると、一瞬でトランザクションが完了します。
ほぼリアルタイムに動作しているため、ブロックチェーン上で動いているアプリケーションであることを意識させません。
トランザクションを発行するための手数料もかからないので、カジュアルにおすしをにぎることができます。

Uniqys Kitの仕組みを学習すれば、Uniqys Kitを利用したアプリケーションは使い慣れた言語で書くことができ、とても気軽に実装できることがわかりました。

おわりに

4日間の連載、いかがでしたでしょうか。
DAppsを開発する上で、Uniqys Kitをどのように使えばいいのかを詳細にお伝えしてきました。

Uniqys Kitは以下の特徴を通して、ユーザーにとっても、開発者にとってもDAppsをより身近に感じてもらうことを目指しています。

  • トランザクションの待ち時間が短い
  • 手数料が安い
  • これまでのWebアプリケーションと同じように実装できる

この連載を通して、Uniqys Kitのことを知っていただき、少しでもこれを使ってDAppsを開発してみようと思っていただけたら幸いです。

進化には多様性が必要である。その多様性を作り出すのはあなた自身だ。

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

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

--

--