Solidity コントラクトの書き方 | 初心者向き

今日は、ブロックチェーンのEthereum (イーサレアム)上でスマートコントラクトを開発するための言語Solidityでのコントラクトの書き方について、初心者の方向けに簡単に解説したいと思います。SolidityはJavaScriptにそっくりですので、JavaScript経験者も楽しめると思います。Solidityの説明に入る前に改めて、ブロックチェーン、スマートコントラクト、分散型アプリケーションについて説明したいと思います。

ブロックチェーンって何

ブロックチェーンは、多数のサーバ(ブロックと呼ばれます)で常に過去から現在に至るまでの記録を共有することで改ざんを防ぐ仕組みを言います。過去から現在に至るまでの記録がチェーンのように繋がっており、そのチェーン全体を分散された多くのブロック上に記録しています。多数のブロック間の同期は多数決で保たれます。すなわち、うち1台のブロックで改ざんがあっても、その他のブロックによってすぐに上書きされます。この特徴が最も活かされるのが仮想通貨です。仮想通貨では、各人の仮想通貨の保有数、人々の間の仮想通貨の授受が、全て時系列に改ざん不能な形で記録されています。反対に私たちが銀行に預けている預金は、それぞれの銀行の中央のシステムにだけ記録されています。なお、ブロックチェーンの開発者はサトシ・ナカモトという英語が堪能な謎の日本人です。

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

スマートコントラクトは、1990年代にNick Szaboによって提唱され名付けられアルゴリズです。スマートコントラクトを日本語に訳すと、スマートな契約となるので、ブロックチェーンを使った契約のイメージを持つかもしれませんが、定義上は契約とは無関係です。スマートコントラクトを契約アプリケーションに使うことはもちろん可能ですが、およそブロックチェーンに乗せたプログラムコードは全てスマートコントラクトと呼ばれます(誤って解説しているブログが非常に多いです)。通常のアプリケーションは特定のサーバに記録されて動くのに対して、スマートコントラクトは分散されたブロックチェーンの上に記録されて動きます。

よって、通常のプログラムはサーバから消すと過去の履歴も含めて全てが消えるのに対し、スマートコントラクトはブロックチェーン上に記録されることから、変更の履歴とその時点を含めて半永久的にプログラムが残ります。イーサリアム開発者のVitalikはスマートコントラクトと呼ばずに”persistent scripts(永続スクリプト)”と呼ぶことを提唱しています。この永続スクリプトを使って開発されるのがDApps:Decentralized Applications(日本語だと分散型アプリケーション)です。ここで始めて契約関係のアプリケーションが一つの用途として登場します。

仮想通貨として有名なビットコインはBitcoin Scriptと呼ばれる言語で動いていますが、Bitcoin Scriptではアプリケーションの開発は難しいです。これに対して、イーサリアムは始めからスマートコントラクト(永続スクリプト)を記述できるように開発され、JavaScriptによく似たSolidityというプログラミング言語を実装しました。1990年代に提唱されたスマートコントラクトは、2015年にようやく実現したことになります。そしてイーサリアムのブロックチェーン上では、Solidityで書いたプログラムを乗せてアプリケーションを開発します。

DApps (分散型アプリケーション)とは

分散型アプリケーションの最大の特徴は(1)改ざんがされない点ですが、(2)起動やシャットダウンを観念できず常に動いているという特徴もあります。起動やシャットダウンは、1台やせいぜい数台のサーバで動くアプリケーションならできますが、世界中の互いに関係のない多数の組織が保有するのサーバ(ブロック)を全てシャットダウンするのは不可能です。もちろんサーバダウンによってアプリが使えなくなることもありません。また、(3)アカウントの開設や個々の取引に承認を与える中央の組織(預金の場合は銀行)が存在しない点も大きな特徴です。以上はメリットになりますが、デメリットとしては(1)世界中に記録が共有されていること(アプリケーションの内容が公で企業秘密になり得ない)と、(2)アプリケーションを動かすためにコストを払う必要がある点があげられます。

Solidity コントラクトの書き方

本題のSolidityで実際にコントラクトの書き方を解説したいと思います。ここでは、アカウントを持つ人がメッセージを残せる簡単なアプリケーションをSolidityで作成したいと思います。下記のコードをご覧ください。Solidityのコードの1行目では必ずSolidityのバージョンを設定します。Solidityのバージョンを設定した後は、コントラクトを作成します。コントラクトは他のオブジェクト指向言語のクラスに相当します。クラスの説明をここでするとかなり長くなるので別の機会にしたいと思います。JavaScriptでclassのキーワードに続けてクラス名を設定するのと同様に、Solidityではcontractのキーワードに続けて、コントラクト名を設定します。

3,4行目ではコントラクト変数(クラス変数に相当)を設定しています。Solidityは、JavaScript同様の静的型付け言語で、変数を設定するには必ずデータ型を定義する必要があります。address型はSolidityに固有のデータ型で、文字通りイーサレアムのアドレス(銀行口座番号に相当)を格納するためのデータ型です。addressに続くpublicによってこの変数をプログラム内のどこからでも呼び出せるようにしています。ownerは変数の名前です。変数名は任意です。続く4行目では配列を設定しています。Javascrpitと全く同じ形です。ここではstring型の要素を持つ配列を設定しています。messagesは変数の名前です。


1  pragma solidity ^0.6.6; 
2  contract SimpleApp {
3  address public owner;
4  string [ ] public messages;
5 }

コントラクト変数を設定した後もJavaScript同様で、コンストラクターを作成します。コンストラクターは空の概念コントラクトを実在させるための初期化設定です。 ここでは2つの変数のうち、ownerだけをmsg.senderで初期化させています。msg.senderは組み込まれた変数で、このコントラクト内の関数を呼び出したアドレス(アカウント)が格納されます。


1  pragma solidity ^0.6.6; 
2  contract SimpleApp {
3  address public owner; 
4  string [ ] public messages;
5 
6  string [ ] constructor() public {
7    owner = msg.sender;
8  }
9 }


続いて、ownerがメッセージを残す関数を作成したいと思います。9行目、関数を宣言するfunctionのキーワードに続き、addmsgという関数を定義しています。変数はstring型を受け入れます。10行目のrequireで、ownerがmsg.senderであることを確認した上、11行目でmessages配列に、新しいメッセージを格納しています。この先には例えば格納されたメッセージを呼び出す関数を設定するとよりアプリケーションとして使えるものになります。


1  pragma solidity ^0.6.6; 
2  contract SimpleApp {
3  address public owner; 
4  string [ ] public messages;
5 
6  string [ ] constructor() public {
7    owner = msg.sender;
8  }
9  function addmsg(string newmsg) public{
10   require(msg.sendr == owner);
11    messages.push(newmsg);
12  }
13 }


以上非常に簡単ですが、Solidityでのコントラクトの書き方について解説いたしました。実際にコードを書く場合は、オンラインIDE(統合開発環境)のremixが便利です。remixで記述したプロジェクトをローカル環境(ローカルではtruffleを使います。)に移植するには、remixdが使えます。今日も最後まで読んで頂きありがとうございました。