シンギュラリティソサイエティでは、代表の中島が NounsDAO 1 のNouner 2 になってから、Web3のブームが来ています。某国産DAOの話題から、エンジニアがそのDAOのSmart Contract 3 のソースを Etherscan 4 上で確認したことを発端に、スマートコントラクトの仕組みへの話題に発展しました。
(専門用語が多いので文末に用語解説を掲載しました)
有本 :XXXX DAOは結構ひどいかも。 XXXXDAO.solが、オリジナルのソースだと思いますが、Web上に
1人1つまでしかmint5 できない制限 と書かれている機能、これは特に制限が実装されてなさそうです。ソースの // public functions 以下が、外から呼べるapiですが、onSaleの場合、だれでも、いくつでもmintできるような実装になっています。
B氏 :そうなんですね… XXXX DAOでお試しの投票があったので体験してきました。 snapshot 6 のサイト上で投票します。
- snapshot へアクセス
- Wallet 接続
- 投票する
- Wallet で 3 の投票で良いかの承認をする
- snapshot で投票結果が見れる
- おそらく、投票締切時刻まで投票選択肢の変更は可能 (選択肢を変更できることが確認済み)
B氏 :投票権は一人一票で設定されている。投票のたびに ETH 7 とかはかからない。
有本 :投票自体は、ベースとなる Compound 8 のスマートコントラクトをそのまま使っているのですかね。ここはまだソースをみてないですが、オンチェーン上で投票するならETHがかかるはずなので(ブロックチューンに書き込むから)どういう仕組なのでしょうね。別件のNFT回りの調査が終わったらCompoundのソースも見てみたいと思います。
B氏 :全ては設計・実装次第なんですね。投票に GAS代9 が必要なのかどうかも含めて。
有本 :はい、基本は Solidity 10 で書かれたプログラムをオンチェーンで EVM 11 を使って動かしているので如何様にも改良可能です。GAS代については、計算量やブロックへの書き込みで決まります。なので、基本的に投票はGAS代がかかるはずなのですよね。なにかCompoundが裏技をつかっているか、もしくはそこのコミュニティーでの投票がETHを使うのではなくWebで行われているかのどちらかです。
B氏 :このWeb サイトが Snapshot というサイトでした。よく見ると、オープンな場での投票でした(www)
有本 :投票時に署名をして、会員か確認するWebサービスですね。
B氏 :XXXX DAOのコミュニティでは、多種多様な人がいらっしゃるので DAO を運営するために、運営者(サポートする人)が必須だと感じました。
うっかりDM でやりとりしてWallet 盗まれる人
手順を読まずにヘルプに問い合わせをする人
などなど。
有本 :これは、オンラインサロンでも同じで、基本はコミュニティー運営ですよね。中島さんの参加しているNounsDAOの話を聞いてもそう思います。
B氏 :大規模コミュニティ & DAO というのがまだ想像でていないんですよね…。どこかの段階で階級社会が出来上がって、それは DAO と呼べるのか?という疑問が拭えません。
- 行動する人
- 発言する人
- 文句だけ言う人
- 見ているだけの人
- 所属だけしている人
有本 :株式会社や政府などの仕組みと比較してDAOといっているだけ、結局は人間が意思決定するので、DAOでも社会の縮図 になると思います。 分散で、自立している人は、組織に属さないか、組織のTOPになるわけで…。 だた、投票や会計が機械化されてオープン になるので、そこがポイントかと。DAOの投票ですらアルゴリズムなので、代表権のある人に権力を集中させるといった仕組みも可能です。(これはDAOというよりはSolidity上でのプログラム、といったほうがよいのかな)
B氏 :そうなんですね。 Solidity は一度決めたプログラムを変更することは可能なのでしょうか?DAO 内の投票でプログラムの変更が可決したら… みたいなイメージです。現実世界でも新たに法律を制定したり、廃止したりするのでそれもできるのかなぁと思った次第です。
有本 :プログラムの変更はできません。しかし、動作を変えることはできます。Solidityはコントラクトという単位でデプロイします。コントラクトは他のコントラクトを呼び出すことができるのですが(コントラクト=クラスインスタンスと考えればよいかな)、呼び出し先のコントラクトを変更することが可能です。なので、そのように作れば、いくらでもプログラムの動作を変更することは可能です。 よって、誰かが作ったコントラクトを使う場合には、ソースをすべて見ておく必要があります。投票結果を書き換えることも可能ですね。しかし、書き換えられたとしても、それをログで追うことは可能です。そのコントラクト自体が古くなった場合には、selfdestruct12 を呼び出して削除して違うバージョンをデプロイして使うことになります。 こういった仕組みがあり、また、コントラクトやそのPublicな関数の呼び出しは誰でもできるので、きちんと実装しておかないと、勝手にmintしたりtransfer13 される可能性もあります。Solidityを実装する上でセキュリティが最も重要です。次にバグを発生させないこと。バグがあっても修正できません。
B氏 :ありがとうございます!バグがあったら、「selfdestructして削除して違うバージョンをデプロイして使うとなります。」をすれば新しいバージョンを利用可能なのでしょうか。それとも、根幹となる部分はどんな方法でも修正不可なのでしょうか。セキュリティの考え方ガラッと変わる印象です。
- 間違いなく実装することが重要
- 反面、リリース後の対応は従来に比べて減る?
有本 :一般的なプログラムで例えると、
- コントラクト=クラス
- オンチェーン上のコントラクタ=クラスインスタンス
- コンストラクタのアドレス=クラスインスタンスのポインター
- コンストラクタのブロックチェーン上の変数=インスタンス変数
例えば、NFTをmintするのは、クラスインスタンスのmintメソッドを呼び出す。これを前提としてクラスインスタンスは、いかなる操作でもそれ自身の変更はできない。デプロイ(インスタンス化)したら、変更は不可で、削除だけはできる。 インスタンス変数は、インスタンスのメソッド経由で変更可能。例えばmintしたらtokenIdをインクリメントしてtokenIdを管理するのは、この仕組を使っている。 クラスインスタンスから、別のクラスインスタンスを呼び出すことは可能。これは、相手のポインタを定数、もしくはインスタンス変数として持っていて、そのポインタを呼び出す。この仕組みを使って、呼び出し先の相手のポインターを書き換えるメソッドを用意すれば、呼び出し先のクラスインスタンスを変更することが可能。しかし、クラスインスタンス自体の仕組みは変えられないので、ここに問題がある場合はクラスインスタンスを削除する必要がある。ただし、作り変えた場合は、クラスインスタンスのポインタ(アドレス)は変わるので、そのクラスインスタンスを呼び出すクライアント全部に新しいアドレスを広告する14 必要がある。
有本 : 根幹となる部分はどんな方法でも修正不可です。
有本 :selfdestructして、コントラクトを新しくした場合は、新しいコントラクトのアドレスを利用者全員に伝える必要があります。なので、正式にリリースする前のテストや検証は超重要です。試しにデプロイして後で変えていく、というのはしづらいです。 逆に言うと、世にあるNFTで、自前でSolidityを書いてもるものは穴がある可能性があるので、暇なら、それを見ていくと、いたずらができるかもしれません。クラスインスタンスのpublicなメソッドは誰でも呼び出せるので。
B氏 :なるほど。ありがとうございました! 現実世界に似た感じになりますね。(憲法、法律みたいです)憲法・法律が変わる時に徹底した周知が必要なところも。
有本 :確かにそうですね! OpenZeppelin15 のreferenceなどは、Web3の憲法みたいなもなので、ここに穴があると大混乱でしょうね。 クリプトゾンビ16 を一通り終わらせれば、これくらいの理解になるので、プログラムを仕事にしている人は必ず、すぐにやりましょう!
B氏 : クリプトゾンビやります!
有本 :これくらいの理解がない人がNFT、Web3、DAOといっていたら、詐欺師だと思って良いですね。
B氏 :詐欺師か、知ったかか、後で直せば良いんでしょと思ってリリースして後悔するか…
有本 :この前も、中島さんかな、twitterでシェアされていたもので、どこかのSolidityでバグが有って数億円が引き出せなくなった、、という記事がありました。 また、NFTはコンテンツが書き換えられない、と言っていますが、ソースやデータを良く見ると、コンテンツのurlが普通のWebだったり、storageのurlが実は書き換えられるようになっている可能性があるので注意です。NFTはコンテンツを書き換えできないように作れるけど、それが必須ではないです。
<用語解説>
Footnotes
-
NounsDAO: DAO(分散型自律組織)のひとつです。DAOは2014年頃登場した概念で、従来の株式会社と違い、意思決定には参加者同士の投票がおこなわれます。DAOの意思決定にはトークンがいりますが、透明性が高く誰でも参加することができます。 ↩
-
Nouner: Noun (NFT: ガバナンス・トークン) を保持し、意思決定に関われる参加者のこと。 ↩
-
Smart Contract: スマートコントラクトとは、あらかじめプログラムで書かれた契約/取引をブロックチェーン上で自動で実行する仕組みです。この概念は、1990年にコンピューター科学者、法学者、暗号研究者であるNick Szabo氏によって考案されました。 ↩
-
Etherscan: 暗号通貨であるEthereumのトランザクション(取引)を確認することができるWebサイトです。 ↩
-
mint: NFTを発行すること。 ↩
-
snapshot: Web3技術を活用したWeb 上の投票サービス。 ↩
-
ETH : Ethereumの単位。 ↩
-
Compound: Ethereum上につくられたDAO。 ↩
-
GAS: Ethereumの取引手数料。 ↩
-
Solidity: スマートコントラクトを記述するための手続き型プログラミング言語。 ↩
-
EVM: スマートコントラクトの展開と実行をこなう、Ethereumの仮想マシンのこと。 ↩
-
selfdestruct: コントラクトを削除する関数。 ↩
-
transfer: 仮想通貨の送金やNFTを送信すること。 ↩
-
広告する: 配信すること。(ブロードキャストのようなイメージ) ↩
-
OpenZeppelin: Ethereum上で安全なスマートコントラクを実装するためのライブラリです。 ↩
-
クリプトゾンビ: CryptoZombiesは、Solidityでスマートコントラクトの構築を学習できるWebサイトです。ゾンビを作りながらゲーム感覚で学べます。 ↩