Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
ICOコンサルティング事業から得たトークンと全体アーキテクチャ設計方針の知見 @ blockc...
Search
Tomohiro Nakamura
November 14, 2017
Technology
25k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ICOコンサルティング事業から得たトークンと全体アーキテクチャ設計方針の知見 @ blockchain.tokyo #2
Tomohiro Nakamura
November 14, 2017
More Decks by Tomohiro Nakamura
See All by Tomohiro Nakamura
Kotlin + Java EE + MongoDBでサーバ組んで本番で動かしてみた
tomohiron
2
2.1k
FinTechスタートアップAnyPayを支える開発 @ Venture Engineer Meetup #01 -Server Side Night-
tomohiron
2
1.2k
Other Decks in Technology
See All in Technology
リアクションエンジニア ― 小さなリアクションから、話しかけやすい組織をつくる ―
ryuguyana
1
130
OneLakeをデータソースにした AI Search(Foundry IQ)の ライフサイクル管理
ryuseiiida
0
230
TSKaigi Sendai 2026 - tsgo時代のTypeScript Playgroundはどう動くか
teamlab
PRO
0
110
Context Ontology Accelerator 入門 (業務データの意味を、AI エージェントに渡す)
inariku
PRO
2
280
試験勉強はGrokBotでやれ
maigo999
0
110
In-Context Learning再入門。ICLの勾配降下的解釈の研究動向を追ってみる。
dai08srhg
1
400
Active Directory と Entra ID のむむむな関係
murachiakira
PRO
3
1.6k
あなたのDartコードは丸見えかもしれない ~reFlutterで暴くFlutterアプリの中身と多層防御~
zozotech
PRO
0
770
AI時代に求められる優秀なTechLeadの振る舞い
pospome
10
15k
AIエージェントの監視、思考を見るか行動を見るか / Monitoring AI Agents: Thoughts or Actions
yusukeshimizu
1
160
お客様の「やりたい」の先を見通す合意形成プロセス ~裏にある課題と不安を解きほぐすコツ~
yukakoseki
0
110
AIに任せられるFlutterコードベースを作る 〜仕様をコードで表し、ハーネスで守る〜
myohei
1
640
Featured
See All Featured
4 Signs Your Business is Dying
shpigford
187
23k
Into the Great Unknown - MozCon
thekraken
41
2.8k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
460
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
480
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
77k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Between Models and Reality
mayunak
4
560
The browser strikes back
jonoalderson
0
1.9k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
121
120k
Tell your own story through comics
letsgokoyo
1
1.1k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
Transcript
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE CTO Tomohiro Nakamura ( @HAIL ) ICOコンサルティング事業から得た トークンと全体アーキテクチャ設計⽅針の知⾒ 2017/11/14(Tue)
$0/'*%&/5*"-DPQZSJHIUCZ"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 ࣗݾհ
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE εϚʔτϑΥϯܾࡁαʔϏεΛఏڙ ΘΓ͔ΜΞϓϦzQBZNPz ܾࡁαʔϏεzQBZNP CJ[z ఏڙதͷαʔϏεʹ͍ͭͯ ఏڙதͷαʔϏεʹ͍ͭͯ
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE *$0ίϯαϧςΟϯάࣄۀʹ͍ͭͯ ৽نࣄۀ 'JO5FDIࣄۀͷల։ɺۀքͷࢿ࣮ࠃ֎ͷؔ࿈اۀͱͷϦϨʔγϣϯΛ׆͔ͯ͠ɺ Ծ௨՟ʹΑΔࢿۚௐୡɺ*$0ίϯαϧςΟϯάࣄۀΛల։ɻ λʔήοτ ڧΈ ελʔτΞοϓɾະ্தখاۀஶ໊ਓͳͲ ࢿۚௐୡधཁ͕ΑΓߴ͍اۀΛ༏ઌɻ Ұൠফඅऀߴ໊͍ϑΝϯ
*$0ʹೃછΈͷ͋ΔاۀҰൠࢿՈ ػؔࢿՈͷרࠐΈૂ͍༏ઌΛݕ౼ ɾԾ௨՟ۚ༥ۀքͷਂ͍ཧղ ɾࢿՈऔҾॴɺۀఏܞઌͳͲωοτϫʔΫ ɾઓུίϯαϧςΟϯάͷέΠύϏϦςΟ ɾߴ͍ٕज़ྗ $0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE ICOコンサルティング事業について 事前準備 事前設計 実装 ICO実施 ⽬的・意義の 定義 調達額・ 計画検討
既存株主への 説明・説得 スキーム決定 コイン機能・サー ビスとの融合決定 コイン実装 サ イ ト オ プ ン プ レ セ ル ク ラ ウ ド セ ル 社 内 側 の 動 き 社 外 協 議 取引所との協議 弁護⼠確認・協議 プロモーション・ 投資家との コミュニケーション キャンペーン 設計 オペレーション 設計 ホワイト ペーパー 作成 サイト 作成 セ カ ン ダ リ マ ケ ッ ト 開 設 1カ⽉〜 1〜2カ⽉ 2〜3カ⽉ :法務・会計 :技術・開発 :ビジネス・マーケ
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE どうしたら ICOに投資してくれるだろう?
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 1. 値上がりが期待できる 2. 付加価値がついている
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 付加価値のかたち ICO実施企業の 提供サービス内にて 通貨として利⽤、もしくは 特別割引などの優待を 受ける事が可能 コインが株式のような 役割を担い、 保有者に対して
企業経営・プロジェクトの 収益の⼀部が還元される サービス型 株式型
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 実際に設計してみよう
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE その前に前提を・・・ Ethereumブロックチェーンに乗っかる ICOの多くはEthereumベース Solidityを使った開発やParityなどを使ったデプロイや管理などエコシステムが できあがりすぎていて圧倒的に楽なため 送受信されるコントラクトはERC20インタフェースに乗っかる Ethereumベースのコントラクトが基本的に実装するべき関数の定義たち、 と考えておけば良い ウォレットや取引所サービスたちは、基本的に各トークンがERC20準拠である
ことを前提にしている
$0/'*%&/5*"-DPQZSJHIUCZ"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); }
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 典型的な(シンプルな)セールの流れ CONFIDENTIAL : copyright © by 2017 AnyPay inc.
all rights reserved 1. セールの実施前に参加予定者に事前登録してもらい連絡⼿段を確保 (Email, Slack, Telegram, etc…) 2. セールの実施前に、参加予定者にETHを取引所アカウントではなく、⾃ 分で秘密鍵を管理しているアカウントに移動しておくよう伝達 3. セール開始直前に、参加予定者にETH振込先を伝達 4. ETHを振り込んでくれたアドレスに、ERC20準拠であるICOトークンを 送り返す 5. 終了⽇時または最⼤調達⾦額に達したら締め切り
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 〜ケーススタディ〜 想定クライアントはアジアのあるライドシェアサービス 当然ながら、ICOをきっかけにサービスの拡⼤を考えている 以下のフェーズに分けてICOをしたいと考えている
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE ケーススタディ ‒ Phase 1 ① このICOで得た資⾦で、サービスに使う⾞両を購⼊する ② このトークンを持っていることにより、購⼊された⾞両によって得られた利益のうち⼀ 部が分配される(株式型)。利益の分配はEthereumベースで毎⽉決まったタイミングで
⾏われる ③ トークンセールの参加にはKYC(本⼈確認) が要求される。また、許可されていないアド レスにtransferすることは許可しない ④ Phase 1のセールは2回⾏われる。それぞれ期間と上限額を事前に決定する。1回⽬は 2ヶ⽉後ぐらいを予定している。2回⽬は未定 ⑤ KYCは2度のPhase 1セールで共有される ⑥ 後々発⾏されるPhase 2のトークンに割引価格で変換できる ⑦ または、⾞両が償却されるまでトークンを持ち続けた場合、再売却価格の分配を受ける こともできる Phase 1
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE ケーススタディ ‒ Phase 2 ① Phase 2のトークンは、このICO予定の会社以外にも、世界中のシェアリング サービスで利⽤可能なサービス型トークンとなっていく計画を持っている ②
サービスのユーザは、このトークンを⽀払に利⽤することができる ③ シェアする側のユーザは、対価としてこのトークンを受取る ④ Phase 1とは違い、こちらのトークンは取引所への上場を予定している Phase 2
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE さあ設計してみよう! オブジェクト指向でいうところのクラス図を書こう! (Ethereumのコントラクト開発は、 正直オブジェクト指向にちょっと寄った JavaScript開発ぐらいの気持ち)
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 要点1 ユーザに伝達したアドレス上の コントラクトを上書きすることは無理
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 要点2 数ヶ⽉以上後先のサービスのことなど 普通確定しない(仕様は誰も知らない) (通貨が仮想になりDBがブロックチェーン になったぐらいでこの宇宙の決まりが 変わるわけない)
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE この2点からの導き • 柔軟に作ろう • ユーザが触れるコントラクトでごちゃごちゃやるのはやめよう • 迷惑かけずに実装を変更できるようにしよう • 先のことはわからないが可能性が⾼いことのPoCはなるべくしよう
• こんな当たり前のことをするのが⾯倒な時点でつらぽよなので、す べてをEthereum上でやるかどうかは疑問視してかかろう (時間次第ですがここで1分ぐらい待ちます)
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 解答例
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 登場⼈物 1. Coin Vendor(投資家がETHを振り込むアドレスのコントラクト) 2. Coin(投資家が⼿に⼊れるトークンの実装。ERC20) 3. Coin Implementation(ロジックを書くコントラクト)
4. Storage(データを持つコントラクト) 5. Shared Storage(複数トークン間でシェアするデータを持つコント ラクト)
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Vendor • Phase 1のコインをまとめ て”Private Coin” と便宜上呼ぶ •
ユーザがこのコントラクトに ETHを送るとpayableな無名関 数()が呼ばれる • セールの期間やこれまでに販売 した(発⾏した)量、最⼤販売量、 販売単位などが定義されている • コインの実装コントラクトへの 参照を持つ • transferFundsはたまったETH を引き出す関数
$0/'*%&/5*"-DPQZSJHIUCZ"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; }
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Implementation • 実際のロジックを持つ • データは持たない • ⾮管理者から関数が叩かれ ることは想定していないの
で殆どの関数が auth 修飾 ⼦つき
$0/'*%&/5*"-DPQZSJHIUCZ"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トーク ンに割引価格で交換できる)
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin • 取引されるトークンのコン トラクト • ERC20準拠 • Eventを呼ぶ •
実装はimplに委譲
$0/'*%&/5*"-DPQZSJHIUCZ"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に委譲
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE Coin Storage Phase 1の2つのトークンそれぞれ別々に持つデータのコントラクト
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE Shared Coin Storage KYC済みアドレスのリストなど、 Phase 1の2つのトークンで共有するデータのコントラクト
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE もう⼀度登場⼈物 1. Coin Vendor(投資家がETHを振り込むアドレスのコントラクト) 2. Coin(投資家が⼿に⼊れるトークンの実装。ERC20) 3. Coin Implementation(ロジックを書くコントラクト)
4. Storage(データを持つコントラクト) 5. Shared Storage(複数トークン間でシェアするデータを持つコント ラクト)
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE リリース⽅法 1. 全てのコントラクトをせっせとデプロイする 2. setImpl(address) auth public: bool などを実⾏して付け替えを⾏う
3. KYC済みユーザの追加は impl.addApprovedAddress(address) データのコントラクト書き換えの場合は マイグレーションも頑張らないといけませんよね…… 正直Ethereumすごい。すごいけど
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE Phase 2をすべて この調⼦で実装していこうと思ったら まだつらい気がしている…… (GAS⼿数料も⾺⿅にならない笑)
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE ⼿段のために⽬的を⾒失わない ⼀番⼤事なことは • ◦ トークンの価値が上がり投資家もユーザもハッピー • ◦ サービスが使いやすくてユーザもハッピー •
◦ メンテが楽で開発者もハッピー • × 全部ブロックチェーンでやるとかっこいい ストレージが増える(RDB, NoSQL, ブロックチェーンetc)ごとに、 当然ながらメンテは⼤変。 Ethereumとプライベートな独⾃ブロックチェーンの併⽤も⼤変。 かっこよさとハッピー、両⽴したい、どうしよう…… えっ、もっと詳しく話を聞きたいって?
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE ここでお知らせです AnyPayではICOコンサルティング を提供しております AnyPayでは優秀なエンジニアと コンサルタントを募集しております
$0/'*%&/5*"-DPQZSJHIUCZ"OZ1BZJODBMMSJHIUTSFTFSWFE 決済でもブロックチェーンでも、 興味ある⼈はWantedly で応募待ってます! https://www.wantedly.com/projects/167898