Ethereum
solidity

Solidity言語メモ

Solidity言語でスマートコントラクトを作るときにの個人的なメモ帳です。

逐次更新中

関数,変数

  • msg.sender
    • コントラクトを呼び出した一番最初のアドレスを返す
  • msg.value
    • 送金した金額
  • tx.origin
    • コントラクトを呼び出したアドレスを返す。
    • コントラクト1 -> コントラクト2を呼び出したときは、コントラクト1のアドレスが返る。
  • address.transfer(送金額)
    • addressのアカウントに、コントラクトがweiで送金する。失敗したらフェイルバックする。
  • address.send(送金額)
    • addressのアカウントに、コントラクトがweiで送金する。
  • address(this)
    • コントラクトのアドレス
  • address.balance
    • weiで残高を返す
  • now
    • 現在の日時を返す
    • now (uint): current block timestamp (alias for block.timestamp)

  • uint
  • boot
  • address
  • mapping
  • bytes

サンプルコード

  • スマートコントラクト実行者に送金する。
function withdraw() returns(bool success) {
    if( msg.sender ) {
        // use the safe send pattern
        if(msg.sender.send(amount) {
          return true;
        }
    }
}
  • コントラクトに送金されたら実行
    function () payable{
        uint amount = msg.value;
        //いろいろ処理をする。
    }
  • スマートコントラクトを削除する
    • 以前はsuicideという関数でしたが、自殺という名称が良くないので変わるらしいです。
    // スマートコントラクトを削除する
    function kill() { if (msg.sender == owner) selfdestruct(owner); }
  • 配列の一部削除
    配列の添え字を-1してあげる必要があるので注意
            //タグを全部検索する
            for ( uint i = 0; i < getTagsIndex(index); i++ ) {
                //一致するタグを検索
                if ( sha3(item[index].tags[i]) == sha3(vTag) ) {
                    //最後のindexでないことを確認する。
                    if (i == getTagsIndex(index)) {
                        return false;
                    }
                    //タグ番号を1個前にずらす。                        
                    for ( uint j = i; j < getTagsIndex(index) - 1; j++ ) {
                        item[index].tags[j] = item[index].tags[j+1];
                    }

                    //最後の配列は空にする。
                    item[index].tags[getTagsIndex(index)] = "";
                    //配列削除するときはかならず-1すること。
                    item[index].tags.length = item[index].tags.length - 1;
                    //成功を返す
                    return true;
                }
            }
  • 文字列比較
    solidityは文字列の比較ができないので、文字列をsha3に変換して比較するとよいです。
    function searchTags(string v_tag) constant returns (string){
            if (sha3(item.tag) == sha3(v_tag) ){
                return true;
            }
    }
  • 配列の末尾に追加
    pushを使うと、配列末尾に追加できる
    function putComments(uint index, string vComment) public returns(bool) {
        //コメント欄の最後に追記する
        item[index].comment.push(vComment);
        return true;
    }

構造体

  struct test{
    string address;
    uint amount;
  }

実行ユーザーを限定する方法

modifier onlyByProvider() {
    require(msg.sender == provider);
    _;
}

function functionName(bytes32 _name) public onlyByProvider {
}

ガス消費を抑えるコツ

  • トランザクションに載せない変数
    変数定義にmemoryを付ける
string[4] memory adaArr = ["This", "is", "an", "array"];
  • 読み込みのみの関数にはconstantを付ける
    function getItemName(uint i) constant returns (bytes ){
        return item[i].name;
    }
  • String型からByte型に変換する
    function stringToBytes(string memory s) public pure returns (bytes) {
        bytes memory b = bytes(s);
        return b;
    }
  • Byte32型からString型に変換する
    function bytes32ToString(bytes32 x) public pure returns (string) {
        bytes memory bytesString = new bytes(32);
        uint charCount = 0;
        for (uint j = 0; j < 32; j++) {
            byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
            if (char != 0) {
                bytesString[charCount] = char;
                charCount++;
            }
        }
        bytes memory bytesStringTrimmed = new bytes(charCount);
        for (j = 0; j < charCount; j++) {
            bytesStringTrimmed[j] = bytesString[j];
        }
        return string(bytesStringTrimmed);
    }

できないこと

  • 構造体をreturnできない。