変数とデータ型
変数の宣言
Solidityは静的型付け言語であり、変数を定義する際にそこに格納するデータ型を明示する必要があります。 以下に符号付整数であるint
型の変数x
を宣言する例を示します。
また次のように宣言時に初期値を指定する事も可能です。
ちなみに初期値を設定しない場合には、各型のデフォルト値が格納されます。例えばint
の場合、0
が格納されます。
データ型
基本型と参照型
先に記したとおり、Solidityは静的型付け言語であり、変数を扱う際にはその変数のデータ型を強く意識する必要があります。Solidityには様々なデータ型が規定されていますが、それらは大きく基本型 と参照型という2つのタイプに分類されます。
これらは変数に格納される際の方法に違いがあります。まず基本型の変数には、「値そのもの」が格納されます。一方で参照型の変数には「値を格納しているメモリ上のアドレス(参照)」が格納されます。この動作の違いにより基本型と参照型で変数を扱う際の挙動に違いが生まれます。基本形であるuint型の変数と、参照型である配列の変数を例にして、両者で代入の挙動の挙動に違いをみてみましょう。
関数valType()
では基本型であるuintの変数を代入した場合の挙動を試験しています。(1)の行では、変数a
に代入された「10」という値そのものがコピーされて変数b
に代入されます(値渡し)。その結果b
の値が(2)で変更されても、元の変数a
の内容には影響を与えません。その結果この関数の実行結果は10
が示されます。
一方で関数refType()
では参照型である配列の変数を代入した場合の挙動を試験しています。配列の変数は参照型であり、参照型の変数には「値を格納しているメモリ上のアドレス(参照)」が格納されています。そのため(3)で配列x
をy
に代入していますが、ここで実際に行われていることは、変数x
の値を格納しているメモリ上のアドレスを変数y
にセットしていることになります(参照渡し)。そのためこの時点でx
とy
は同じ場所を見ていることになり、(4)でy
の内容を変えると同時に変数x
の内容も変更されることになります。結果、この関数の実行結果は[500, 600]
が示されます。
以下でSolidityで規定されている基本型と参照型のそれぞれのデータ型について見ていきます。
符号付き整数型
以下の例のように符号付き整数型はint●
句を用いて宣言します。ここで「●」は変数のビット長の指定であり8~256までの8の倍数が指定されます。例えばint8は8ビット符号付整数型を表わします(-128 ~ 127)。数字が省略されint
と指定された場合はint256
を意味します。またデフォルト値は0です。
符号なし整数型
以下の例のように符号なし整数型はuint●
句を用いて宣言します。ここで「●」は変数のビット長の指定であり8~256までの8の倍数が指定されます。例えばuint8は8ビット符号なし整数型を表わします(0 ~ 255)。数字が省略されuint
と指定された場合はuint256を意味します。またデフォルト値は0です。
真偽型
真偽(論理)型変数はbool
句により宣言します。true
(真)またはfalse
(偽)の2値のみが格納可能です。デフォルト値はfalse
になります。
アドレス型
アドレス型はEOAやContractの20バイトの長さのアドレスを格納する型でありaddress
句で宣言します。
■ balance属性
アドレス型にはbalance
属性が規定されています。例えば下記の例の用にbalance属性を用いると指定のアドレスが保有するetherの量が取得可能です。
■ send()関数
アドレス型にはsend
関数が規定されています。<address>.send(x);
により指定のアドレス<address>
にx
weiのetherを送金することができます。以下に実際に送金を行う簡単なコントラクトのコードを示します。
【TIP】実際に上記のコントラクトのsendTest関数を動かす際は、コードをコンパイルしブロックチェーンに登録後、本コントラクトのアドレスに5wei以上のetherを送金しておく必要があります。というのもsendTest()関数はコントラクトが保有するetherを指定のアドレスに送る関数であるためです。また、アカウントの状態を変える関数のために、「Contractを作成してみる」節で説明したとおり、sendTestの関数の実行はsendTransaction関数を用いて呼び出す必要があります。
配列
Solidityでは、固定長、可変長のどちらの配列型も扱うことが可能です。配列要素の型はストレージ変数の場合は任意のデータ型の配列を定義することが可能です。
固定長配列は、データ型T
、長さk
の配列はT[k]
で宣言します。一方可変長配列の場合はT[]
とします。
以下に、固定長配列を扱うSolidityコードの例を示します。
上記のContractコードをコンパイルし、ブロックチェーン上に登録しContractのそれぞれの関数を呼び出すと下記のような実行結果になります。
また、上記Contractコードでコメントアウトしている関数(getStArray)はstring型の配列全体を返す関数を意図していますが現バージョンのコンパイラでは「Error: Internal type is not allowed for public and external functions.」というエラーになりコンパイルできません。これはuint等とは異なり、文字列型自体がコンパイラ内でバイト配列型として扱われており、「文字列型の配列」はネストされた2次元配列として扱われます。現バージョンコンパイラは、ネストされた配列を関数の引数または返り値に指定することをサポートしておらず、エラーになります。
■ length属性、push関数
配列には配列長さを示すlength
属性が規定されています。可変長配列では下記の例のようにlength属性を指定することで配列要素を削除することも可能です。
また可変長配列の最後に要素を追加するpush関数が用意されています。使い方の例を以下に示します。
上記のContractコードをコンパイルし、ブロックチェーン上に登録しContractのそれぞれの関数を呼び出すと下記のような実行結果になります。
Last updated