ALISのICOについての技術的FAQ

ALIS
ALIS
Oct 29, 2017 · 16 min read
Image for post
Image for post

こんにちは、ALIS CTOの石井です。

みなさまに応援していただき、ALISのICOは目標額の3.5億円を超える約4億円を調達できました。ありがとうございます。ICOにはEthereumを利用していますが、Ethereum上に構築したICO用スマートコントラクトについて多くの方から技術的な質問をいただいております。
せっかくなので、こちらにまとめます。

前提

Contractのコードを書く時に参考にしているもの(サイトや書籍など)を教えていただきたいです

GitHub上の良質なコードが一番参考になります

公式サイトは期待しない方がいい

  • メンテ不充分。

解説記事や本も参考程度にとどめる

  • 進歩がとてつもなく早いのですぐ古くなる。

暗号通貨の開発はバグがあると非常に危険であることが前提ですが、これならいける!という確証をどんな感じに持ちながら開発を進めているのか

「非常に危険」は、たしかにその通りです

  • 一例: 2017年7月、Parityというウォレットで 34億円 の被害が出たバグがこちらです。

ひとまずsmart-contract-best-practicesをすべて読み込む。
極めて優良なドキュメントです。スマートコントラクトを書くエンジニアは必読。日本語に翻訳中

以下の内容は上記のドキュメントに書かれていることでもありますが、具体例としていくつか記載します。

コードをシンプルに保つ

  • 本当に重要じゃないものは実装しない。コード書かないのが一番という場面は多々ある。

とにかくテストをみっちり書く

  • ALISのテストの内容はCircleCIで見られます。

徹底的にライブラリを使う

  • よくできたライブラリを使い、そこでできることは自前で実装しない。

外部の人間にみっちりレビューしてもらう

  • ALISの場合は10年超の経験を持つエンジニア5人に丸一日時間を作ってもらいレビューしてもらいました。

その他、いろいろ上記のベストプラクティスに記載があることを実施しました。それでも自分のバグ一つで億が飛ぶので、痺れますけどね。

テストコードが必須で重要だと思いますが、どのようなテストを書いておくべきですか?

できればカバレッジ100%目指したい

  • カバレッジが高いからって安心できるわけではないですが、それでも高いに越したことはない。

開発環境全般について。Contractのデプロイ先は開発環境(testrpcと)ステージングと本番、みたいな分けはありますか?

コードを書きテストを走らせるのはすべて testrpc

testrpcはテストを走らせるただけのものです。

挙動確認は基本的に gethで構築したプライベートネット

  • 速度という点でテストネットよりも圧倒的に有利。

みっちりプライベートネットでテストしたらメインネットで最終テスト

  • gasが高いので気軽にはできない。

私が実装していたタイミングでは公式のテストネット(ropsten)が攻撃を受けてて使い物にならなかった

  • 今は安定している(はず)。

AlisのContractにおいてはTruffleとZeppelnを採用していますが、どのような経緯でこれを選びましたか?

  • GitHub上で活発に開発が継続している良質なプロジェクトである。

リリース後に修正をカジュアルにしても良いものなのか

  • 答えはNoです。基本的には修正できません。

ICO以降、Contractのアップデートはどのような内容で行っていきますか?

  • ICO用のコントラクトはトークンとマルチシグウォレット以外は使い捨てです。アップデートしません。トークンとマルチシグウォレットもアップデートできる仕様ではありません。

極力Gas Feeを減らす工夫はどのように行いますか?

  • ICOでは考慮していません。する必要が無いからです。

マルチシグWalletの導入目的と導入方法を教えていただきたいです

EOAではプロジェクトとしてセキュアではないから導入しました。

  • 一人がミスしたらすべてが終わる。

private netとmain netの使い分けについて教えていただきたいです。private netは開発用?

切り分けは以下のとおりです

  • Main net: プロダクション環境、最終テストの環境

コントラクトにはGASの処理についてはどのようなことが書かれていますか?

  • 今回はコントラクト自体にはgasの処理は書いておりません。

solgraphは、コントラクトのソースコードを解釈してビジュアルにするものだと思いますが、これを見て誰が何を判断しますか?

開発者やQAを担う人が以下を確認しやすくなります。

危ないfunctionがどれか

  • 要注意なfunctionは画像では赤枠で囲まれます。

スコープが適切か

Ethereumのフルノード同期させているのはなぜでしょうか

運用上、もっともセキュアであろうと判断したからです。開発者はフルノードを使用しています。
非エンジニアはgethのlight clientモードを使用しています。

Zepplin内にMultisigWalletクラスがあると思うのですが、ALISのContractでは独自に実装されている(?)ようで、何か理由があるのでしょうか

最新のopenzeppelin-solidityのリポジトリを見ていただければと思うのですが、もうマルチシグウォレットはありません。
https://github.com/OpenZeppelin/openzeppelin-solidity

公式に ConsensSys(Gnosis)の方が良いよ と言って削除されました。
ALISではそちらを使用しています。
https://github.com/gnosis/MultiSigWallet

BurnableTokenはどういう目的で使われているのでしょうか。PoBの必要性があるのでしょうか

※この質問はburnが決定する前にいただきました。
※ALISでは自前でコントラクトを配置していますが、現在はopenzeppelin-solidityBurnableToken.solが実装されているのでそちらを使用すべきです

burnの機能は必須と考えています

これは技術的な話というよりも、いかに価値を凝縮させるか。あるいは希釈させるかの話です。
たとえば上限5億トークン、という立て付けでICOを実施します。ICO完了後に、運営が新たに自分たちのために10億トークン発行しました! と発表したらどうなるでしょう。非難轟々なはずです。
なぜならトークンの価値が希釈するからです。
たとえば5億トークンのときに100円の価値が付いてたとすれば、論理的には約33.3円まで価値が希釈されることとなります。(現実的にはいろいろな思惑があってぴったり3分の1とはなりませんが)

話を戻してトークンのburnですが、こちらは逆です。
5億トークンのICO完了後、運営が私たちは自分たちの1億トークンをburnしますと発表した場合を考えてみましょう。これはトークン保有者にとっては得するニュースです。
なぜならトークンの価値が凝縮するからです。
5億トークンの時に100円だった場合、論理的には125円まで価値が凝縮されることとなります。つまり持っているだけで得をするのです。

そしてburnの方法ですが、これはトークン自体にburnの機能を持たせるのがベストと判断しました。無効なアドレスに送信することで実質的にburnする、というアプローチも伝統的に用いられていますが、ERC20準拠トークンではトークンコントラクトのtotalSupplyで常に適切な量を確認できるべきなので、その場合はより適切なburn処理が必要となります。そのためALISトークンにはburnの処理を実装しています。

ブロックとUNIXTIMESTAMP両方使っているのはなぜですか

Ethereumの過渡期だからです。

Ethereumはそのロードマップで、合意形成アルゴリズムを現状のPoWからPoSへの移行を予定していますが、その過程のハードフォークで分裂が起こらないようにdifficulty bombという施策を施しています。これはマイニングのためのdifficultyが漸増するという内容です。

Image for post
Image for post

ALISのプロジェクトを開始した当時(2017/05)は、Ethereumのブロックで時間を計るというアプローチが有効でした。しかしdifficulty bombの影響で、時間の見積もりが困難となりました。またEthereumにはメトロポリス・ハードフォークも控えておりブロックによる見積もりは事実上不可能でした。
そのためUNIXTIMESTAMPも併用しています。

なぜ初めからUNIXTIMESTAMPを使用しないのかというと、Ethereumのマイナーに僅かながら不正の余地を与えるからです。
詳細はこちらを御覧ください。openzeppelin-solidityでちょうどv1.2.0からv1.3.0にかけて議論が行われ、ブロックタイムからUNIXTIMESTAMPへの切り替えが行われた際のものです。参考になるかと。

今からコントラクトを実装する場合、よほど要件がシビアでないかぎりUNIXTIMESTAMPを使用すべきです。

ICOの時にどのように信頼を得るようにしたか。開発コードを公開するケースがありますが公開していたか?

コードは最初からGitHub上ですべて公開していました。今後も可能な限りオープンソースでの開発に努める予定です。

ICO最中に攻撃やハックを受けたりしたかと思いますが、どのような種類の攻撃を受けてどのようにさばいたか知りたいです。

この観点では、わかりやすくするためスマートコントラクトWEBサイトに分けて回答いたします。

スマートコントラクト

ALISのICOでは、スマートコントラクトへの目立った攻撃はありませんでした。多少の悪意あるトランザクションは存在しますが、コントラクトの中身を考慮していない総当り的・機械的な攻撃であり脅威を感じるほどの内容ではありません。

しかし、スマートコントラクトが攻撃されるのは稀であると考えるのは早計です。一度攻撃が成功したら数億円というお金が手に入るので、むしろ徹底的に付け入るスキが無いか世界中のクラッカーから見られていると考えるべきでしょう。

事実、The DAOやParityなど、過去に何度もスマートコントラクトの脆弱性による数十億円規模の損害が発生しています。これらの攻撃は、どれもコントラクトの中身を入念に検証し実行されています。

ALISではそのような現状を鑑みて、徹底的に品質とセキュリティにこだわりスマートコントラクトを実装しました。そのため、一ヶ月以上に渡り数億円という金額がICO用コントラクト上に存在していましたが、クラッカーにそれを奪われることはありませんでした。

WEBサイト

イスラエルのスタートアップであるCoinDashは、ICO開始直後にWEBサイトをクラックされ8億円弱をクラッカーに奪取されました

ALISではこのような事態を想定し、WEBサイトはAWS S3上に完全に静的なページとして構築しています。これによりクラックのリスクは圧倒的に低減します。詳しくは以前のエントリーを参照してください。

ファイナライズ実施時にAlisTokenのfinishMinting()を行わない理由はなんでしょうか?

アプリケーションの仕様として将来的にmintする予定のためです。
ホワイトペーパーに記載のとおり、ALISのトークン設計では、年間のインフレ率を50%として設定しています(すべてがALISプラットフォーム上に保持されるわけではないため、実際には20%程度と見込んではいます)。これは新たにトークンをmintすることを意味します。mintされたトークンはコンテンツ作成者、評価者に分配されます。

余談になりますが、もしここでfinishMinting()を行った場合、ALISトークンは二度とmintできません。ここがスマートコントラクト、というよりブロックチェーンを扱う上で怖いところなのですが、設計をミスすると取り返しがつきません。この実装を入れていなければ、ホワイトペーパーで想定しているALISのメディアは極めて実現困難になっていたと言えます。これはALISのICOで使用したopenzeppelin-solidityの仕様なのですが、ミスを起こしやすい仕様ではありました。そのため、openzeppelin-solidityの後続のバージョンではfinalizeの処理からfinishMinting()が除却されました

ちなみに将来的にトークンをmintする必要が無い場合、むしろ積極的にmintできないよう実装すべきです。それは、このトークンはもう増えることが無い=mintによる価値の希釈は起こらないという信頼のブロックチェーン上での担保を意味するからです。

備考

  • ICOについて質問をいただいた場合はこちらに随時追記してゆきます。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store