【Blockchain】初めてのSmart Contractsを作ってみた

`Ethereum` (イーサリアム)プラットフォームで `Blockchain` の勉強をはじめました。
まず、言葉の定義から・・・

## Smart Contractsとは
`Contracts` = `契約` とは、2つまたは複数の間で交わす約束で、次の事柄が定義されています：

  - 何ができるのか
  - どのようにするのか
  - どのようなルールがあるのか

※ 日常で交わされる契約では、公証人と時間と手数料が必要

`Smart Contracts` = `賢い契約` とは、Blockchain内に保持することができるプログラムであり、全てのノードがそのコピーを持っています。そのプログラムの中に上記の3点の事柄を定義することができる。また、Blockchainに上げること、実行することなどには手数料 `GAS` がかかります。

## プログラミング言語と開発環境
EthereumでSmart Contractsを作るためには、 `Solidity` というプログラミング言語を使います。コンパイルすると `Bytecode` という名称のマシンコードができ、トランザクションを利用してEthereumのBlockchainに送ることができます。これで、この契約のインスタンスができ上がります。

全てのノードは、`Ethereum Virtual Machine (EVM)` を持っています。これで、Smart ContractsのBytecodeを実行することができます。

開発環境として `Remix` というIDEを利用することができます。
Remixは、WebブラウザベースのSolidity言語の統合開発環境です。
Smart Contractsの実行(シミュレーション)やデバッグができるのはもちろん、EthereumのBlockchainに参加しているノードへ接続ができ、Smart Crontactsのデプロイなどができます。
Remix IDEを使うには、次のアドレスにアクセスするだけです。

[https://remix.ethereum.org](https://remix.ethereum.org)

さて、お次は、お待ちかねの初のBlockchainプログラミングです。

## 初めてのSmart Contracts
Solidity言語でSmart Contractsを作るのは、Javaなどのオブジェクト指向プログラミングのクラスを作るのにすごく似ています。

```js
// (1) 言語のバージョン
pragma solidity ^0.4.24;

// (2) Smart Contract名
contract MessageStore {
    
    // (3) 属性
    address private owner;
    string private message;
    
    // (4) コンストラクタ
    constructor() public {
        owner = msg.sender;
    }
    
    // (5) 関数
    function setMessage(string newMessage) public {
        message = newMessage;
    }
    
    // (6) 関数 view
    function getMessage() public view returns (string) {
        return message;
    }
}
```

**(1) 言語のバージョン**

- 言語バージョンはコンパイラと互換性を持たなければならない。 (IDEの右側でコンパイラを選ぶことができます)
- 今回の場合は、バージョン: `0.4.24+commit.e67f0147.Emscripten.clang` を選択します。

![IMG-01](https://qiita-image-store.s3.amazonaws.com/0/273166/31b3cdf1-c8e2-4059-0c4a-f4b7dd64bc7d.png)

**(2) Smart Contract名** (クラス名と同じ)

- 今回の場合は、 `MessageStore` にします。

**(3) 属性**

- 属性は、次の順番 `変数型` `アクセス制限` `変数名` で定義します。
- Blockchainに参加するノードには一意のアドレスが振られていて、そのアドレスはプログラムで `address` 型に収納します。
- 今回は、属性としてこのSmart Contractsのオーナーは誰なのか `owner` と保存したいメッセージは何か `message` を定義します。

**(4) コンストラクタ**

- インスタンスを生成するときに呼ばれる関数です。
- 主に属性などの初期化をします。
- 今回の場合は、属性 `owner` に `msg.sender` (ブロックを生成したノードのアドレス)を設定します。

**(5) 関数**

- 関数(コンストラクタを含む)は、次の順番で定義します。  
  `function` `関数名` (`変数型` `変数名`…) `アクセス制限`
- `public` 関数を実行するには、通常 `GAS` がかかります。
- ここでは、引数で渡される文字列 `newMessage` を属性 `message` に設定します。


**(6) 関数 return あり**

- 戻りがある関数の定義は次の順番で定義します。  
  `view` `returns` (`変数型`)
- `view` はデータを取得 `getter` であることを明示します。 (`GAS` がかかりません。タダですよを意味します)
- ここでは、属性 `message` を返します。

## Smart Contractの実行(シミュレーション)
コンパイルは、IDEの右側にある `Compile` > `Start to compile (Ctrl-S)` をクリックします。

実行は、IDEの右側にある `Run` タブを選択後、次の設定をします。

- `Environment` : `Javascript VM (Local)`
- `Account` : `5つあるアカウントの内、任意のアカウントを選ぶ`
- `Gas limit` : `任意の手数料制限を設定`  
  - 足りない場合は、エラーが発生します
  - 大きい程、処理優先されます
  - よく使われる通貨単位は `wei` と `ether` です
  - `1 ether` = `1e18 wei` (ゼロが18こ)

そして `Deploy` ボタンをクリックで実行します。

さて、実行に成功すると、次のようにIDEの右側に `MessageStore`が実行していることを確認できます。

![IMG-02](https://qiita-image-store.s3.amazonaws.com/0/273166/a6da940e-ea95-6287-8400-65612e7aa416.png)

そして、public関数も表示されるので、ここで呼び出すことができます。
例えば、 `setMessage` に "Hello World" を入力し、クリックしてみましょう。 (引数が `string` の場合、ダブルコーテーションは必要です)
そして、次は、 `getMessage` をクリックしてみましょう。
いかがでしたか？正常に動作しましたでしょうか？
これで、初めてのSmart Contractsの完成です。