Solidity　基礎文法まとめ[備忘録]

JSやC言語、Javaなど色々な言語を学んできて、ブロックチェーンに関して気になったので、
Solidityの勉強を始めました。そこで、JSやCを触ってきた自分が
忘れやすそうなところをメモしています✊

# 基礎文法

## 初期設定的な内容
Solidityでは、プログラムの始まりに`pragma solidity ^0.4.19;`のように記述し
使用するコンパイラのバージョンを指定する必要がある。
（将来コンパイラのバージョンが原因でコードが壊れることを防ぐため）
また、`contract`（訳：契約）がclass, component的な感じ。

### 書き方
```solidity:contract.sol
pragma solidity ^0.4.19;

contract HelloWorld{
    // 内容を書く
}
```

### 継承
is_Aの形式で継承できる。フレームシステムあたりの話を思い出す感じ。
```solidity:contract.sol
// is 継承したいContract
contract Hello is Greet {
}
```

### import
JSと同じだが、ダブルクオートじゃないと受け付けない。
```solidity:Contract.sol
import "./utilcontract.sol"
```

## 型、コレクション周り

<table>
    <thead>
    <tr>
        <th>名称</th>
        <th>記述</th>
        <th>その他情報</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>符号無し整数(unsigned int)</td>
        <td>uint(=uint256)</td>
        <td>uint32,uint16,uint8など、種類あり</td>
    </tr>
    <tr>
        <td>文字列</td>
        <td>string</td>
        <td>直接の比較は不可(Javaっぽい)</td>
    </tr>
    <tr>
        <td>アドレス</td>
        <td>address</td>
        <td>アカウントのユニークな識別番号。<br>msg.senderで関数を呼び出したユーザーのアドレスを取得できる。</td>
    </tr>
    <tr>
        <td>マッピング</td>
        <td>mapping<br>mapping (address => uint) public accountBalance;</td>
        <td>JSのオブジェクトや辞書型と同じ。</td>
    </tr>
    <tr>
        <td>ユーザ定義型（構造体）</td>
        <td>struct Example{<br>&nbsp;&nbsp;uint amount;<br>&nbsp;&nbsp;string name;<br>}</td>
        <td>C言語と同じ使い方</td>
    </tr>
    <tr>
        <td>配列(少し特殊)</td>
        <td>uint[2] fixedArray;<br>uint dynamicArray;</td>
        <td>固定長、可変長があり<br>ブロックチェーンのデータ保存→可変長。<br>pushメソッド＝JSのpush<br>＋配列の長さも返す</td>
    </tr>
    <tr>
        <td>キャスト（型変換）</td>
        <td>uint8(b)</td>
        <td>型名（変数）でOK。JSと同じ</td>
    </tr>
    </tbody>
</table>




## アクセス修飾子周り
<table>
    <thead>
    <tr>
        <th>名称</th>
        <th>その他情報</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>public</td>
        <td>どのContractからも参照可能</td>
    </tr>
    <tr>
        <td>private</td>
        <td>同一Contract内のみ参照可能。<br>配列など、privateがついたものは<b>_</b>始まりが通例</td>
    </tr>
    <tr>
        <td>external</td>
        <td>外部のみアクセス可能。</td>
    </tr>
    <tr>
        <td>internal</td>
        <td>Javaのprotected的な感じ。<br>継承したコントラクトからアクセスできるが、他の外部からのアクセスは不可</td>
    </tr>
    </tbody>
</table>

## 関数周り

基本的な使い方は以下の通り
```solidity:contract.sol
function eatCakes(string _name, uint _amount) {
}

// private, publicなどアクセス修飾子の位置（引数の後）
function eatCakes(string _name, uint _amount) private {
}

// 何かしら値を返すとき 「returns(返す変数の型)」をつける
function eatCakes(string _name, uint _amount) private returns(string) {
}

// 関数の修飾子
// view：データの読み取り専用で編集できない
function eatCakes(string _name, uint _amount) public view returns(string) {
}

// pure：アプリ内のデータにすらアクセスできなくなる
function eatCakes(string _name, uint _amount) private pure returns(string) {
}
```

## ハッシュ
Solidityには、SHA3（Secure Hash Algorithm 3、ハッシュ関数の計算手順）の
バージョンの一つであるkeccak256が組み込まれている。
また、文字列の直接的な比較はできないので、文字列の比較を行いたい場合は
このハッシュで比較する。
```solidity:contract.sol
// 使い方
keccak256("文字列");
// 例
keccak256("aaaac");

// if文の書き方はC言語っぽい感じ
if(keccak256("aaaac") == keccak256("aaaa")) {
}
```

## イベント
Eventは、ブロックチェーンで何かが生じたときに、
コントラクトがアプリのフロントエンドに伝えることができるもので
特定のイベントを'listening'状態（接続待ち状態）にして、
何かあった時にアクションを起こすこともできる。
```solidity:contract.sol
// イベントの宣言
event IntegersAdded(uint x, uint y, uint result);

function add(uint _x, uint _y) public {
  uint result = _x + _y;
  // 関数が呼ばれたことをアプリに伝えるためにイベントを発生させる：
  IntegersAdded(_x, _y, result);
  return result;
}
```

## バリデーション的なもの
`require`を使って、Reactの`useEffect`のようなことができる。
正確には、ある条件を満たさない場合はエラーを投げて実行を止めることができるもの。
```solidity:contract.sol
function sayHiToVitalik(string _name) public returns (string) {
  require(keccak256(_name) == keccak256("Vitalik"));
  return "Hi!";
}
```


## ストレージとメモリ
変数の保存場所はストレージとメモリの２種類あり、
Storage はブロックチェーン上に永久に格納される変数で、
それと対照的にMemoryは一時的な変数で、外部関数をコントラクトに呼び出す際に
消去されるもの。
状態変数（関数外で宣言された変数）の場合はデフォルトで
storageで、ブロックチェーン上に永久に格納される。
一方、関数内で宣言された変数はmemoryとして扱われて関数の呼び出しが終われば
消えるように設定されている。
```solidity:contract.sol
// 宣言の仕方
contract Example {
    storage uint amount;
    memory uint tmp;
}

```

# フロントで扱うための技術

web3.js

https://web3js.readthedocs.io/en/v1.7.5/

Ethers.js

https://docs.ethers.io/v5/