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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
その Lambda、8分で 管理者権限まで奪われます
k1nakayama
7
3.7k
【技術的負債conf】事業成長に伴う技術的負債の説明責任とAIによるモニタリング、認知的負債について
i35_267
4
2.2k
ボードゲームの遊び相手をFoundation Modelsで作る / iOSDC Japan 2026
genda
0
190
AI 時代のスタートアップエコシステ厶から考究する技術的負債との向き合い方
m3m0r7
PRO
3
2.7k
Azure Serverless 2026:Production-ready な AI エージェント基盤 / Azure Serverless 2026: Production-Ready AI Agent Platform
miyake
2
610
JSONataとAWS Step Functionsで目指すRuntimelessな世界
mu7889yoon
1
500
Oracle Cloud Infrastructure(OCI):Onboarding Session(はじめてのOCI/Oracle Supportご利⽤ガイド)
oracle4engineer
PRO
2
21k
AIに任せた品質は、誰が見立てるのか - AI時代のテストマネジメント
nakanao
3
3.1k
開発投資の期待値を上げるプロダクトロードマップづくり ~プロダクトエンジニアが越境して事業を伸ばす~
kekekenta
1
250
AIエージェントを安全で速い現場監督にする:Jev・Obsidian・メタハーネス
x5gtrn
PRO
0
120
SREの視点で考えるSIEM活用術 〜AWS環境でのセキュリティ強化〜
cscengineer
PRO
0
360
AIエージェントの権限管理 3: Agentic RAG の Fine grained access control 編
ren8k
1
270
Featured
See All Featured
Building the Perfect Custom Keyboard
takai
2
890
How to build a perfect <img>
jonoalderson
1
6k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Testing 201, or: Great Expectations
jmmastey
46
8.3k
Making Projects Easy
brettharned
120
6.8k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
How to Talk to Developers About Accessibility
jct
2
560
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Marketing to machines
jonoalderson
1
5.8k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
850
A Soul's Torment
seathinner
8
3.6k
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