FiNANCiE Lab

ブロックチェーンで世界を変える、株式会社フィナンシェのテックチームブログです

個人情報秘匿のためトランザクションの暗号化ハッシュを認証鍵にした話

背景

全ての取引を公開管理台帳(Blockchain)に公開したかった。しかし、個人情報保護のため、個人を特定できるような情報を秘匿する必要があった。

要件の整理

方法案

以下の3案を候補にあげたが、最終的に3番を採用した。

1. 公開鍵暗号方式

最初に思いつく方法は、公開鍵暗号方式秘密鍵トランザクションを暗号化して、公開鍵をユーザ認証に使う。残念ながらこの手法は、使えない。なぜなら公開鍵から個人を特定できてしまうからだ。前述のように、全トランザクションを公開しているので、公開鍵に紐づく全てのトランザクションを抽出できる。そこから個人を推測することができてしまう。

2. 階層的決定性ウォレット

次に思いつくのは、階層的決定性ウォレットの仕組みを使う方法。ユーザ認証鍵をトランザクション毎に分けることで、個人を推測できない。個別のユーザ認証鍵を紛失したとしても、Seedさえ分かれば、全てのユーザ認証鍵を階層決定的に復元できる点が魅力的。 問題は、ユーザ認証鍵の管理コスト。トランザクション量に比例してかかる。削減したい。

3. トランザクションの暗号化ハッシュを認証鍵にする

トランザクションをユーザ鍵で暗号化し、その結果を認証鍵として使う。認証鍵でトランザクションを再暗号化して署名を作成する。 認証鍵を作れるのは、ユーザ鍵の所持者だけ。認証鍵を開示することで、トランザクションの所有権を示すことができる。トランザクションに対応する認証鍵は毎回違うので、所有者を推測できない。ユーザ鍵だけ管理すればよいので低コスト。

※ただし「なりすまし」は検知できない

技術詳細

まずは概要図。 f:id:re795h:20191112095347p:plain

Step1: ユーザ鍵生成

ユーザ鍵は、共通鍵生成アルゴリズムのAESを使って作成する。AESにした深い理由があるわけではない。他のアルゴリズムでも構わない。BitcoinやEthereumの秘密鍵でも構わない。

参考のためRubyでコードを示す。

require 'openssl'

OpenSSL::Cipher::AES256.new(:CBC).random_key
=> "d\xDC\xE9\e\r\x127@\xAA\x8A\xB4\x02\xAD\xA9\x95\xF9\xCA\x18@cW\xD6G\b\xF4\xB3J\xE33B2\x9A"

Step2: 認証鍵生成

トランザクションのうち、個人情報に当たらない部分は公開する。この部分をPayloadと呼称する。Payloadをユーザ鍵でHMACしたものをユーザ認証鍵とする。 HMACのハッシュ関数SHA256を使ってるのは、広く使われてるから。本心ではKeccak256を使いたかった。残念ながらRubyopensslライブラリで未対応だった。

user_key = "d\xDC\xE9\e\r\x127@\xAA\x8A\xB4\x02\xAD\xA9\x95\xF9\xCA\x18@cW\xD6G\b\xF4\xB3J\xE33B2\x9A"
payload = "{ type: xxx, amount: yyy }"

authentication_key = OpenSSL::HMAC.digest('SHA256', user_key, payload)
=> "\xB0\xDA{\xFC\xD3p\x8CR_\xA9\xB2\x1E\xB8/\x1E&\xF6\xAAZ\xE4\x89\x0E\x01G\xA7\xAEm]\x18\xB6\x9C\x8C"

Step3: 署名作成

認証鍵でPayloadをHMACしたものを署名として使う。

authentication_key = "\xB0\xDA{\xFC\xD3p\x8CR_\xA9\xB2\x1E\xB8/\x1E&\xF6\xAAZ\xE4\x89\x0E\x01G\xA7\xAEm]\x18\xB6\x9C\x8C"
payload = "{ type: xxx, amount: yyy }"

signature = OpenSSL::HMAC.hexdigest('SHA256', authentication_key, payload)
=> '2e49b12c72ab5c23c515faa0ceee8f9d1910af4c20540bcb544cd49027a8e5f6'

個人情報にあたるuserを署名に置き換えて公開する。

original_tx = { user: 000, type: xxx, amount: yyy }

public_tx = { 
  signature: "2e49b12c72ab5c23c515faa0ceee8f9d1910af4c20540bcb544cd49027a8e5f6"
  payload: "{ type: xxx, amount: yyy }"
}

Step4: 認証鍵送付

ユーザは証明したいトランザクションのIDと認証鍵を検証者に送る。

Step5: 認証

検証者はトランザクションIDを元に公開トランザクションから該当するトランザクションを取得する。Payloadを認証鍵でハッシュ化し、署名と等しいことを確認する。

public_tx = { 
  signature: "2e49b12c72ab5c23c515faa0ceee8f9d1910af4c20540bcb544cd49027a8e5f6"
  payload: "{ type: xxx, amount: yyy }"
}

authentication_key = "\xB0\xDA{\xFC\xD3p\x8CR_\xA9\xB2\x1E\xB8/\x1E&\xF6\xAAZ\xE4\x89\x0E\x01G\xA7\xAEm]\x18\xB6\x9C\x8C"

authentication_hash = OpenSSL::HMAC.hexdigest('SHA256', authentication_key, payload)
=> '2e49b12c72ab5c23c515faa0ceee8f9d1910af4c20540bcb544cd49027a8e5f6'

if authentication_hash == public_tx.signature {
  // User verified!
}

Ethereumを公開管理台帳として使う現実的な方法

結論

データ本体を分散DB(IPFS)に格納して、そのリファレンスをEthereumに格納する。

どこに なにを なぜ
IPFS 公開すべきデータ本体 低コスト。容量制限なし。可読性が高い。
Ethereum IPFSハッシュ値 データ本体が改竄されていないことを永続的に保証

Overview

Ethereumを公開管理台帳として使おうとしたとき、まず直面するのが、ガスコストが高すぎるという問題。EtherumのOpcodeの中でもストレージ格納の際に実行される"SSTORE"は最も高い

次に直面するのが容量の問題。Solidityの仕様では容量に上限はないらしい(どんな長い文字列でも格納できる)ものの、Ethereumの仕様ではGas Limitという上限がある。データを格納するとガスコストがかかり、1つのBlockに詰め込めるガス量には上限がある。

つまり、Ethereum単体では公開管理台帳として適さない。そこでIPFSと併用する。世の中の多くのプロジェクトがそうしている。Origin ProtocolOpenlawもそうしている。IPFSにデータ本体を格納して、IPFSハッシュをEthereumに格納する。

IPFSハッシュのEthereumへの格納の仕方としては"ログ出力"がよい。配列に格納する方法が一般的と思うが、先ほど言及したようにストレージ格納はガスコストが高い。ログ出力ならばその半分程度と安い。もし、削除や何かしらのオペレーションを想定せず、単に格納したいだけならば、ログ出力の方がよい。

実装例

参考のため、具体的な実装例を示す。

1. IPFSハッシュ

IPFSハッシュはByte32型で格納する。理由は、そのままString型で格納するとガスコストが若干高くなるから。Etherumではデータは32byteごとに分割格納される。そして32byte以下だとパックされる。Byte32型が最もお得である。

IPFSハッシュStringのByte32型への変換はBase58デコードで行う。理由は、IPFSハッシュはBase58エンコードされたものだから。

実装はOrigin Protocolのコードを参考にする。

function getBytes32FromIpfsHash(hash) {
  return `0x${bs58
    .decode(hash)
    .slice(2)
    .toString('hex')}`
}

2. Contranct

ログのガスコストはindexedされた変数の数に依存する。少ない方が安い。

eventSigイベント名に当たるもの。Ethereumのお作法に従い関数シグネチャと同様に、イベント名をKeccak256 hashして、その先頭4byteを指定する。

不要なログは記録すべきでないので、modifierにonlyWhitelistAdminを指定し、ホワイトリストに登録されたアドレスだけが実行できるようにする。

import 'openzeppelin-solidity/contracts/access/roles/WhitelistAdminRole.sol';

contract IpfsHashRecord is WhitelistAdminRole {

    event Recorded (
        bytes4 indexed eventSig,
        uint256 indexed createdAt,
        bytes32 ipfsHash
    );

    function writeHash(bytes4 _eventSig, bytes32 _ipfsHash)
        public
        onlyWhitelistAdmin
    {
      emit Recorded(_eventSig, uint256(now), _ipfsHash);
    }
}

注意点

IPFSノード運用が必要

IPFSは分散DBであるが、他人がデータを保持するインセンティブがないので、基本的には自分で保持して、外部に公開する必要がある。 IPFSの構築方法については、別記事が参考になる。

個人情報秘匿が必要

BlockchainとIPFSは外部に公開されるので、多くの場合は個人情報を秘匿する必要がある。秘匿手法は無数に考えられるるが、フィナンシェで採用した方法はこちら

用途

  • デジタル所有権の記録と証明

デジタル作品のハッシュ値と所有者の情報をBlockchainに記録する。 作品そのものをBlockchain上に格納するとガスコストが高くなるのでハッシュ値のみ。ハッシュ化アルゴリズムは何でもよいが、IPFSを使うのが楽。Blockchainは改竄が困難なので、所有権を立証できる。

  • プラットフォーム潔白性の検証と証明

例えば決済プラットフォームの運営主体が、取引に不正がないことを証明したいとする。Dappsのようにビジネスロジックをオンチェーンで実行すれば、それで済む話だが、多くの場合はそうではないはずだ。そこで、取引の結果のみBlockchainに格納する。一度格納すると後から改竄は困難。全ての取引結果から現在の状態を復元できれば、取引に不正がないことを証明できる。ちなみに、フィナンシェはこの用途で使っている。

例えばeventSigをこのように、トークンの名前と関数の結合と定義する。

eventSig => First 4 bytes of Keccak256(“token_name:transferFrom”)

そして、IPFSにその他の情報(送信者、受信者、額)を格納する。

{
 from: 0x825bBB7fdD9292ba18913c1E784D839DbEF82BbB,
 to: 0x49Cb60853D1a527995F6CB784e9641bb408dBb51,
 value: 10000000
}

Polkadot / Substrate触ってみた(前編:環境構築)

前置き

rudo@CTOです。

我らがFiNANCiEテックチームでは日々ブロックチェーンに関する研鑽を重ねているのですが、現状はリアルタイムにパブリックチェーンで全てのトランザクションを実行するのは難しいという結論です。

経緯はこちらの記事↓

lab.financie.jp

にまとまっていますが、個人的には敗北感に打ちひしがれています。ユーザーファーストのためとはいえ、ブロックチェーン原理主義ブロックチェーンに夢を託す者としては忸怩たる思いです。いつかリベンジしてやろうと次世代を担うブロックチェーンを模索しているのですが、今回はPolkadotというプロトコルを触ってみたのでご紹介します。

Polkadotってなんぞ?

独自チェーンを作って、他のチェーンと相互につなげて運用するための仕組みをもったプロトコルです。似たようなクロスチェーンを目的としたソリューションにCOSMOSがありますが、自前でコンセンサスノードを用意する必要があります。Polkadotはコンセンサスノードを共用する仕組みになっており、COSMOSとの大きな違いはそこにあります。将来FiNANCiEでリアルタイムオンチェーンに回帰する際、それをあてにできないかと目論んでいます。ただ、現状でPolkadotのメインネットに参加する(ParachainをRelaychainに参加させる)には色々とハードルが高く、今すぐに採用できるわけではなさそうです。

なお日本では @WatanabeSota さんがかねてよりPolkadotに取り組んでおり、詳しくは渡辺さんのQiitaを参照いただくのがよいと思われます。 qiita.com

Substrateってなんぞ?

昔流行った◯◯ツクールみたいなやつです。独自チェーンツクール。Polkadotに接続可能な独自チェーンを構築することができますが、Polkadotとは独立したフレームワークなのでPolkadotに接続することは必須ではありません。

早速導入...が、ダメ!

というわけでまずは開発環境を構築してみます。いつもこういう環境構築って一発ですんなり行った試しがないのですが、今回もご多分に漏れずしっかりばっちりハマりました。ちなみにmacOS Mojaveです。そのうち長いものに巻かれてCatalinaになると思います。

まず第一歩目でローカルにノードを立てようとして

curl https://getsubstrate.io -sSf | bash

を実行するも途中でこける。gccがないとかナントカ言われる。

brew install gcc

を実行してからリトライ。進む。が、こける。 なんやかんや調べてるうちに

brew doctor

で文句言われたところの修復を全部ためしてくれという案内を見る。 診断してみたら出るわ出るわの警告、それらを全て直す(brew cleanup)。直す(brew link)。直す(brew unlink & link)ッ!

そして再度

curl https://getsubstrate.io -sSf | bash

. . .

   Replacing /Users/rudo/.cargo/bin/subkey
    Replaced package `subkey v2.0.0 (/private/var/folders/2z/wpg0klfx1_vfqllndt_zvrv40000gn/T/tmp.W1z4gHE8/subkey)` with `subkey v2.0.0 (/private/var/folders/2z/wpg0klfx1_vfqllndt_zvrv40000gn/T/tmp.bLAcwjZZ/subkey)` (executable `subkey`)
~/Documents/substrate
Cloning into '/var/folders/2z/wpg0klfx1_vfqllndt_zvrv40000gn/T/tmp.24n4shma'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 200 (delta 3), reused 2 (delta 0), pack-reused 194
Receiving objects: 100% (200/200), 42.82 KiB | 270.00 KiB/s, done.
Resolving deltas: 100% (113/113), done.
Run source ~/.cargo/env now to update environment

通ったッ

おそるおそる

substrate

. . .

2019-11-11 13:40:34 Substrate Node
2019-11-11 13:40:34   version 2.0.0-9037ce12f-x86_64-macos
2019-11-11 13:40:34   by Parity Technologies, 2017-2019
2019-11-11 13:40:34 Chain specification: Flaming Fir
2019-11-11 13:40:34 Node name: stimulating-skate-4160
2019-11-11 13:40:34 Roles: FULL
2019-11-11 13:40:34 Initializing Genesis block/state (state: 0xd733…e696, header-hash: 0xb653…1d25)
2019-11-11 13:40:34 Loading GRANDPA authority set from genesis on what appears to be first startup.

起動できたッ

ということで後編に続きます。 ちなみにサラッと書いてますが、↑の工程は色々の開発タスクの合間を見て試していたので足掛け一週間ぐらいかかりました。

フィナンシェのBlockchainアーキテクチャ変遷と今後

※本記事はQiitaからの移行です


こんにちは、Takです。前回の勉強会はLibraについて解説、議論しました。 本番リリースを前にメンバーも増えたことなので、今回はフィナンシェのBlockchainアーキテクチャ変遷を紹介しました。

初期設計(Closed β)

  • オークション、マーケットプレイスのロジックは全てBlockchain(Ethereum)上に実装
  • 一般的なDapps同様、ユーザがMetamask等のウォレットを使ってBlockchainと交信

課題

  • Etherでの入出金、ERC20トークンの売買が可能なことから、一般向けにリリースするには仮想通貨交換業の免許が必要。取得のために何千万、何億円とかけて体制を構築する必要がある。取引所が本業ではないので、そのための投資が割に合わない
  • Metamaskのようなウェットの扱いに慣れていないユーザにとっては、大変使いづらくユーザビリティが悪い
  • Etherを所持していないユーザは取引所のアカウント作成から始めなければならず、使用開始のハードルが著しく高い

一般公開(Open β)

  • 円で入出金を行い、ERC20トークンをプラットフォーム外へ持ち出させない仕様に変更。これにより仮想通貨交換業の免許が不要となる
  • Blockchainとの交信をサーバーサイドで実施する仕様に変更。ガス代も運営が支払う。これによりMetamaskの使用や、取引所のアカウント作成が不要となる

詳しい仕組みについてはブロックチェーンで人をカード化して売買できるサービスを作ったので解説するを参照。

課題

  • 将来的に1日に10万トランザクション処理する必要があるが、Ethereumのスピードが早くなっていない場合は、我々のサービスでメインネットを占有してしまう
  • Ethereum価格の上昇に伴いガス代が上昇。ユーザに課しているトランザクション手数料を超えガス代赤字となった

FiNANCiE Lightningの導入(Open β)

  • オークション、マーケットプレイスのロジックをOff-Chainし、実行結果をデータベースに格納する仕様に変更。これによりスケーラビリティのボトルネックとガス代赤字が解消された。そもそもユーザ目線でEthereumの使用は秘匿されており、この変更による悪影響はない。むしろ、トランザクション手数料が無料となり、トランザクションファイナリティの待ち時間がゼロとなったことで、ユーザビリティが著しく向上した
  • Off-Chainでの実行結果を一定時間おきにIPFSへアップロードし、IPFSハッシュをEthereumに書き込む仕様に変更。プラットフォームのIntegrityのためTraceabilityとImmutabilityを確保した格好

f:id:re795h:20191030190949p:plain

今後

  • 我々が目指すのは"Decentralized"なプラットフォーム。On-Chainで全て処理する状態に再移行する
  • 使用するチェーンについてはEthereum3.0が本命。しかし、暫定的にCosmosやPolkadotで独自チェーンを開発することや、EOSやLibraを利用することを検討

最後に

フィナンシェではエンジニアを募集してます。本番運用している、ゲーム関連以外のBlockchainを使ったコンシューマー向けサービスは少ないです。実践的な経験が積め、知見が溜まりますよ。

ご興味のある方は是非、採用フォームWantedlyからお声がけください。

Libraについての勉強会

※本記事はQiitaからの移行です


こんにちは、Takです。前回は「ブロックチェーンとは」という一般的な話題をテーマに勉強会を開きました。今回はLibraについて解説、議論しました。

Libraとは何か?

まずは、Libraについてざっくりと解説しました。詳しい内容はホワイトペーパーを読めばわかるので割愛します。

LibraとはFacebook主導で提唱された金融プラットフォームです。 そして、

多くの人びとに力を与える、シンプルで国境のないグローバルな通貨と金融インフラになる

というミッションを掲げています。 17億人とも言われる銀行口座を持たないような人でも、スマフォは持っています。そのスマフォを通して、手軽に安価に金融サービスが受けられる、そんなプラットフォームの構築を目指しています。

正直、目新しさは全くなく、ブロックチェーンの使い方として、昔から提唱されています。Tedでもプレゼンがありました。5年程前です。ただ、Facebookというパワープレイヤーがやると標榜することに、スケール感を想起させ、本当に実現できそうな期待感があります。

どんなことができるのか?

コンピュータのプログラムを動かすことができます。銀行システムや会計システム、アマゾンや楽天のようなECサイトFacebookTwitterのようなSNS、これらのサーバーサイドをLibraプラットフォーム上に構築できます。

具体的にはスマフォだけでお金を送れます LINE Payみたいに。イメージとしてはこのような感じになると予想します。(動画はStatusというEthereumのモバイルウォレットです)

また、技術的に可能という意味で、お金だけじゃなくてデジタルアセット(デジタルデータとか、権利とか)も送れる ようになるだろうし、デジタルデータだけじゃなくて、不動産とか商品とか、購買できる ようになるはずです。

どんな特徴があるのか?

4点列挙します。

1. 法定通貨バックのステーブルコイン

Libraの価値は一定で、Bitcoinのように変動しません。価値の裏付けとして円やドルなどの法定通貨を用います。

仕組みはTetherとのようだと予想します。(Tetherは1tether=1$なコイン)Suicaのように、入金した分だけ発行され、出金した分だけ減らされます。ただ、USDドルのように単一通貨にペグするとは言っておらず、複数の法定通貨にペグするらしいので、より複雑な仕組みになるはずです。

参考:「価格が安定している暗号通貨 "Stablecoin" 概要」のTether項

2. 独自言語のスマートコントラクトが動くチェーン

プログラミング言語「Move」を用いたスマートコントラクトを実装可能で、Ethereumと同じくトランザクション履歴とステートを記録するアカウントモデルを採用しています。BitcoinのようなUTXOモデルではありません。

余談ですが、アカウントモデルの図としてこちらが大変参考になります。

3. コンソーシアムチェーン

Libraは複数企業により共同で運用されます。運営主体はスイスにある非営利組織でLibra Associationという名称です。

協会メンバーはそうそうたる顔ぶれです。VisaやCoinbaseも参加します。メンバーになるための基準は高く、評価額・顧客資産などの資産を持つ他、グローバルリーチプロダクトの保有、Fortune500などの評価企業であることが条件とされ、$10m(10億)以上の出資が必要です。現在、30社程度が参加しており、今後、100社まで増やす予定とのことです。

参加メンバーの主な収益源はトランザクション手数料です。しかし、このトランザクション手数料は低く設定されるので、他で収益を上げないと割に合いません。なので、参加企業は積極的にLibra上にサービスを展開してゆくと予想します。(なお機関投資家のみに限定された私募形式で投資用のトークンを発行しているようなので、ここでの収益も見込める)

4. コンセンサプロトコルはPBFTのようなもの

無作為に選定されたリーダーノードがブロックを生成、他ノードが検証と認証する形のアルゴリズムで、詳しくはこちらを参照してください。

正確にはHotStuffをベースとしています。 トランザクションのファイナリティが10秒とPBFTとしては遅いです。遅い理由としては、次の二点が考えられます。

心配な点

3点列挙します。

1. 各国の規制

ここを乗り越えないと、サービスとしてローンチできないので、最も重要です。 通貨が国にとってどれほど重要かを示す一例として、仮に通貨を偽装した場合、こうなります。

その国の信用を揺るがし、最悪の場合、国家の転覆をも生じかねない性質を持つため、どの国においても金額の多少に関わらず重罰が適用される。

国としては、国民に法定通貨を使って欲しいはずなので、そこら辺を、協会がどう折り合いをつけてゆくのか注目です。

2. 協会のガバナンス

協会メンバーは平等に1票の権利を持つとはいえ、現実的には企業規模を考えると、権利は不均衡だと思われます。また、全体の意思決定に不利益を被るメンバーが、Bitcoinのフォークのように離反することも考えられます。

そんな状況を、協会がどうやって統治してゆくのか注目です。

3. トランザクションのファイナリティに10秒かかる

ユーザビリティの観点から10秒は遅いと考えます。 仮にお金を送った時、着金確認まで10秒も待たされたらイライラするはずです。上述したように安全面を考えての10秒という設定だと思われるので、これ以上早くするのは難しいと考えます。

UXとセキュリティで、どう妥協点を探ってゆくのか注目です。

参考資料

最後に

フィナンシェではエンジニアを募集してます。本番運用している、ゲーム関連以外のブロックチェーンを使ったコンシューマー向けサービスは少ないです。実践的な経験が積め、知見が溜まりますよ。

ご興味のある方は是非、採用フォームWantedlyからお声がけください。

フィナンシェでブロックチェーン勉強会、始めました。

※本記事はQiitaからの移行です


こんにちは、Takです。前回までは、ブロックチェーンの実践的な知見の共有を主眼に、@ku_sukeさんの記事 @rudoさんの記事 @tomuさんの記事 を書きました。

今回は趣旨を変え、フィナンシェ社内の取り組みをご紹介します。 ブロックチェーン勉強会を始めました。

なぜ始めたの?

フィナンシェはテクノロジーファーストを掲げています。そのための第一歩として、まずはメンバーの誰に聞いてもブロックチェーンについて何かしら語れるものがある状態を目指してゆきます。そのため参加者はエンジニアに限らず、非エンジニアも対象にしました。

どんな事をやったの?

ブロックチェーンに関するトピックをディスカッション形式で議論しました。議論が深まることで、ブロックチェーンの理解が深まる想定です。あえて、スライドによる知識インプット形式では実施しませんでした。

まず、講師が話題を提示 → 有識者が回答 → 参加者が質問 → 講師ないし有識者が回答 → 参加者が質問...loop の流れです。

どんな様子?

講師としてCTOの西出が場をファシリテートしつつ、お昼時だったので、参加者はサブウェイのサンドイッチを頬張りながら、議論を交わしました。 f:id:re795h:20191030185805p:plain f:id:re795h:20191030185821p:plain

どんな感じだった?

ブロックチェーンとは何か」というトピックに対して「容量的に大丈夫?」とか「量子コンピュータが実用化しても問題ない?」とか「台帳はいったいどこにあるのよ!」のように議論が様々な方向に派生してゆきました。ブロックチェーン知ってる人としては、聞いていて面白かったです。

中でも「スマートコントラクトをロードバランサーのように並列処理すれば早くなるのでは?」という質問に驚きました。 つまりShardingです。Ethereum研究者が目下、研究中のスケーリングソリューションを、ブロックチェーンを知らない人が思いついていましたw

最後に

勉強会の内容は、次回以降も記事にしてゆきます。

また、フィナンシェではエンジニアを募集してます。本番運用している、ゲーム関連以外のブロックチェーンを使ったコンシューマー向けサービスは少ないです。実践的な経験が積め、知見が溜まりますよ。

ご興味のある方は是非、採用フォームWantedlyからお声がけください。

ブロックチェーンサービスを作ったけど結局ブロックチェーンを見えなくした

※本記事はQiita @tomu さんの記事の転載です


前回のrudoさんの記事に続き、FiNANCiEではブロックチェーンサービスをどう作ってきたかの話です。今回はブロックチェーンとUX面での考察になります。

ブロックチェーンをやめた

 出だしから、何を言ってるんだと思われるかもしれないですが、最後までお付き合いください。 FiNANCiEは当初、MetaMaskというETHウォレットを利用して各ユーザのブラウザから直接コントラクトを呼び出していました。これが一般的なDAppsの利用方法だからです。Crypto KittiesやMy Crypto Heroesも同じですね。

 しかし、一番初めのベータテストを2018年の夏に実施したところ、やはり多くの課題がありました。まずは速度です。当時は自前のしょぼいインスタンスに建てたGethにアクセスしていたのですが、パラメータ設定も厳しめにしていたので5人のテストでもコントラクト実行のたびに「あれ、反応がないです・・」という微妙な空気が流れてしまいました。(数十秒後に通る)

 ほかにも、何も説明せずにチュートリアルを開始してもらうと、「え、MetaMaskってなんですか」みたいな話になり、よくよく考えると仮想通貨を持っていない人にとっては、次のようなめちゃくちゃ高いハードルを越える必要がありました。

  • サービスに会員登録してチュートリアルをみる
  • MetaMaskが必要といわれ、ダウンロードしてインストールする
  • MetaMaskの英語の注意文を読み、秘密鍵を作成する。忘れないようにする。
  • 仮想通貨取引所をさがして、登録する
  • 本人確認書類を提出し、数日後にハガキが届く
  • はがきを受け取って仮想通貨取引所に入金する
  • 入金した日本円でETHを買う取引所によっては「指値」「成行」などを理解しておく必要あり
  • 入金直後は資金移動制限があるので、半額を自分のMetaMaskウォレットに送金する
  • FiNANCiEに戻ってきて、自分のMetaMaskをFiNANCiE上に紐づけて、利用開始。その際、GAS代として20円程度支払う。

 残念ながら日本では「ちょっとレート悪いけどShapeShiftでクレカでETH買ってきてよ!」とはいろいろな観点から案内できませんし、すべきではありません。

 このため、もしその仕様で推し進める場合、ターゲットユーザは「クリプトのリテラシーが高いユーザーとその周辺くらいまで」となってしまいます。これは非常に悩みました。しかしFiNANCiEのやりたいことを考えると、普通のユーザが使えないとサービスとして広がらないと考え、思いきって捨てることにしました。

FiNANCiEはDAppsであることを捨て、バックエンドにブロックチェーンを使った一般的なwebアプリケーションにすることにしました。

台帳コントラクトを開発する

 しかしながら、全てブロックチェーンを捨てるのではなく、Plasmaをはじめとする高速化や、その他の技術的革新、法的整備により簡単に仮想通貨でブロックチェーンアプリケーションが気軽に楽しめるようになる未来を見据えて、内部的に切り替えしやすい機構を開発することにしました。

 前回ご紹介したRaidenのダッチオークションやBancorのマーケットプレイスはすべてスマートコントラクトで実装されていますが、これらはもともとETHを払い込むことを想定して作られているため、改修が必要があります。

 そこで、日本円で払い込まれたお金をブロックチェーン上で扱いやすくするための独自トークンをERC-20ベースで用意しました。ただトークンを作るだけでは動作しないため、ダッチオークションおよびBancor側に手を加えます。具体的には、独自トークンを管理する台帳コントラクトを用意し、そこから実際の各コントラクトを呼び出すようにします。

f:id:re795h:20191030185244p:plain

 Bancorの場合、ETHのネイティブトークンと、ERC-20では扱いに差があったため多少のハックが必要でしたが、最終的には実装することができました。

コードを監査する

 このようにして実装したスマートコントラクトのコードですが、リリースするにあたりバグやセキュリティホールがあってはいけません。スマートコントラクトの開発はソフトウエアというよりハードウエアに似ているといわれますが、そう簡単に書き換えられないという性質は確かに似ています。

 もし、不具合があった場合は、再度工場に発注して新製品を作るように、お客さんに依頼して新しいコントラクトに引っ越ししてもらう必要があります。

まとめ

 今回はブロックチェーンとUX面という観点で、FiNANCiEが何故いまの形になったかをまとめてみました。 まだまだ、やりたい事はたくさんあるけどひとつひとつ積み上げてよりよいプロダクトにしていきたいと思っています。

 恒例になってしまいますが、FiNANCiEではエンジニアを募集しております!コンシューマー向けサービスとして既に提供を始めているブロックチェーンサービスってまだまだ少ないので、かなり面白い経験がつめるのではなかいと思います。興味お持ちの方は、是非こちらからお声がけください!