Solidiity Documentation ver0.5.8を読んだ(3.1.1のまとめ)

```ASimpleSmartContract.sol 

pragma solidity >=0.4.0 <0.7.0;

contract SimpleStorage {
    uint storedData;  //storedDataは状態変数
    
    function set(uint x) public {
        storedData = x;
    }
    
    function get() public view returns (uint) {
        return storedData;
    }
```
#ポイント
・solidityのコントラクトはイーサリアム上に存在する特定のアドレスに紐ずけられたコード（関数）とデータ（状態）の集合である。
・storedDataは、データベースを管理するコードの関数を呼ぶことで参照や変更が可能なデータベース上のsingle slot（穴）であると考えられる。
・setやgetといった関数は変数の値を参照や変更に用いることができる。
・このコントラクトはこの数をあなたが公表することを防ぐことができる方法を除いて、世界の誰からでもアクセス可能なこのただ１つの数を保存することを誰かに許すことに効果的な方法はない。
・誰でもset関数に異なる値でcallを繰り返すことができ、あなたの数に上書きできる。しかしその数はブロックチェーン上に記録される。

##注意
・コントラクト名や関数名、変数名といった全ての識別子はASCII文字列に制限されている。
・文字変数にUTF-8符号化データを保存することができる。

#警告
・Unicode textを使うときは気をつけなければならない。似ている文字は違うコードポイントを持ち、異なる文字配列とし符号化されるから。





```SubcurrencyExample.sol

pragma solidity >=0.5.0 <0.7.0;

contract Coin {

    //アドレス型で誰でもアクセスできる状態変数を定義
    address public minter;  //publicはこれらの変数を外部から読みやすくする
    mapping (address => uint) public balances;  //publicな状態変数を定義 
    
    event Sent (address from, address to, uint amount); //イベントによりライトクライアントは効率的に変更に対応できる
    
    constructor() public {  //コンストラクタはコントラクトを生成した時のみ実行されるコード
        minter = msg.sender;  //このコントラクトを生成したアドレスがminterアドレスに代入される
    }
    
    function mint(address receiver, uint amount) public {
        require(msg.sender == minter);  //minterアドレスしかmint関数を実行できない
        require(amount < 1e60);
        balances[receiver] += amount;  //たくさんコインを発行して後でオーバーフローを起こさないように、
    }
    
    function send(address receiver, uint amount) public {  //誰でも関数を実行できる
        require(amount <= balances[msg.sender], "Insufficient balance.");  //残高があるか確認
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Sent(msg.sender, receiver, amount);
    }
}
```
#ポイント
・アドレス型は160ビットの値で数学的操作はできない。アドレス型はコントラクトのアドレスや外部の人に属するキーペアを保存するのに適している。
・publicはコントラクトの外部から現在の状態変数にあなたがアクセスできる関数を生成する。
・ex1.solとex2.solはほとんど同等の文である。

```ex1.sol
address public minter;
```

```ex2.sol

function minter() external view returns (address) {
    return minter;
}
```
mappingできるkeyとvalueの数は有限である。
ex3.solとex4.solはほとんど同等の文である

```ex3.sol
mapping (address => uint) public balances;
```

```ex4.sol
function balance(address _account) external view returns (uint) {
    return balances[_amount];
}
```

・ユーザーインターフェイス（サーバーアプリケーション）は、高いGasを伴わずにeventがblockchainにemitされるのをlisten（待機）することができる。
・eventがemitされると、listnener（待機者）は引数from,to,accountを受け取る。これらはトランザクションの追跡を簡単にしている。
・eventをlinstenする為に以下のようなJavaScriptコードを使える。（これはweb3.js経由でコントアクトが作成されていることを前提にしている。）

```listen.js
Coin.Sent().watch({}, '', function(error, result) {
    if (!error) {
        console.log("Coin transfer:" + result.arg.amount + 
            " coin were sent from" + result.args.from +
            " to " + result.args.to + ".");
        console.log("Balance now:\n" + 
            "Sender: " + Coin.balances.call(result.args.from) +
            "Receiver: " + Coin.balances.call(result.args.to));
    }
})
```
・このコンストラクタは永久的にコントラクトを生成した人のアドレスを保存する。
・msg（txやblockを伴う）は、特別なグローバル変数である。これはブロックチェーンにアクセスできる性質を保持している。
・msg.senderはそのお時外部からその関数を呼び出したアドレスである。
・requierはその引数がfalseだと評価されると、全ての変更を元に戻す。

#注意
このコントラクトを実行しても、ブロックチェーンエクスプローラでは、このコントラクトのアドレスのみしか確認できない。トークンを送ったことや残高が変更されたことは、このコントラクトのデータストレージにのみ保存されるため。eventを使用することで、ブロックチェーンエクスプローラでそれらを追跡することができる。その場合コインを保有するアドレスではなくコイン管理するコントラクトアドレスを探す必要がある。