【Solidity】public変数はゲッターメソッドを自動生成する

solidityでは、public変数を宣言するとゲッターメソッドが自動生成されます。
例えば以下のソースでは、

```
pragma solidity ^0.5.0;

contract PublicTest {
    uint8 public v1;
}
```

自動生成されたゲッターメソッドで変数値を取得できます。

```
PublicTest pt = new PublicTest();
uint8 v1 = pt.v1();
```

Javaなどのように、変数を直接参照することはできません。

```
// 以下はコンパイルエラーとなる
uint8 v1 = pt.v1;
```

なお、セッターメソッドは自動生成されません。
セッターメソッドが必要な場合は自分で定義する必要があります。

上記ソースのABIは以下となります。

```
[
	{
		"constant": true,
		"inputs": [],
		"name": "v1",
		"outputs": [
			{
				"name": "",
				"type": "uint8"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	}
]
```

ABIでは"v1"という名前のメソッドが定義されています。
`"constant": true`は、このメソッドがデータを更新しないことを示しています。
`"inputs": []`は、メソッドに引数がないことを示しています。
`"outputs": ～`は、戻り値の名前とデータ型を示しています。

#配列の場合
配列のpublic変数を宣言した場合、配列要素を取得するゲッターメソッドが自動生成されます。
例えば以下のソースでは、

```
pragma solidity ^0.5.0;

contract PublicTest {
    uint8[] public array1;
}
```

自動生成されたゲッターメソッドで配列要素を取得できます。

```
PublicTest pt = new PublicTest();
uint8 v1 = pt.array1(0); // 0はインデックス
```

配列そのものは取得できません。

```
// 以下はコンパイルエラーとなる
uint8[] array1 = pt.array1();
```

上記ソースのABIは以下となります。

```
[
	{
		"constant": true,
		"inputs": [
			{
				"name": "",
				"type": "uint256"
			}
		],
		"name": "array1",
		"outputs": [
			{
				"name": "",
				"type": "uint8"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	}
]
```

`"inputs": ～`で、引数にインデックスを指定する必要があることを示しています。

#mappingの場合
mappingのpublic変数を宣言した場合、mapping要素を取得するゲッターメソッドが自動生成されます。
例えば以下のソースでは、

```
pragma solidity ^0.5.0;

contract PublicTest {
    mapping(uint8 => string) public m1;
}
```

自動生成されたゲッターメソッドでmapping要素を取得できます。

```
PublicTest pt = new PublicTest();
string s1 = pt.m1(0); // 0はmappingのKey
```

mappingそのものは取得きません。

```
// 以下はコンパイルエラーとなる
mapping(uint8 => string) m1 = pt.m1();
```

上記ソースのABIは以下となります。

```
[
	{
		"constant": true,
		"inputs": [
			{
				"name": "",
				"type": "uint8"
			}
		],
		"name": "m1",
		"outputs": [
			{
				"name": "",
				"type": "string"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	}
]
```

`"inputs": ～`で、引数にKeyを指定する必要があることを示しています。

#構造体の場合
構造体のpublic変数を宣言した場合も、ゲッターメソッドが自動生成されます。
例えば以下のソースでは、

```
pragma solidity ^0.5.0;

contract PublicTest {
    struct Data {
        uint8 a;
        uint8 b;
        uint8[] c;
        mapping (uint8 => string) map;
    }
    Data public d1;
}
```

自動生成されたゲッターメソッドで構造体の変数値を取得できます。
ただし、配列とmappingは、インデックスやKeyを指定することが難しいため、返却されない仕様となっています。
（つまり、`a`と`b`のみ返却される）

```
PublicTest pt = new PublicTest();
(uint8 a, uint8 b) = pt.d1();
```

構造体そのものは取得できません。

```
// 以下はコンパイルエラーとなる
Data d1 = pt.d1();
```

上記ソースのABIは以下となります。

```
[
	{
		"constant": true,
		"inputs": [],
		"name": "d1",
		"outputs": [
			{
				"name": "a",
				"type": "uint8"
			},
			{
				"name": "b",
				"type": "uint8"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	}
]
```

#「配列のmapping」「mappingのmapping」の場合
「配列のmapping」「mappingのmapping」のpublic変数を宣言した場合も、ゲッターメソッドが自動生成されます。
例えば以下のソースでは、

```
pragma solidity ^0.5.0;

contract PublicTest {
    mapping(uint8 => string[]) public m2; // 配列のmapping
    mapping(uint8 => mapping(uint8 => string)) public m3; // mappingのmapping
}
```

自動生成されたゲッターメソッドで配列要素、mapping要素を取得できます。

```
PublicTest pt = new PublicTest();
string s1 = pt.m2(0, 1); // 第1引数がmappingのKey、第2引数が配列のインデックス
string s2 = pt.m3(0, 1); // 第1引数が外側のmappingのKey、第2引数が内側のmappingのKey
```

上記ソースのABIは以下となります。

```
[
	{
		"constant": true,
		"inputs": [
			{
				"name": "",
				"type": "uint8"
			},
			{
				"name": "",
				"type": "uint8"
			}
		],
		"name": "m3",
		"outputs": [
			{
				"name": "",
				"type": "string"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [
			{
				"name": "",
				"type": "uint8"
			},
			{
				"name": "",
				"type": "uint256"
			}
		],
		"name": "m2",
		"outputs": [
			{
				"name": "",
				"type": "string"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	}
]
```

m2の`"inputs": ～`は引数にKeyとインデックスを指定する必要があることを示しています。
m3の`"inputs": ～`は引数にKeyを2つ指定する必要があることを示しています。