Slide 1

Slide 1 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE CTO Tomohiro Nakamura ( @HAIL ) ICOコンサルティング事業から得た トークンと全体アーキテクチャ設計⽅針の知⾒ 2017/11/14(Tue)

Slide 2

Slide 2 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE ⾃紹介 AnyPay株式会社 CTO Tomohiro Nakamura ( @HAIL ) 2010年 早稲⽥⼤学⼤学院情報理⼯学専攻 2010年 Goldman Sachs 2012年 Electronic Arts (ex. Playfish) 2014年 Wekids Inc. 創業 2016年 AnyPay株式会社 CTOとして⼊社 好き: Kotlin, Android, GCP paymo招待コード: PNKYFNP ࣗݾ঺հ

Slide 3

Slide 3 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE εϚʔτϑΥϯܾࡁαʔϏεΛఏڙ ΘΓ͔ΜΞϓϦzQBZNPz ܾࡁαʔϏεzQBZNP CJ[z ఏڙதͷαʔϏεʹ͍ͭͯ ఏڙதͷαʔϏεʹ͍ͭͯ

Slide 4

Slide 4 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE *$0ίϯαϧςΟϯάࣄۀʹ͍ͭͯ ৽نࣄۀ 'JO5FDIࣄۀͷల։ɺۀք΁ͷ౤ࢿ࣮੷΍ࠃ಺֎ͷؔ࿈اۀͱͷϦϨʔγϣϯΛ׆͔ͯ͠ɺ Ծ૝௨՟ʹΑΔࢿۚௐୡɺ*$0ίϯαϧςΟϯάࣄۀΛల։ɻ λʔήοτ ڧΈ ελʔτΞοϓɾະ্৔தখاۀஶ໊ਓͳͲ ࢿۚௐୡधཁ͕ΑΓߴ͍اۀΛ༏ઌɻ Ұൠফඅऀ΁ߴ஌໊౓΍޿͍ϑΝϯ૚ *$0ʹೃછΈͷ͋Δاۀ΍Ұൠ౤ࢿՈ΍ ػؔ౤ࢿՈͷרࠐΈૂ͍༏ઌ౓Λݕ౼ ɾԾ૝௨՟ۚ༥ۀք΁ͷਂ͍ཧղ ɾ౤ࢿՈऔҾॴɺۀ຿ఏܞઌͳͲωοτϫʔΫ ɾઓུίϯαϧςΟϯάͷέΠύϏϦςΟ ɾߴ͍ٕज़ྗ $0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE

Slide 5

Slide 5 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE ICOコンサルティング事業について 事前準備 事前設計 実装 ICO実施 ⽬的・意義の 定義 調達額・ 計画検討 既存株主への 説明・説得 スキーム決定 コイン機能・サー ビスとの融合決定 コイン実装 サ イ ト オ プ ン プ レ セ ル ク ラ ウ ド セ ル 社 内 側 の 動 き 社 外 協 議 取引所との協議 弁護⼠確認・協議 プロモーション・ 投資家との コミュニケーション キャンペーン 設計 オペレーション 設計 ホワイト ペーパー 作成 サイト 作成 セ カ ン ダ リ マ ケ ッ ト 開 設 1カ⽉〜 1〜2カ⽉ 2〜3カ⽉ :法務・会計 :技術・開発 :ビジネス・マーケ

Slide 6

Slide 6 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE どうしたら ICOに投資してくれるだろう?

Slide 7

Slide 7 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 1. 値上がりが期待できる 2. 付加価値がついている

Slide 8

Slide 8 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 付加価値のかたち ICO実施企業の 提供サービス内にて 通貨として利⽤、もしくは 特別割引などの優待を 受ける事が可能 コインが株式のような 役割を担い、 保有者に対して 企業経営・プロジェクトの 収益の⼀部が還元される サービス型 株式型

Slide 9

Slide 9 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 実際に設計してみよう

Slide 10

Slide 10 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE その前に前提を・・・ Ethereumブロックチェーンに乗っかる ICOの多くはEthereumベース Solidityを使った開発やParityなどを使ったデプロイや管理などエコシステムが できあがりすぎていて圧倒的に楽なため 送受信されるコントラクトはERC20インタフェースに乗っかる Ethereumベースのコントラクトが基本的に実装するべき関数の定義たち、 と考えておけば良い ウォレットや取引所サービスたちは、基本的に各トークンがERC20準拠である ことを前提にしている

Slide 11

Slide 11 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE ERC20 contract ERC20 { // 合計流通量を返す function totalSupply() constant returns (uint totalSupply); // _owner の持っている量を返す function balanceOf(address _owner) constant returns (uint balance); // _to に _value 分送る(ウォレットアプリがよく叩く関数) function transfer(address _to, uint _value) returns (bool success); // _from から _to に _value 分代理で送る function transferFrom(address _from, address _to, uint _value) returns (bool success); // _spender に _value 分代理で送ることを許可する function approve(address _spender, uint _value) returns (bool success); // _owner は _spender にどれだけの量を代理で送ることを許可しているか返す function allowance(address _owner, address _spender) constant returns (uint remaining); }

Slide 12

Slide 12 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 典型的な(シンプルな)セールの流れ CONFIDENTIAL : copyright © by 2017 AnyPay inc. all rights reserved 1. セールの実施前に参加予定者に事前登録してもらい連絡⼿段を確保 (Email, Slack, Telegram, etc…) 2. セールの実施前に、参加予定者にETHを取引所アカウントではなく、⾃ 分で秘密鍵を管理しているアカウントに移動しておくよう伝達 3. セール開始直前に、参加予定者にETH振込先を伝達 4. ETHを振り込んでくれたアドレスに、ERC20準拠であるICOトークンを 送り返す 5. 終了⽇時または最⼤調達⾦額に達したら締め切り

Slide 13

Slide 13 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 〜ケーススタディ〜 想定クライアントはアジアのあるライドシェアサービス 当然ながら、ICOをきっかけにサービスの拡⼤を考えている 以下のフェーズに分けてICOをしたいと考えている

Slide 14

Slide 14 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE ケーススタディ ‒ Phase 1 ① このICOで得た資⾦で、サービスに使う⾞両を購⼊する ② このトークンを持っていることにより、購⼊された⾞両によって得られた利益のうち⼀ 部が分配される(株式型)。利益の分配はEthereumベースで毎⽉決まったタイミングで ⾏われる ③ トークンセールの参加にはKYC(本⼈確認) が要求される。また、許可されていないアド レスにtransferすることは許可しない ④ Phase 1のセールは2回⾏われる。それぞれ期間と上限額を事前に決定する。1回⽬は 2ヶ⽉後ぐらいを予定している。2回⽬は未定 ⑤ KYCは2度のPhase 1セールで共有される ⑥ 後々発⾏されるPhase 2のトークンに割引価格で変換できる ⑦ または、⾞両が償却されるまでトークンを持ち続けた場合、再売却価格の分配を受ける こともできる Phase 1

Slide 15

Slide 15 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE ケーススタディ ‒ Phase 2 ① Phase 2のトークンは、このICO予定の会社以外にも、世界中のシェアリング サービスで利⽤可能なサービス型トークンとなっていく計画を持っている ② サービスのユーザは、このトークンを⽀払に利⽤することができる ③ シェアする側のユーザは、対価としてこのトークンを受取る ④ Phase 1とは違い、こちらのトークンは取引所への上場を予定している Phase 2

Slide 16

Slide 16 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE さあ設計してみよう! オブジェクト指向でいうところのクラス図を書こう! (Ethereumのコントラクト開発は、 正直オブジェクト指向にちょっと寄った JavaScript開発ぐらいの気持ち)

Slide 17

Slide 17 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 要点1 ユーザに伝達したアドレス上の コントラクトを上書きすることは無理

Slide 18

Slide 18 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 要点2 数ヶ⽉以上後先のサービスのことなど 普通確定しない(仕様は誰も知らない) (通貨が仮想になりDBがブロックチェーン になったぐらいでこの宇宙の決まりが 変わるわけない)

Slide 19

Slide 19 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE この2点からの導き • 柔軟に作ろう • ユーザが触れるコントラクトでごちゃごちゃやるのはやめよう • 迷惑かけずに実装を変更できるようにしよう • 先のことはわからないが可能性が⾼いことのPoCはなるべくしよう • こんな当たり前のことをするのが⾯倒な時点でつらぽよなので、す べてをEthereum上でやるかどうかは疑問視してかかろう (時間次第ですがここで1分ぐらい待ちます)

Slide 20

Slide 20 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 解答例

Slide 21

Slide 21 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 登場⼈物 1. Coin Vendor(投資家がETHを振り込むアドレスのコントラクト) 2. Coin(投資家が⼿に⼊れるトークンの実装。ERC20) 3. Coin Implementation(ロジックを書くコントラクト) 4. Storage(データを持つコントラクト) 5. Shared Storage(複数トークン間でシェアするデータを持つコント ラクト)

Slide 22

Slide 22 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Vendor • Phase 1のコインをまとめ て”Private Coin” と便宜上呼ぶ • ユーザがこのコントラクトに ETHを送るとpayableな無名関 数()が呼ばれる • セールの期間やこれまでに販売 した(発⾏した)量、最⼤販売量、 販売単位などが定義されている • コインの実装コントラクトへの 参照を持つ • transferFundsはたまったETH を引き出す関数

Slide 23

Slide 23 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Vendor要所 function () public payable { vend(msg.sender, msg.value, now); } function vend(address receiver, uint value, uint timestamp) internal returns (bool) { uint amount = value / tokenUnitPrice; // ETH (単位は wei) を購入数に変換する require(amount >= minimumPurchaseUnit); // 最小販売トークン数を超えているか require(timestamp >= salesBegin && timestamp < salesEnd); // 販売期間の確認 require(safeAdd(amount, cumulativeSalesAmount) <= salesAmount); // 在庫の確認 cumulativeSalesAmount = safeAdd(cumulativeSalesAmount, amount); impl.mint(receiver, amount); // 発行する(実装はimplに委譲されている) return true; }

Slide 24

Slide 24 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Implementation • 実際のロジックを持つ • データは持たない • ⾮管理者から関数が叩かれ ることは想定していないの で殆どの関数が auth 修飾 ⼦つき

Slide 25

Slide 25 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Implementation要所 function transfer(address sender, address to, uint amount) auth public returns (bool) { require(coinStorage.coinBalanceOf(sender) >= amount); // 残高を超えて送金してないか require(amount > 0); // 1円以上送ろうとしているか // オーナーまたは許可された (KYC 通過済み) アドレスかを確認 require(sharedStorage.isOwnerAddress(to) || sharedStorage.isApprovedAddress(to)); // 送金元の残高を減らし、送金先の残高を増やす coinStorage.setCoinBalance(sender, safeSub(coinStorage.coinBalanceOf(sender), amount)); coinStorage.setCoinBalance(to, safeAdd(coinStorage.coinBalanceOf(to), amount)); // 送金先がコントラクトで、isPrivateTokenAcceptable が true を返すコントラクトではreceiveToken() if (isContract(to)) { PrivateCoinAcceptableContract receiver = PrivateCoinAcceptableContract(to); if (receiver.isPrivateTokenAcceptable()) { require(receiver.receiveToken(sender, amount)); } } return true; } ここがPhase 2のPoC部分 (Phase 1トークンはPhase 2トーク ンに割引価格で交換できる)

Slide 26

Slide 26 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin • 取引されるトークンのコン トラクト • ERC20準拠 • Eventを呼ぶ • 実装はimplに委譲

Slide 27

Slide 27 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin要所 function transfer(address to, uint amount) public returns (bool) { if (impl.transfer(msg.sender, to, amount)) { Transfer(msg.sender, to, amount); return true; } else { return false; } } Eventを呼ぶ 基本的にimplに委譲

Slide 28

Slide 28 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Storage Phase 1の2つのトークンそれぞれ別々に持つデータのコントラクト

Slide 29

Slide 29 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Shared Coin Storage KYC済みアドレスのリストなど、 Phase 1の2つのトークンで共有するデータのコントラクト

Slide 30

Slide 30 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE もう⼀度登場⼈物 1. Coin Vendor(投資家がETHを振り込むアドレスのコントラクト) 2. Coin(投資家が⼿に⼊れるトークンの実装。ERC20) 3. Coin Implementation(ロジックを書くコントラクト) 4. Storage(データを持つコントラクト) 5. Shared Storage(複数トークン間でシェアするデータを持つコント ラクト)

Slide 31

Slide 31 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE リリース⽅法 1. 全てのコントラクトをせっせとデプロイする 2. setImpl(address) auth public: bool などを実⾏して付け替えを⾏う 3. KYC済みユーザの追加は impl.addApprovedAddress(address) データのコントラクト書き換えの場合は マイグレーションも頑張らないといけませんよね…… 正直Ethereumすごい。すごいけど

Slide 32

Slide 32 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE Phase 2をすべて この調⼦で実装していこうと思ったら まだつらい気がしている…… (GAS⼿数料も⾺⿅にならない笑)

Slide 33

Slide 33 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE ⼿段のために⽬的を⾒失わない ⼀番⼤事なことは • ○ トークンの価値が上がり投資家もユーザもハッピー • ○ サービスが使いやすくてユーザもハッピー • ○ メンテが楽で開発者もハッピー • × 全部ブロックチェーンでやるとかっこいい ストレージが増える(RDB, NoSQL, ブロックチェーンetc)ごとに、 当然ながらメンテは⼤変。 Ethereumとプライベートな独⾃ブロックチェーンの併⽤も⼤変。 かっこよさとハッピー、両⽴したい、どうしよう…… えっ、もっと詳しく話を聞きたいって?

Slide 34

Slide 34 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE ここでお知らせです AnyPayではICOコンサルティング を提供しております AnyPayでは優秀なエンジニアと コンサルタントを募集しております

Slide 35

Slide 35 text

$0/'*%&/5*"-DPQZSJHIU˜CZ"OZ1BZJODBMMSJHIUTSFTFSWFE 決済でもブロックチェーンでも、 興味ある⼈はWantedly で応募待ってます! https://www.wantedly.com/projects/167898