シードって何? VC関連のメモ
スタートアップ界隈で仕事をしていれば、ジャフコとかインキュベイトファンドとか、
VC(ベンチャーキャピタル)の名前はよく聞く。
けれど彼らが何をしているのか私はよくわかっていない。
中の人に聞いてみるのが良さそうだけれど、まずは周辺知識についてまとめておく。
むっちゃわかりやすい参考記事 : 起業したてのシードスタートアップに投資する日本のVC(シードアクセラレーター/インキュベーター)さんをまとめました | TURN YOUR IDEAS INTO REALITY.
スタートアップのフェーズ
これについては調べるといろいろな区分けがあるが、
海外の記事を見るとだいたいこの4つだったので以下のまとめとする。(解説文は私の肌感)
- シード (seed) : プロダクト作成のため、資金や協力者集めの段階。社員(?) 1〜2人程度
- シリーズA : プロダクトは出来たがまだまだ会社は不安定。社員3〜10人程度
- シリーズB : 資金繰りに安定が見えてきた。買収を持ちかけられることも。社員10〜30人程度
- シリーズC : 事業の拡大が見えてきて、上場準備をおこなうため外部から積極的に役員を入れ始めたりする。社員50人〜程度
pre-seed, seed, post-seed, pre-A, Early A, A, Late A, B, ... などなど、細分化するといろんな呼び名がある。
参考: There are only three startup stages – Angular Ventures – Medium
……が、まあ、参考として貼った記事のタイトルが
『There are only three startup stages』であるように、大事なのは3つだ。
シード期・シリーズA・シリーズAを越えた後 の3つ。
実際、ベンチャー界隈の人と話すときは「シード」と「シリーズA」という言葉を覚えておけばなんとかなる。
シードからシリーズAあたりのことを「スタートアップ」と呼ぶこともあるので、
「『スタートアップ』の時期を乗り越えて……」という発言は「お金のない時期を乗り越えて……」という意味に解釈すればOK。
「スタートアップ界隈」と言うときは「ベンチャー界隈」と同義。
「スタートアップ」という言葉の範囲は広いのだ……。
ピッチイベント(ビジネスコンテスト)
IVS LaunchPad、TechCrunch Tokyo などが有名なピッチイベント。
(参考: ピッチイベントまとめてみました。 | 起業サプリジャーナル )
「起業したい、こんなアイディアがある!」という人たちの発表の場で、ここから投資が決まることも多い。
起業家からしてみれば、「このアイディア良さそうだけど、すでにありきたりなものじゃないか」「資金調達できるだろうか……」などの不安がある中で揉んでもらえるし、
投資家からしてみれば有望な投資先の発見につながるのでまさに Win-Win なイベント。
ピッチ (pitch) というのは短いプレゼンを指すらしい。
ピッチと言うと「ピッチャー(ボールを投げる人)」を連想するけど、「言葉を投げる」の意味合いもあるようで…。
(参考: 現役商社マンによる実践ビジネス英会話 #6 Pitch|WEBマガジンKEY-PRESS《キープレス》by三鬼商事 )
ピッチイベントへの参加を考えるなら、このテンプレートが役に立ちそう。
どのようなことをスライドに盛り込むべきか、わかりやすくまとめられている。↓
[スライド] スタートアップの 3 分ピッチテンプレート – Taka Umada – Medium
デット, エクイティ
デット (debt) は「負債」、エクイティ (equity) は「株式」。
参考: 投資の基礎知識「デット」と「エクイティ」の違いとは? | 富裕層向け資産防衛メディア | 幻冬舎ゴールドオンライン
起業家から見て日本政策金融公庫からの借り入れは debt で、
VCからの資金提供は equity 。
「エクイティ」という単語は、投資会社出身の人と話すとそこそこ出るワードなので覚えておくと便利。
VCの種類
ざっくり分けた。
- 銀行や保険会社など金融系
- 例: SMBCベンチャーキャピタル, 三菱UFJキャピタル, りそなキャピタル, 三井住友海上キャピタル
- 証券系(上場時に幹事会社になれる旨味があるので、金融系とは分けた)
- 事業会社系(CVC = Corporate Venture Capital)
- 独立系(VCが本業)
- ANRI, B Dash Ventures, インキュベイトファンド, WiL, グロービス・キャピタル・パートナーズ, インフィニティ・ベンチャー・パートナーズ(IVP)
- 個人投資家
- 例: 家入一真さん, 佐藤裕介さん, 中川綾太郎(あやたろう)さん, 古川健介さん
- 政府系
- 例: 産業革新機構
例を挙げればキリがないのでかなり絞ったぞ!
思っていたよりいっぱいあるぞ!
ジャフコは野村證券系だったけれど、2017年7月に野村の持っていた株を買い*1、
今は独立系となった様子。
CVCとして2019年2月に『DMM VENTURES』が誕生したのが最近のニュース。
( 「40以上の事業を持つ強みを生かせ」DMMがCVCをつくる理由 | STARTUP DB MEDIA | 日々進化する、成長産業領域に特化した情報プラットフォーム )
基本的にVCは資産運用を目的とするが、
CVCは事業シナジーを目的とする面もあるのが異なるところ。
(参考: 001 Startupの資金調達 — ピッチの相手はVCそれともCVC? – S. Nishimura – Medium )
参考記事に
スタートアップからすると、特定の企業の資金を受け入れ、「色がつく」ことを避けたいという場合もある
とあるが、この「(資金調達により)色がつく」という表現を使うことはあるので覚えておくといい。
資金調達を受けるというのは、自分の会社の決定権の一部を売ることでもあるので、
どこから投資を受けるかというのは思いのほかセンシティブ。
(お金を調達できればいいじゃん、くらいに安直に考えていた……)
VCの資金をどうとらえるか、銀行融資ではないので返済する必要はありませんが、出資を受けることはある意味自分の株という魂の一部を渡すことと同じです。なので、それに対して何を求めるか、本当にお金なのか、一緒に経営していくことなのか、ノウハウなのか、よく判断したほうが良いとは思います。
( http://www.jafco.co.jp/case/uuum より引用)
という一文がよく表している。
夜も遅くなってきたのでここまで。
ファンドの資金集め手法とか、1号, 2号とか、実際どのような業務が行われているのかとか、まだまだ謎が多い。
ベンチャーに投資して投資の運用益で食っていると思われがちなベンチャー・キャピタルのお仕事は意外にもファンドの固定手数料が食い扶持のメインなビジネス
( http://www.turnyourideasintoreality.com/2013/12/vcinjapan より引用)
というのも実際そうなのか気になるところ。
VCやってる人に、どういう思いで何をして、どうやりくりをしているのか聞いてみたいなぁ。
CircleCI 2.0 で deploygate に Android アプリをアップロード
Android アプリを DeployGate へ
CircleCI を使って簡単にデプロイしたいな〜、と記事を探したら、
1.0 の記事が多かったので CircleCI 2.0 向けの記事を書くことにしました。
異なる証明書で署名されたアプリと言われ、deploygate に毎回アンインストールを求められる件についても、
「6. 異なる証明書で署名されたアプリと言われないために」の項で解決策を記しています。
実験台となったのは、
前回の『AndroidのgRPCクライアントをKotlinで実装しました』の記事で取り扱ったこちらのリポジトリ。
1. config.yml はこうなった
まずは出来上がりから。
.circleci ディレクトリを作った上で、その中に config.yml という名前で保存します。
ただ、このあとの解説で書きますが、 DG_API_KEY
を設定しないといけないので、
このままだとまだデプロイが出来ません。
aliases: android_docker: &android_docker docker: - image: circleci/android:api-28 environment: TZ: Asia/Tokyo steps: - restore_cache: &restore_cache key: &jars_key jars-{{ checksum "build.gradle.kts" }}-{{ checksum "app/build.gradle.kts" }} - run: &download_deps name: Download dependencies command: ./gradlew androidDependencies - save_cache: &save_cache paths: - ~/.gradle key: *jars_key - run: &build_debug_apk name: Build debug APK command: ./gradlew assembleDebug - run: &test name: test command: ./gradlew test - run: &upload_to_deploy_gate name: Upload to DeployGate # Set DG_API_KEY in CircleCI command: | APK_PATH=app/build/outputs/apk/debug/app-debug.apk TIME=$(date "+%Y/%m/%d %H:%M") COMMIT_HASH=$(git log --format="%H" -n 1 | cut -c 1-8) USERNAME=nekonenene curl -F "file=@${APK_PATH}" -F "token=${DG_API_KEY}" -F "message=Build by CircleCI <${COMMIT_HASH}> (${TIME})" https://deploygate.com/api/users/${USERNAME}/apps version: 2 jobs: build: <<: *android_docker steps: - checkout - restore_cache: *restore_cache - run: *download_deps - save_cache: *save_cache - run: *build_debug_apk test: <<: *android_docker steps: - checkout - restore_cache: *restore_cache - run: *download_deps - save_cache: *save_cache - run: *test deploy: <<: *android_docker steps: - checkout - restore_cache: *restore_cache - run: *download_deps - save_cache: *save_cache - run: *build_debug_apk - run: *upload_to_deploy_gate workflows: version: 2 build_and_deploy: jobs: - build - test - deploy: requires: - build - test filters: branches: only: master context: deploygate
あとで再び書きますが、このリポジトリでは gradle 設定を Kotlin で書いているために、
「build.gradle.kts」と書いている箇所があります。
たいていの方は「build.gradle」と書き直してください。
また、docker image は「circleci/android:api-28」を使っていますが、
compileSdkVersion に合わせたものをお使いください。
2. master 以外のブランチではデプロイしない
他のブランチで push されたときもテストはしたいけど、
deploygate にアップロードするのは master ブランチへコミットがあったときに限定したいな〜
という希望があると思います。
それを実現しているのが workflows の部分です。
workflows: version: 2 build_and_deploy: jobs: - build - test - deploy: requires: - build - test filters: branches: only: master context: deploygate
workflows としてはこうなっています。
ここの jobs で、実行する job を指定でき、各々にはさらに設定を書くことが出来ます。
- deploy: requires: - build - test filters: branches: only: master context: deploygate
filters: に branches: only: master と書かれていることによって、
master ブランチへコミットがあったときだけ、deploy job は実行されるようになっています。
また、 requires: に build と test が書かれていることによって、
build job と test job の両方が終わった後に deploy job が走るようになっています。
これを書かなかった場合、他の job と deploy job がパラレルに(並行して)走ります。
つまり、フローとしては以下のようになっています。
build ──┬── deploy (only: master) test ──┘
context については後で説明します。
3. 各 job を定義する
workflows から先に説明しましたが、もっとも大事なのは jobs の部分です。
ここで、何がおこなわれるかを定義します。
version: 2 jobs: build: <<: *android_docker steps: - checkout - restore_cache: *restore_cache - run: *download_deps - save_cache: *save_cache - run: *build_debug_apk
と書かれている部分ですね。
簡潔に書くため、YAMLのAnchors and Aliases 機能を使って書きましたが、
省略せずに書くと以下のようになっています。
jobs: build: docker: - image: circleci/android:api-28 environment: TZ: Asia/Tokyo steps: - checkout - restore_cache: key: jars-{{ checksum "build.gradle.kts" }}-{{ checksum "app/build.gradle.kts" }} - run: name: Download dependencies command: ./gradlew androidDependencies - save_cache: paths: - ~/.gradle key: jars-{{ checksum "build.gradle.kts" }}-{{ checksum "app/build.gradle.kts" }} - run: name: Build debug APK command: ./gradlew assembleDebug
今回はビルドに使う Android SDK が 28 であるため、
使用する Docker image も circleci/android:api-28
を使用しています。
他のバージョンもありますので、ふさわしいものを探してください。
https://hub.docker.com/r/circleci/android/tags
restore_cache では、
build.gradle.kts
および app/build.gradle.kts
が更新されているかを確認し、
変更がなければ以前 save_cache で保存した .gradle
を使用します。
これにより、2回目以降の CircleCI の実行時間が短くなります。
前回の記事でも触れましたが、 Gradle Kotlin DSL により
gradle 設定を Kotlin で書いているためにファイル名が「build.gradle.kts」になっています。
Gradle Kotlin DSL を使っていない場合は、 key: のところは
jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
と書きましょう。
4. deploygate にアップロード
肝心の deploygate へのアップロードですね!
このようにコマンドを作成しました。
- run: &upload_to_deploy_gate name: Upload to DeployGate # Set DG_API_KEY in CircleCI command: | APK_PATH=app/build/outputs/apk/debug/app-debug.apk TIME=$(date "+%Y/%m/%d %H:%M") COMMIT_HASH=$(git log --format="%H" -n 1 | cut -c 1-8) USERNAME=nekonenene curl -F "file=@${APK_PATH}" -F "token=${DG_API_KEY}" -F "message=Build by CircleCI <${COMMIT_HASH}> (${TIME})" https://deploygate.com/api/users/${USERNAME}/apps
deploygate の API ドキュメント によれば、
アプリのアップロードは
curl \ -F "token=xxx" \ -F "file=@sample.apk" \ -F "message=sample" \ https://deploygate.com/api/users/_your_name_/apps
で出来ると書かれていますのでそれに従っています。
変数 APK_PATH にデバッグビルドで作られるアプリのパスを指定、
message に入れる文字列として変数 TIME, COMMIT_HASH を定義、
変数 USERNAME には deploygate のユーザー名を代入したあと、API を叩いています。
"message=Build by CircleCI <${COMMIT_HASH}> (${TIME})"
となっていますので、
「Build by CircleCI <02f18181> (2019/02/23 19:07)」のようなメッセージが付けられることになります。
メッセージに日時を入れているのは、
deploygate アプリからバージョン一覧を見たときに、どれが何か全然わからなかったためですね…。
↓ 入れないとこんな感じ
コミットメッセージを入れようかとも思いましたが、
コミットメッセージに特殊文字が含まれる場合に curl が失敗しないよう
処理を考えなくては…なので今回はやりませんでした。
5. deploygate API Key の指定
さて、上のコマンドで "token=${DG_API_KEY}" となっている箇所がありました。
ここの変数にどうやって値を入れているかの話をします。
CircleCI には、設定画面からプロジェクトごと、もしくは Context ごとに環境変数を設定できるようになっています。
今回はそれの後者、Context を使った環境変数の設定をおこなっています。
参考 : https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-context
以下の画像のように、「SETTINGS」の「Contexts」へと進みます。
右上に「Create Context」のボタンがあると思いますので、それを押して Context の新規作成をします。
Name はわかりやすく「deploygate」としておきましょう。
すると、以下の画面が出ますので「Add Environment Variable」ボタンから環境変数の追加をおこないます。
入力画面が出たら、Nameに「DG_API_KEY」、Valueに deploygate の API キーを入力します。
API キーは https://deploygate.com/settings の下の方に書かれています。
この設定を完了させたことにより、
(2. で説明を省きました) context: deploygate のコンフィグにより、
deploy job の実行時にいま設定した環境変数が読み込まれるようになります。
これで、 deploygate へ Android アプリを永遠にアップロードすることができる
CircleCI config が完成しました! おつかれさまです!!
6. 異なる証明書で署名されたアプリと言われないために
これで一件落着かと思いきや罠があります。
異なる証明書で署名されたアプリ (バージョン 1.0=1) が既にインストールされています。新しいアプリをインストールする前に、一度アンインストールしてください。
と、アンインストールが毎回求められてしまうことが発生します。
なんで起きるかというと、デバッグビルドの署名は通常 ~/.android/debug.keystore
にある証明書が使われるのですが、
CircleCI が使う Docker イメージが毎回異なるため、署名に使う証明書も一致しないのです。
ということで、 デバッグビルドに使う証明書を指定しましょう!!
まずはプロジェクトのルートディレクトリにて以下のコマンドを実行します。
keytool -v -genkey -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US" -keyalg RSA -validity 36500
これで 36500 日(およそ100年)有効の証明書が作成できます。
次に app ディレクトリの build.gradle.kts
に以下のような設定が含まれるよう修正します。
参照: https://github.com/nekonenene/grpc_android_client/blob/master/app/build.gradle.kts
android { // 中略 signingConfigs { getByName("debug") { storeFile = rootProject.file("debug.keystore") storePassword = "android" keyAlias = "androiddebugkey" keyPassword = "android" } } buildTypes { getByName("debug") { isMinifyEnabled = false signingConfig = signingConfigs.getByName("debug") } } }
Gradle Kotlin DSL を使わない場合の書き方は異なります。公式のドキュメントなどを参照してください。
storePassword, keyAlias, keyPassword は、さっきのコマンドで指定した値(-storepass android -alias androiddebugkey -keypass android
)と一致するように気を付けてください。
これにより、デバッグビルド時に、プロジェクトのルートディレクトリに作った
debug.keystore
が毎回使われ、同一の証明書による署名となってくれるため、
deploygate にアンインストールが毎回求められる問題はなくなります。
7. おしまい
しっかり書いたらけっこう長くなりましたが、以上!
Android アプリを deploygate にデプロイし続ける方法でしたー!
異なる証明書で署名されたアプリ 問題は、昔「毎回アンインストールはめんどいな〜」って思いながらも
しぶしぶやっていましたが、今回調べたらちゃんと対処法が発見できてよかったです。
DroidKaigi 2018 のアプリ もよく見ると、
debug.keystore がトップディレクトリに置いてありますね。なるほどなー。
らくらく実機テストをして、楽しいアンドロイド開発ライフをお過ごしください!
AndroidのgRPCクライアントをKotlinで実装しました
このあいだの記事では、Go 言語による gRPC サーバーの実装を完了させました。
また、 Go 言語によるクライアント実装についても触れました。
実運用としてクライアント(データの受け取り手)となるものは、Web の他に、
Android や iOS などのスマートフォンであることが多いかと思います。
というわけで、今回は、Android の gRPC クライアントを Kotlin で実装してみました。
1. 参考
以下が特に参考になりました。
- 公式のチュートリアル: https://grpc.io/docs/tutorials/basic/android.html
- Android の実装例: https://github.com/grpc/grpc-java/tree/v1.18.0/examples/android/helloworld
- protobuf-gradle-plugin の README: https://github.com/google/protobuf-gradle-plugin
また、出来上がりがこちらですので、
このあとの説明は、このコードを見ながらだとわかりやすいと思います。
2. proto を ビルドするための gradle の設定
最近は build.gradle
を Groovy でなく Kotlin で書くことも流行っている気配なので Kotlin で書きました。
……が、そこまで大きなメリットがあるわけではなく、
少数派の書き方となってしまい情報が得づらくなるので、Android 開発に慣れていなければあまりオススメできません。
基本的には app ディレクトリ以下の build.gradle.kts
を編集すれば良く、
grpc-java リポジトリにある実装例の build.gradle
を、Kotlin 向けに書き直して以下のようにしました。
import com.google.protobuf.gradle.* import org.jetbrains.kotlin.config.KotlinCompilerVersion plugins { id("com.android.application") kotlin("android") kotlin("android.extensions") id("com.google.protobuf") version "0.8.8" } val grpcVersion = "1.18.0" val protocVersion = "3.6.1" android { compileSdkVersion(28) defaultConfig { applicationId = "net.hatone.hello_grpc" minSdkVersion(21) targetSdkVersion(28) versionCode = 1 versionName = "1.0" testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner" } buildTypes { getByName("debug") { isMinifyEnabled = false } getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation(kotlin("stdlib-jdk8", KotlinCompilerVersion.VERSION)) implementation("com.android.support:appcompat-v7:28.0.0") implementation("com.android.support.constraint:constraint-layout:1.1.3") // Test testImplementation("junit:junit:4.12") androidTestImplementation("com.android.support.test:runner:1.0.2") androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.2") // gRPC implementation("io.grpc:grpc-okhttp:$grpcVersion") implementation("io.grpc:grpc-protobuf-lite:$grpcVersion") implementation("io.grpc:grpc-stub:$grpcVersion") implementation("javax.annotation:javax.annotation-api:1.3.2") } protobuf { protoc { artifact = "com.google.protobuf:protoc:$protocVersion" } plugins { id("javalite") { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" } id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:$grpcVersion" } } generateProtoTasks { all().forEach { it.plugins { id("javalite") id("grpc") { option("lite") } } } } }
https://github.com/nekonenene/grpc_android_client/blob/master/app/build.gradle.kts
ポイントは、plugins
ブロックにある id("com.google.protobuf") version "0.8.8"
です。
これにより、 protobuf-gradle-plugin が依存関係となり、
protobuf
ブロックの使用が可能になっています。
なお、『API 'variant.getJavaCompile()' is obsolete and has been replaced with 'variant.getJavaCompileProvider()'.』という Warning がビルド時に出ますが、
おそらくこれは protobuf-gradle-plugin の問題によるもので、近い将来解決されるでしょう。
proto ファイルは app/src/main/proto
ディレクトリ以下に置きます。
それ以外のディレクトリに置きたい場合は、 sourceSets
ブロックに定義を書きましょう。
(参考: https://github.com/google/protobuf-gradle-plugin#customizing-source-directories )
ビルドに成功すると、以下のように generatedJava フォルダの下に、
proto ファイルの定義に従って Java のクラスやインターフェイスが作られたことが確認できます。
generatedJava は便宜上のフォルダで、実際は
GreeterGrpc.java
は app/build/generated/source/proto/debug/grpc/io/grpc/examples/hello/
ディレクトリ下、
HelloProto.java
などは app/build/generated/source/proto/debug/javalite/io/grpc/examples/hello/
ディレクトリ下に作られていました。
3. gRPC 通信をおこなう
これもまた、grpc-java リポジトリにある実装例の HelloworldActivity.java
を Kotlin 向けに書き直せばいけます。
……が、このままだとさすがに汚いので、このコードで言うところの GrpcTask クラスは別ファイルに分け、
また、callback を設定し、Activity と疎結合になるようにしました。
やっていることとしては非常に単純で、
val channel = ManagedChannelBuilder .forAddress("grpc-test.hatone.net", 443) .useTransportSecurity() .build() val stub = GreeterGrpc.newBlockingStub(channel) val request = HelloRequest.newBuilder() .setName("Nanako") .setAge(75) .build() val reply: HelloReply = stub.sayHello(request) reply.message
このような書き方で簡単にレスポンスを取得できてしまいます。
GreeterGrpc クラスなどが自動生成されてくれるおかげで楽ができるのです。
SSL/TLS 通信をおこなうので、ManagedChannel 作成の際に
usePlaintext()
でなく useTransportSecurity()
メソッドを使うようになっている点にご注意ください。
また、インターネット通信をおこなうので、 AndroidManifest.xml
に
<uses-permission android:name="android.permission.INTERNET" />
の1行を追加しておくことを忘れないようにしてください。
4. おわりに
もうちょっと書くことがある気もするんですが、ブログにしてみると意外とこんなものでした。
proto ファイルは今回は gRPC サーバー側の hello.proto
を単純にコピーしてきましたが、
同一である必要があるので、別リポジトリを作って管理し、
submodule として各々が最新を引っ張ってくる作りにしておくと良いと思います。
久しぶりに Android アプリのコードを書いたので何度か悩みましたが、
それなりにきれいな実装に出来たと思うのでよかったです。
今回は AsyncTask を使いましたが、 RxJava(RxKotlin)も使ってみたいですね!