こんにちは、@kojamamです。10日目の記事をを代わりに投稿させていただきます。
最近、Solidityによるスマートコントラクト開発の講義することがあったのですが、Web業界に浸っていた人が戸惑いがち、つまりがちなポイントが共通してあるなと思ったので書き留めておきます。
Webとブロックチェーンはかなり性質の異なる技術なので、これからブロックチェーンに触れ、スマートコントラクトを書き始める人のためになればうれしいです。
以下では特に断りがない限りPublicなEthereumネットワークの話をします。また感覚的に理解してほしいため、厳密性には欠ける部分があります。
言葉の対応
まず、簡単な対応表を書いておきたいと思います。厳密には一対一ではないですが、感覚的にはこんな感じです。
Web | Ethereum |
---|---|
クラス | コントラクト |
メンバ変数 | ステート変数 |
メソッド | メソッド |
リクエスト | トランザクション, コール |
戸惑いポイント
その1: アプリケーションサーバーがない
Webだとアプリケーションサーバーを立てて、そこにコードをデプロイして、アプリケーションが動くという一連の流れがあります。それに対し、EthereumのスマートコントラクトはEVMと呼ばれる「すべてのEthereumノードが構成するブロックチェーンネットワーク上に構成された単一のVM」上にデプロイされ動作するため、特定のサーバーで動くというわけではありません。つまり、スマートコントラクトを動作させるのに自前のサーバーを持っておく必要もありません。
このような特徴を持っているため、Ethereumは「ワールドコンピュータ」と呼ばれることもあります。
その2: デプロイ=インスタンス化
スマートコントラクトは"コントラクト"と言う単位でデプロイを行います。コントラクトはクラスのようなもので、変数やメソッドが含まれたまとまりです。
コントラクトは前項で説明したようにEVM上にデプロイされるわけですが、デプロイと同時にインスタンス化が行われ、コンストラクタが実行されます。デプロイされる度にコントラクトには固有のアドレスが発行され、永続化されます。
一つのコントラクトを複数インスタンス化するためにはインスタンス化する度にデプロイする必要があります。デプロイには多くのGas(手数料)を消費するのでむやみに行うものではありません。
その3: DBMSやファイルストレージはない
WebではアプリケーションがDBMSとやり取りをし、データを処理をするというのが一般的です。しかし、スマートコントラクトはそのようなことは出来ません。1
コントラクトのインスタンスは永続化されているため、ステート変数(メンバ変数のようなもの)にデータを保持しておくことになります。データを保存する度にGasがかかるため、その辺も考慮しておきましょう。
ファイルストレージもないので必要ならば別に用意する必要があります。2
その4: リクエストには2種類ある
コントラクトに対するリクエストには2種類あります。
一つ目は"トランザクション"といい、コントラクトの状態を変更する、つまりマイナーに処理を行ってもらいチェーンにデータを書き込むリクエストです。これはEthereumに限った話ではありませんが、チェーンにデータを書き込むトランザクションにはGasがかかります。
二つ目は"コール"といい、コントラクトの情報を読み取るリクエストです。こちらは書き込みが発生しないのでGasはかからず実行できます。なお、状態を変更が必要なメソッドをコールで呼び出すことは出来ません。
コールとトランザクションを区別してコントラクトを設計しましょう。
その5: アップデートや停止はできない
スマートコントラクトは一度デプロイするとEVM上で自律的に動作します。開発者のサーバーで動いているものではありません。これがどういうことを意味するかというと、デプロイされたコントラクトは開発者の手を離れてしまい、アップデートや停止といった操作はできません。
ブロックチェーンは過去の履歴を改竄されないことがその特徴なので、一度デプロイされてチェーンに書き込まれたものを書き換えることが出来ないのです。
アップデートしたい場合は別インスタンス、別アドレスとしてデプロイし直す必要があります。この場合も以前のコントラクトは消えません。
その6: コントラクトの内容はすべて公開される
コントラクトへのトランザクションがEVMで実行されるにはすべてのマイナーがその内容を取得できなければなりません。ですのでコントラクトに書いたメソッド、変数などは全世界に公開されます。公開されていることでトランザクションの処理と証明が行えるのです。
外に漏らしてはいけない機密情報をコントラクトに保存するのは避けましょう。
その7: 乱数は作れない
コントラクトでは基本的に乱数を作ることは出来ません3。すべてのマイナーでトランザクションの実行結果が同じにならないといけないので不確定の要素は含めることは出来ないのです。
その8: 時間とカネがかかる
先程からGasを消費するというという話をしてきましたが、トランザクションの実行には必ずGasと呼ばれる手数料がかかります。GasはEtherで支払うので結果的に現実のお金を消費することになります。基本的にはトランザクションの送信元ユーザーに手数料を毎回負担してもらうことになります。
また、各トランザクションはその承認を待たないといけないため、処理に時間がかかります。通常のWebアプリケーションのように即時処理をするのは不可能です。
まとめ
以上となります。思いついたものを書いたため、不足もあるかもしれませんがWebとはだいぶ違うんだなと言うことが分かっていただけたかなと思います。
ブロックチェーンエンジニアが増えていって情報もどんどん増えていってくれればれしいです。