ユーニックス総合研究所

  • home
  • archives
  • smart-contruct-danger

スマートコントラクトの危険性とは【バグを修正したい】

スマートコントラクトの危険性とは

昨今、Webや社会を賑わしているのは「ビットコイン」だ。
ビットコインの技術は革命と言われている。

ビットコインに追従するように新たな仮想通貨(トークン)が生まれている。
そしてちまたにはビットコインによる億万長者も多数生まれ続けている。

ビットコインといえば「ビットコイン」、それから「イーサ」だ。
イーサは「イーサリアム」というプラットフォームで利用されるトークンだ。

そしてイーサリアム上ではDApps(分散型アプリ)という次世代アプリの開発が行われている。
DAppsでは「スマートコントラクト」というイーサリアム上で実行できるプログラムを扱う。

今回はこのスマートコントラクトの危険性について考えてみたいと思う。

関連記事

スマートコントラクトの危険性とは【バグを修正したい】

イーサリアムとは?

仮想通貨「イーサ」を流通させているのは「イーサリアム」というプラットフォームだ。
イーサリアムは分散型アプリ(DApps)やスマートコントラクトを実行するプラットフォーム、つまりOSみたいなものとして開発されている。

イーサの値段が上がっているのはつまりイーサリアムに対する期待がそれだけ大きいことを意味する。
イーサとイーサリアムの関係は密接である。

イーサリアムのシェアを奪おうとしている他のプラットフォームもある。
それらは「イーサリアムキラー」と呼ばれている。

ではイーサリアムで実行できる分散型アプリ「DApps」や「スマートコントラクト」とは一体何なのか?
これらがあると何が嬉しいのか?

分散型アプリ「DApps」の必要性

分散型アプリとは一体どういうものなのか?
これについて知るには従来のアプリについて知っておく必要がある。

従来のWebアプリはいわゆる「クライアント・サーバー型」の通信モデルを使っている。
これらのWebは「Web2.0」と言われている。

いっぽうDAppsは「P2P型」の通信モデルを使っている。
これらのWebは「Web3.0」と言われる。

クライアント・サーバー型の通信

クライアント・サーバー型のアプリは、中央にサーバーと呼ばれるパソコンを配置する。
そしてその周りにはクライアントと呼ばれるパソコンが複数存在する。

クライアントはサーバーに「データをくれ」という要求を送る。
サーバーはクライアントの要求にこたえてデータを送る。
つまりクライアントがサーバーに「このブログのこの記事を送って」と送るわけである。
サーバーはそのブログの記事のデータをクライアントに送る。

これがクライアント・サーバー型の通信モデルだ。

P2P型の通信

いっぽうP2Pは、「ノード」と呼ばれるパソコンが無数に存在する。
ノードは他のノードとデータを「相互に」やり取りする。

世界中のノードと相互にデータをやり取りして「P2Pネットワーク」というネットワークを構築する。
これがP2P型の通信モデルだ。

P2Pの特徴

クライアント・サーバー型は中央のサーバーがダウンすると、周りにいるクライアントはデータを取得できなくなる。
たとえばAmazonがダウンしたら買い物が出来なくなるのと同じだ。

いっぽうP2P型は1つや2つのノードがダウンしてもP2Pネットワークは維持される。
ネットワークを通じてデータを取得することができるので、買い物が出来なくなるということがない。
P2Pはこのため「ゼロダウンタイム(一度稼働したら稼働し続ける)」と言われている。

ビットコインもブロックチェーンを通じてP2Pを使っているが、ビットコインはすでに10年以上稼働を続けている。

ブロックチェーンの存在

イーサリアムなどのプラットフォームは「ブロックチェーン」と呼ばれる技術を使っている。
ブロックチェーンはP2Pを使って成り立っている。
ブロックチェーンはビットコインを実現するために開発された技術だ。

つまり関係的には

  • DAppsはプラットフォーム上(イーサリアムなど)で稼働して
  • プラットフォームはブロックチェーンを使っていて
  • ブロックチェーンはP2Pを使っている

という関係になる。

ではブロックチェーンとは何なのか?
ブロックチェーンとは「取引履歴を保存する仕組み」のことを言う。

ブロックチェーンではP2Pで繋がる各ノードが同じデータベースを持っている。
そしてデータベースには「ブロック」と呼ばれる履歴が保存される。

ブロックはチェーンのように繋がっている。
この様子を指してブロックチェーンと呼ばれる。

ブロックは新たに追加することはできる。
しかしブロックチェーンでは追加したブロックは削除・変更することができない。
よって改ざんも極めて難しい。

スマートコントラクトとブロックチェーン

スマートコントラクト」はブロックチェーン上の取引を自動化するプログラムのことを言う。
これはイーサリアムでは「Solidity」などの専用プログラミング言語で書かれている。

プログラマーによって書かれたスマートコントラクトはコンパイル(バイトコードに変換)され、イーサリアムのP2Pネットワークに送られる。
イーサリアムのネットワークには「マイナー(採掘者)」と呼ばれるノードが無数に参加している。
マイナーはトークン(仮想通貨)による報酬(Gas)と引き換えに、CPUパワーを提供している。
CPUパワーは新しいブロックの書き込みに使われる。

ブロックの書き込みではコンセンサスアルゴリズム(合意形成)が使われる。
たとえば「PoW」というアルゴリズムでは、マイナーに計算を競争させて、競争に勝利したマイナーにブロックを書き込ませて報酬を与える。
これによってマイナーは自発的に計算を行ってくれる。

スマートコントラクトのプログラムはマイナーによって、イーサリアムのブロックチェーンに書き込まれる。
これはどういうことかと言うと、一度ブロックチェーンに書き込まれたスマートコントラクトは、削除も変更も出来ないということになる。

DAppsとスマートコントラクト

DAppsはブロックチェーン上に存在するスマートコントラクトを実行するアプリケーションである。
なぜこれが分散型アプリと呼ばれるのかと言うと、スマートコントラクトのプログラムがブロックチェーン上に存在するからである。

スマートコントラクトのプログラムはブロックチェーン上から取得されて実行される。
イーサリアムでは「EVM(Etherium Virtual Machine)」という仮想マシンがあり、これでプログラムが実行される。

つまりスマートコントラクトの実行はイーサリアムのネットワークが生きていれば行えるということになる。
このため一度ブロックチェーンに登録されたスマートコントラクトはゼロダウンタイムで稼働し続ける(いつでも実行可能になる)ことになる。

DApps自体は既存の技術で作られることも多い。
たとえばReactやVueでフロントエンド部分を書き、そこからAPIを通じてスマートコントラクトを実行する、といった具合だ。

スマートコントラクトの透明性

ブロックチェーンのデータベースは各ノード上に存在する。
そのためネットワークに参加していれば、だれでもデータベースの中身を見ることができる。

スマートコントラクトのプログラムはコンパイルされてブロックチェーンに書き込まれるが、この時ソースコードも一緒に書き込まれる。
つまりスマートコントラクトのソースコードは誰でも確認することが出来るということになる。

特定のスマートコントラクトのソースコードの確認はイーサリアムであれば「Ethereum (ETH) Blockchain Explorer」から行うことが出来る。

たとえば「Ruletka」というロシアンルーレットゲームのスマートコントラクトは↓から見ることができる。

ちなみにエクスプローラーではソースコードの他にアドレスの履歴を見ることも出来る。
アドレスとは仮想通貨の口座番号みたいなもので、仮想通貨の取引ではこのアドレスで取引を行う。

自分のアドレスで調べてみると履歴が表示されるだろう。
ちなみにそのアドレスがどれぐらいトークンを持っているのかもわかる。
(ということはつまりアドレスを他人に教えるということは、そのアドレスで管理している仮想通貨資産がいくらあるか公開することになるわけだ)

DAppsは非中央集権的でパブリックである

DAppsはスマートコントラクトが世界に公開されており、スマートコントラクト自体は中央集権的なサーバーも必要としない。
そのため従来の大企業のサービスを個人が利用するという形態から離れて、あくまで「個人対個人」のやり取りが可能になる。

このため企業に管理されることそれからソースコードが不透明なことを嫌う人たちに大変人気が出ると予測される。

スマートコントラクトの危険性とは?

スマートコントラクトの危険性については開発者視点とユーザー視点があるが、まずは開発者視点の話をする。

スマートコントラクトは性質上、↓の特徴を持つ。

  • ソースコードが公開される
  • バイトコードの変更・削除ができない

この内、ソースコードが公開されるのは別に問題ない(問題あることもあるけど)。
これはプログラムの透明性と言う意味において場合によっては必要なことと認識している。
さっこんのOSSが流行っているのもこれのためである。

問題は「バイトコードの変更・削除ができない」という点だ。

バグをフィックス(修正)できない

ブロックチェーンに登録したスマートコントラクトのバイトコードは、バグをフィックスできない。
バイトコードを変更できないからだ。

よって、基本的にはバグが無いと言える状態でリリースしなければならない。
あるいはSolidityなどではSelf-Destructというスマートコントラクトの停止処理が行えるので、これをあらかじめソースコードに組み込んでおいて、問題があったら停止する、という風にする。

だがバグをフィックスできないというのは、たいへん開発難易度が上がる。

バグのないプログラムを作るのは可能か?

バグの無いプログラムは、不可能ではないが私の経験からするとほぼ不可能に近い。
つまり、バグのないスマートコントラクトを作るのは、よほどコードが小さくなければほぼ不可能だと思える。

よってスマートコントラクトのコード量を減らして、ほかのブロックチェーンに登録していないコードを増やすというのが自然解になる。
だがそうすると不透明なコードが増えて、分散的な実行範囲が減る。
つまり分散型アプリの意味が薄れる。

バグのないプログラムを作るには、コードを極力シンプルにする必要がある。
複雑なコードにはほぼバグが入るからだ。

バグが無いことを保証するにはテストを書く必要がある。
だがテストも完全ではなく、テスト漏れがあった場合はそこからバグが入る。

バグのあるスマートコントラクトが稼働を続けたら?

Self-Destructなども行えないバグのあるスマートコントラクトがブロックチェーン上で稼働を続けることになると、何が起こるのか?
これは未知的でよくわからない。

私が思うより問題になるケースは少ないのかもしれない。
でもバグがやばいバグだったらちょっとゾッとするよね。

🦝 < ゾッとするで済めばいいけど

🐭 < これから歴史が証明してくれるよ

バージョンアップ可能なスマートコントラクトの開発

この危険性への対策の1つに「プロキシ・コントラクト」というのがよく知られている。
プロキシ・コントラクトを使うと、スマート・コントラクトのバージョンアップが疑似的に可能になる。

プロキシとは「代理」という意味だ。
つまり代理のコントラクトを1つ用意する。
そしてその代理のコントラクトから実際のコントラクトを呼び出す。

代理のコントラクトの呼び出すコントラクトのアドレスを変えれば、呼び出す実装を変えることができる、というものだ。
バージョンアップをする場合は代理コントラクトの持っている呼び出すコントラクトのアドレスを更新する。

しかしこれも代理コントラクトから呼び出せる関数などは、変更できない(たぶん)。
呼び出すコントラクト側でどうにかするしかない。
また呼び出すコントラクトも、古いバージョンのSelf-Destructは必要になる。

つまり根本的にはバグの問題はずっと残る。

DApps(スマートコントラクト)への投稿データはどうなるの?

これはユーザー視点の話になる。
スマートコントラクトに投稿されるデータは、コードによってはスマートコントラクトが保持する仕組みになっている。

ここら辺はまだ確認していないが、投稿の履歴はブロックチェーンに残るらしい。
たとえばメッセージを投稿したとする。
これは文字列で「こんにちは」とか「さようなら」とか、そういうメッセージだ。

このメッセージはブロックチェーンにデータとして残るのだろうか?
つまりエクスプローラから「こんにちは」とか「さようなら」というメッセージを見れるのか? ということだ。

仮にそうだとしたら、当然問題は起こるだろう。
投稿した変なメッセージが永遠に残ってしまうなら大問題だ。

消せないし、アドレスと一緒にメッセージ内容も残る。
もしこういう仕様だとしたら使うのはちょっとためらってしまう。

人間、なにかのはずみで変なメッセージを送ることは誰にでもある。
それが消えずに残るというのは、非情な話である。

🦝 < ここら辺は未確認の話

🐭 < 自分で確認してね

おわりに

今回はスマートコントラクトの危険性について考えてみた。
分散型アプリはWeb3.0で主流となっていくと一部で予想されている。

しかし、バイトコードを修正できないという根本的な問題はずっと残ることになる。
(もっともこれは問題ではなくメリットであると捉える人もいる)
この問題を開発者の皆さんがどう考えるかである。

私は今のところ、スマートコントラクトの開発には慎重になっている。
もう少し調べて納得してから開発したい。

🦝 < 分散型アプリは果たして流行るのか?

🐭 < それは未知数