#関数
関数の作成は、次のように定義します。
function eatHamburgers(string _name, uint _amount) {
}
string
と uint
という2つのパラメーターを持ちます。
グローバル変数と区別をつけるために、関数パラメーター変数名はアンダースコア(_)をつけるのが通例(必須ではありません)です。
関数は次のように呼び出します。
eatHamburgers("vitalik", 100);
#Private関数
Solidityでは、関数はデフォルトでpublic
になっています。つまり、誰でも(別のコントラクトから)自分で作成したのコントラクトの関数を呼び出して、実行できるということです。
これは、攻撃に対してコントラクトが脆弱になります。そのため、自分が使う関数はデフォルトでprivate
にして、公開しても構わない関数だけをpublic
に設定します。
Private関数は次のように定義します。
uint[] numbers;
function _addToArray(uint _number) private {
numbers.push(_number);
}
このように書くと、この関数はコントラクト内の他の関数からだけ呼び出して、numbers配列に格納できます。
Private関数は、Public関数のパラメータと同様に、関数名にアンダースコア(_)をつけるのが通例です。
#戻り値
関数の戻り値を設定する場合は次のように定義します。
function sayHello() public returns (string) {
string greeting = "What's up dog";
return greeting;
}
Solidityでは関数の宣言に、戻り値の型を含みます(ここではstring
です)。
しかし、このままだと誰からでもこの関数を編集することができてしまいます。
なので、次のように設定します。
- view関数
function sayHello() public view returns (string) {
viewをつけると、読み取りのみ行うことができます。
- pure関数
function _multiply(uint a, uint b) private pure returns (uint) {
return a * b;
}
pureをつけると、アプリ内のデータにアクセスできなくなります。
どのような時にpure/viewを使い分けるのか難しい場合には、
コンパイラが警告してくれるので、大丈夫です。
#構造体
pythonだと一つの変数(定数)にstringとintは入れることはできませんが、Solidityの構造体はstringもintもどちらも入れることができます。
structは以下のように作成します。
struct Person {
uint age;
string name;
}
#配列
Solidityには、固定長配列と可変長配列、2種類の配列が用意されています。
// 2要素の固定長配列:
uint[2] fixedArray;
// 文字列の固定長配列の例。5つの文字列を格納:
string[5] stringArray;
// 可変長配列 - 決まったサイズはないので、格納し続けることができます:
uint[] dynamicArray;
配列をpublicで指定すると自動的にgetter関数を作成します。
getter関数とは、外部から見れるようにする関数のことをいいます。
Person[] public people;
上記は、Person構造体をpeople配列(パブリック配列)で指定するという意味です。
パブリック配列は、読み込みはできますが、書き込みはできません。
そのため、公開するコントラクトのデータを格納する時に便利です。
このままだと、people配列には何も入っていないので、次のように追加していきます。
// 新しいPersonを作る:
Person satoshi = Person(172, "Satoshi");
// それを配列に格納する:
people.push(satoshi);
上記のコードを1行にまとめることができます。
people.push(Person(16, "Vitalik"));
array.push()
は配列の最後に何かを追加するので、要素は追加した順番になります。
uint[] numbers;
numbers.push(5);
numbers.push(10);
numbers.push(15);
// 数字は [5, 10, 15]