solidityの構文

Solidityとは

f:id:adrenaline2017:20190706101609p:plain Ethereumでスマートコントラクトを開発する為の言語です。構文がJavaScriptに似てるので、非常に親みやすい言語だと思います。 solidityはsolcと呼ばれるSolidityコンパイラによってEVM(Ethereum Virtual Machine)が扱える専用のバイトコードに変換されます。

solidityの型には値型と参照型があります。値型は実データそのものを格納し、参照型は実データを参照するためのポインタを格納します。

値型

  • 符号付き整数(int)
  • 符号なし整数(uint)
  • 文字列(string)
  • 論理型(boolean)
  • アドレス(address)
  • バイト型配列(bytes)
  • 関数 (function)
  • 列挙型(enum)

参照型

符号付き整数/符号なし整数

整数には 符号あり整数(int)と符号なし整数(uint)があります。intとuintは変数のbit長を8-256bitで指定出来ます。例えば8bitのuintの場合はuint8と表します。

    // uintに-60を代入するとは出来ない
    uint signedInteger = 60;
    int unsignedInteger = -30;

加算、減算、乗算、徐算、剰余は他のプログラミング言語と同じ様に出来ます。またビット演算子(&, |, ^, ~, <<, >>)比較(<=, <, ==, >, >=)論理演算子(!, &&, ||, ==, !=)計算代入も使用することが可能です。

    uint base = 60;
    uint add = base + 10; // 70
    uint sub = base - 10; // 50
    uint mul = base * 10; // 600
    uint div  = base / 10; //6

文字列

stringには文字列を入れることができます。しかしsolidityのstringの場合、そのまま文字列を比較することができません。Keccak256関数を使って文字列をbytes32型にしてから比較する必要があります。

  
function comparison(string memory _str) public pure returns (bool){
        return keccak256(abi.encode(_str)) == keccak256(abi.encode("hoge"));
    }

アドレス

ウォレットアドレスとコントラクトアドレスがあります。Ethereumのアドレスサイズである20bytesの値を格納します。

function getBalance(address _addr)public view returns (uint){
        return _addr.balance;
}

関数

関数の宣言はfunctionを使います。

//function 関数名(型 変数名){関数の処理}

function companyMember(string _name, uint _age){}

関数を呼び出す場合は以下の通りです。

companyMember("jiro", "37");

関数から戻り値を返す時はアクセス修飾子の後ろにreturns、処理にreturnを書きます。returnsの後には戻り値の型を宣言します。

//function 関数名 (型 変数名)アクセス修飾子 returns(戻り値の型){} 

string word = "Hello World!";
function helloWorld() public view returns (string memory){
    return word;
  } 

他からのアクセスをコントロールする為にsolidutyではpublic, private, internal, externalの4つのアクセス修飾子があります。

・public: コントラクト内外部及び継承されるのも可能

・private: コントラクト内部からのみ参照が可能

・internal: コントラクト内部及び継承されれるのが可能

・external: コントラクト外部からのみ参照が可能

状態修飾子は関数がブロックチェーンとどのように作用し合うのか示すもので、viewとpureの2種類があります。どちらもトランザクションを発行しないので、呼び出しの際にガスは必要ありません。

・view ブロックチェーンに対してデータの保存や変更は一切行わず、読み取りだけを行います。

・pure ブロックチェーンに対してデータの保存や変更を一切行わないだけでなく、読み取りも行いません。

solidityではデータの保存にstorageとmemoryの2種類があります

・storage:ブロックチェーンにデータを永久に保存するのでgathコストがかかる

・memory: コントラクト実行時に一時的にデータを保持するだけなのでgathコストがかからない

privateの場合は関数名の前にアンダーバー(addToArray)が慣習的に使われます。書かなくてもコンパイルエラーにはなりません。memberのアンダーバーは引数が関数内で参照される際に慣習的に使われます)

uint[] members;

function addToArray(uint _member) private {
    members.push(_member);
}

列挙型

列挙型はユーザー定義型を作成する方法です。列挙型には少なくとも1つの定数が必要です。

contract Enum{
    enum Colors{
        Red,
        Blue,
        Green
    }
    Colors color;
    
    function setColor() public {
        color = Colors.Blue;
    }

構造体

複雑なデータ型を作る際に構造体(struct)を用いて表現することが出来ます。 構造体には複数のプロパティを持つデータ型を作ることが可能です。

contract Structure {
    struct Person {
        string name;
        uint age;
    }
    
    Person[] public projects;
    
    function createPerson(string memory _name, uint _age)public{
        Person memory newPerson = Person({
           name: _name,
           age: _age
        });
        projects.push(newPerson);
    }
}

配列

solidityでは2種類の配列があります。

・固定配列 サイズを指定した固定長になります。

uint[2] fixedArray;

・可変配列 サイズが指定されていない可変長になります。

uint[] dynamicArray;

マッピング

マッピングはデータとデータを参照するキーを組み合わせたKVS(キーバリューストア)です。

//mapping (キー => バリュー) アクセス修飾子 マッピング名;

contract Account{
    struct User {
        address addr;
        uint amount;
    }
    mapping(uint => User) public Users;
}