BlockstackでDApp入門 Part 2 ~Animal Kingdom編~

Yuya Sugano
22 min readApr 13, 2019

--

HushHubさんで行われたBlockstackのワークショップまとめのPart 2です。Part 1ではBlockstackの概要とアカウント設定およびサンプルアプリの実行を行いました。 Part 2ではチュートリアルに出てくるAnimal KingdomとApp.coへのアプリ追加を行います。We appreciate for Louis Ivan from Amsterdam his enthusiasm and his visit at HashHub for the workshop.

Customized Animal Kingdom

以下の太字のものをPart 2では記載しています。

  • Blockstackとは(再掲)
  • Blockstack DApp
  • Blockstack ID、Netlifyアカウント作成
  • 環境構築
  • Animal Kingdomのカスタマイズ
  • アプリケーションデプロイ(Netlify)
  • App.coへのアプリ追加とApp Mining

Blockstackとは

ブロックチェーンの仕組みを利用して非中央集権型のアプリケーションを作成できるプラットフォームです。Blockstackではブロックチェーン技術を認証とデータ保存に使用しています。ユーザの暗号鍵、データは全てユーザの所有とされ、Blockchain Name Service および Blockchain & P2P Network と各種API(下図のIdentity API、Storage API、Tokens API)がBlockstackアプリと連携することで動作するようになっています。[2]

https://aishinbun.com/clm/20180507/1402/

インターネットの上にTCP/IPの層があり、その上にBlockstackのブロックチェーンとBlockstackのソフトウェア層、その上に作成したDAppが展開されるアーキテクチャになっています。ユーザのIDやデータが管理主体から切り離されているため従来の中央集権型サービスのような情報漏洩や企業によるデータの独占といった懸念が緩和されます。

Animal Kingdomのカスタマイズ

カスタマイズの前にAnimal Kingdomのアプリケーション動作とコードを確認しました。 https://animalkingdoms.netlify.com/へアクセスして、Part 1で取得したBlockstack IDでサインインします。[3]

Web App版のBlockstackブラウザでIDを作成しておく必要があります。

Click on one of your Blockstack ID

サインインするとAnimal Kingdomのラインディングページへと遷移します。

Animal Kingdom Landing page

Animal Kingdomの目的は自身の動物王国を作ることです(なんと、そのままですねw)。好きな動物と土地をそれぞれ選択し、最下部の『Done』をクリックすることでGaiaへデータを保持することができるようになります。

Animal Kingdom Fancy landing page

動物王国の主として森で犬を支配できました。

Ruling of wilderness, like WTF

またBlockstack Explorerから保存されたデータを閲覧することが可能となっています。[4]

(検索窓に自身のBlockstack IDを入力して検索、ユーザプロファイルの『View Raw Profile Data』をクリックして、jsonデータの”apps”の要素)

Click on View Raw Profile Data

githubからコードをcloneしてください。コード内容を確認してからカスタマイズしていきます。[5]

$ git clone https://github.com/blockstack/animal-kingdom.git
$ cd animal-kingdom
$ ls -al
total 536
drwxrwxr-x 8 User User 4096 Apr 10 20:25 .
drwxrwxr-x 4 User User 4096 Apr 10 20:25 ..
drwxrwxr-x 3 User User 4096 Apr 10 20:25 config
drwxrwxr-x 2 User User 4096 Apr 10 20:25 cors
drwxrwxr-x 8 User User 4096 Apr 10 20:25 .git
-rw-rw-r-- 1 User User 316 Apr 10 20:25 .gitignore
-rw-rw-r-- 1 User User 2639 Apr 10 20:25 package.json
-rw-rw-r-- 1 User User 501057 Apr 10 20:25 package-lock.json
drwxrwxr-x 4 User User 4096 Apr 10 20:25 public
-rw-rw-r-- 1 User User 2353 Apr 10 20:25 README.md
drwxrwxr-x 2 User User 4096 Apr 10 20:25 scripts
drwxrwxr-x 2 User User 4096 Apr 10 20:27 src

Animal KingdomではReactが使用されていますが、他のJavascriptのライブラリでコーディングすることもできます。Blockstackはライブラリフリーなので、VueやNext.jsでも問題ないと思います。JSX/ES6あたりの理解はもはや必須のようです(-_-;)。 blockstack.js ライブラリはアプリ側からBlockstack IDを認証し、Gaiaにあるユーザデータを読み書きするために必要で、Blockstack DAppには必ず必要なライブラリといえます。

ユーザ識別子(ID)の認証

src/App.js ファイルのnew UserSession() でユーザセッションを作成し、isUserSignedIn() にてユーザがサインイン状態かどうか判別しています。サインイン状態であれば src/SignedIn ページを、サインイン状態でなければsrc/Landing ページを表示します。

import React, { Component } from 'react'
import './App.css'
import { UserSession } from 'blockstack'

import Landing from './Landing'
import SignedIn from './SignedIn'

class App extends Component {

constructor() {
super()
this.userSession = new UserSession()
}

componentWillMount() {
const session = this.userSession
if(!session.isUserSignedIn() && session.isSignInPending()) {
session.handlePendingSignIn()
.then((userData) => {
if(!userData.username) {
throw new Error('This app requires a username.')
}
window.location = `/kingdom/${userData.username}`
})
}
}

render() {
return (
<main role="main">
{this.userSession.isUserSignedIn() ?
<SignedIn />
:
<Landing />
}
</main>
);
}
}

export default App

次にsrc/Landing.js を確認します。『Sign in to Blockstack』ボタンをクリックするとredirectToSignIn がコールされ、サインインの認証画面へとリダイレクトされます。BlockstackブラウザでBlockstack IDを作成していない場合は、以下左のようにPart 1でご紹介したBlockstack IDの新規作成の画面となります。

https://docs.blockstack.org/develop/images/kingdom_notin.png

Blockstack IDでサインインが成功するとBlockstack DAppは、ユーザプロファイルの読み込みと、Gaiaのデータの読み書きができるようになります。データはGaia Storage HUBに一意のURLで暗号化されて保存されます。

またUserSession はセッションデータをブラウザのローカルストレージへ保持するので、今までの中央集権型のアプリケーションの様にセッション状態を中央のサーバやクラウド上のRedisなどで管理しておく必要はありません。

Gaiaでデータ取得と保存

GaiaはBlockstackのデータストレージです( https://hub.blockstack.org)。[6]

src/SignedIn.js ファイルのloadMe() メソッドでユーザプロファイルの確認をしています。UserSession で使用するME_FILENAMEおよびappConfigはsrc/constants.js に設定があります。

import React, { Component } from 'react'
import { Switch, Route, Redirect } from 'react-router-dom'
import { UserSession } from 'blockstack'
import EditMe from './EditMe'
import Kingdom from './Kingdom'
import NavBar from './NavBar'
import OptionsList from './OptionsList'
import OtherKingdoms from './OtherKingdoms'
import { appConfig, ME_FILENAME } from './constants'
import './SignedIn.css'

loadMe() メソッド部分。

componentWillMount() {
this.loadMe()
}
loadMe() {
const options = { decrypt: false }
this.userSession.getFile(ME_FILENAME, options)
.then((content) => {
if(content) {
const me = JSON.parse(content)
this.setState({me, redirectToMe: false})
} else {
const me = null
this.setState({me, redirectToMe: true})
}
})
}

ユーザが動物と土地を選択して、『Done』をクリックするとsaveMe(me) メソッドが呼ばれユーザのデータが保存されます。Gaia Storage HUBをデータストアとして使用している場合には、繰り返しになりますが、Blockstack ExplorerからデータのURLを閲覧することが可能です。

Animal Kingdomコード変更

いよいよコード修正です。Animal KingdomのコンポーネントであるTerritoriesOther Kingdoms へ要素を追加します。まずはwesteros.jpgをpublic/territories 内へ保存してください。

https://docs.blockstack.org/develop/images/westeros.jpg

$ cd public/territories
$ wget https://docs.blockstack.org/develop/images/westeros.jpg
--2019-04-10 21:50:28-- https://docs.blockstack.org/develop/images/westeros.jpg
Resolving docs.blockstack.org (docs.blockstack.org)... 178.128.123.58, 2400:6180:0:d1::575:a001
Connecting to docs.blockstack.org (docs.blockstack.org)|178.128.123.58|:443... connected.
HTTP request sent, awaiting response... 200 OK
westeros.jpg 100%[==============================================>] 14.40K --.-KB/s in 0.08s2019-04-10 21:50:29 (174 KB/s) - saved [14747/14747]$ cd ../../
$ ls public/territories/
forest.jpg tundra.jpg westeros.jpg

src/constants.js 内でTerritoriesOther Kingdoms の要素を追記します。

export const TERRITORIES = [
{
id: 'forest',
name: 'Forest',
superpower: 'Trees!'
},
{
id: 'tundra',
name: 'Tundra',
superpower: 'Let it snow!'
},
{
id: 'westeros',
name: 'Westeros',
superpower: 'The Iron Throne!'
}
]

Other Kingdomsは、王国を作成したhttps://animalkingdoms.netlify.comを追加してください。自身のBlockstack IDをruler:へ指定します。

export const OTHER_KINGDOMS = [
{
app: 'https://animal-kingdom-1.firebaseapp.com',
ruler: 'larry.id'
},
{
app: 'http://localhost:3001',
ruler: 'larz.id'
},
{
app: 'https://decentralised-islands.netlify.com',
ruler: 'yannael_leborgne.id'
},
{
app: 'https://thirsty-jang-0c0a17.netlify.com',
ruler: 'ma1222042.id.blockstack'
},
{
app: 'https://animalkingdoms.netlify.com',
ruler: '<YOUR ID>.id.blockstack'
}
]

コード変更ができましたのでnpm startで実行します。環境がローカルで完結している場合は、アプリケーションの動作確認で行ったように動物王国を完成させることができるはずです。

$ npm start> animal-kingdom@1.0.0-alpha.2 start /home/ether/work/blockstack/animal-kingdom
> node scripts/start.js

ランディングページが出てきます。

Animal Kingdom Top page

リモートサーバで動かしている環境では、『Sign in with Blockstack』をクリックすると以下のような認証エラーの画面が出てきました。

オリジン間リソース共有(cross-origin requests, CORs)のエラーで、今回アクセスしているBlockstack DAppからBlockstackブラウザへ認証する際に、クロスオリジンの事象が発生しているためです。

CORs occurred

オリジン間リソース共有を解消するため、コードをビルドしてserveでアプリケーションを起動します。

$ npm run build> animal-kingdom@1.0.0-alpha.2 build /home/ether/work/blockstack/animal-kingdom
> node scripts/build.js
Creating an optimized production build...
...
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/
Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.
File sizes after gzip:416.36 KB build/static/js/main.8ffff9b4.js
863 B build/static/css/main.30d9d418.css
The project was built assuming it is hosted at the server root.
You can control this with the homepage field in your package.json.
For example, add this to build it for GitHub Pages:
"homepage" : "http://myname.github.io/myapp",The build folder is ready to be deployed.
You may serve it with a static server:
serve -s buildFind out more about deployment here:http://bit.ly/CRA-deploy

事前にビルドしてできたフォルダ内に、cors/_headersおよびcors/_redirectsをコピーしてからserve -s buildでアプリケーションを起動してみてください。※ビルドの操作は次にNetlify上へアプリケーションを構築する際にも必要となります。

アプリケーションデプロイ(Netlify)

Part 1においてNetlifyというサービスへアカウント登録を行いました。NetlifyはHerokuのようなホスティングサービスで、Githubと連携しCI(Continuous Integration)も構築できます。[7]

まずはAnimal Kingdomのコードをビルドしてオリジン間リソース共有(cross-origin request, CORs)対策のためにbuildフォルダへ必要なファイルをコピーしておきます。

$ npm run build
...
$ cp cors/_headers build
$ cp cors/_redirects build

Netlifyへのアプリケーションデプロイは、ビルドしてできたbuildフォルダをドラッグ&ドロップするだけでできます。以下の赤枠の中にbuildフォルダを入れてください。自動でデプロイされ、URLが発行されます。

Easy deploy and integration

https://kind-stonebraker-397032.netlify.comというURLでAnimal Kingdomがデプロイされました。クリックするとランディングページへ行くはずなので、Blockstack IDでサインインしてください。

地形に追加したWesterosが表示されていることを確認してください。以下は動物に猫、地形に『Westeros』を選択して『Done』をクリックした結果です。

動物王国の主としてWesterosで猫を支配できました。

Ruling of wilderness, WTF

ナビゲーションになる『Other Kingdoms』をクリックしてみましょう。https://animalkingdoms.netlify.com/で作成したURLが追加されていることを確認してください。

Find your other kingdoms

App.coへのアプリ追加とApp Mining

App.coはBlockstackによって提供されるDAppのマーケットプレースです。Blockstackによって運営されていますが、Blockstackアプリケーションだけでなく、CryptoKittiesなど他のブロックチェーンアプリも登録されています。[8]

App MiningはBlockstackアプリケーションを対象にしたファンドプログラムで基準を満たしたアプリケーションが登録され、毎月ランキングに応じて$100,000がFounderへビットコインで支払われます。上位チームで毎月$20,000相当のビットコインが報酬として支払われています。[9]

それでは先ほどビルドしてデプロイしたAnimal KingdomをApp.coへ登録してみます。App.coの『Add your app』をクリックして必要な事項を入力していきます。

Add your app on App.co

最後まで入力を終えたら『Submit App』をクリックして完了です。

Submit your App on App.co

審査がレビュワーによって完了した後に、入力したメールアドレス宛に返信がきます。

Your App has been added !!

以上、ワークショップの内容は完了です。Javascriptでフロントエンドとblockstack.js ライブラリさえ使えれば簡単なアプリは作成できるので、開発の敷居は非常に低いように感じました。

まとめ

  • Blockstackはブロックチェーンの仕組みを利用して非中央集権型のアプリケーションを作成できるプラットフォームである
  • Blockstack DAppでは blockstack.js ライブラリおよびフロントエンドに使用するJavascriptライブラリを選択してコーディングする
  • Blockstack DAppはライブラリフリーで、使用するJavascriptのライブラリは自由に選択できる
  • App.coにブロックチェーン基盤を問わずDAppを登録することができる
  • App Miningへ登録することでBlockstackアプリのランキングへ参加でき、$100,000が上位チームへ支払われる

--

--

Yuya Sugano
Yuya Sugano

Written by Yuya Sugano

Cloud Architect and Blockchain Enthusiast, techflare.blog, Vinyl DJ, Backpacker. ブロックチェーン・クラウド(AWS/Azure)関連の記事をパブリッシュ。バックパッカーとしてユーラシア大陸を陸路横断するなど旅が趣味。

No responses yet