privateとinternalはそのまま返せる
privateかinternalの修飾詞がついた関数の場合は、特に注意しなくてもstructをreturnできる。
struct UserInfo {
...
}
mapping(uint256 => UserInfo) internal _userIdToUserInfo;
function getUserInfo(uint256 _userId) internal view returns (UserInfo memory) {
return _userIdToUserInfo[_userId];
}
注意:
solidity 0.5.4でのコードです。
0.4.xの場合は、returnする値にストレージ領域を指定しません。
returns (UserInfo memory)
-> returns (UserInfo)
externaとpublicは、ABIEncoderV2を指定する
solidity外部にstructを返す場合は、ABIEncoderV2を指定する必要がある。
pragma experimental ABIEncoderV2;
こうすることでstructを外部にも返せるようになり、web3からも参照できるようになる。
ABIEncoderV2 を使うことによるWarning
ABIEncoderV2を指定することで、以下の「実験的なやつだからlive deploymentでは使わないで」というWarningが出てしまう。
Experimental features are turned on. Do not use experimental features on live deployments.
この注意は何を指しているのか。
現状、solidityの関数でstructを返す場合ABIEncoderV2を指定する必要があるが、これを指定するとコンパイラに「live deploymentsでは使わないで」と注意される。ただ、これはセキュリティ上の問題ではなく、gasの使用量が多くなることへの注意らしい。https://t.co/eB7VknHaHL
— こみー / Ryo Komiyama (@ryoheikomy) 2019年2月18日
twitterに書いたので引用しますが、これはセキュリティに対するwarningではなく、gasの使用量が増加することに対するwarningだそうです。
そのため、「本番環境では使えないから結局structは要素ごとにreturnするしかないのか」となる必要はなく、「gasかかるっぽいから、どのくらいかかるか試してから使うかどうか決めよう」と考えれば良さそうです。
まとめ
Solidityでstructをreturnするときは、以下のようにABIEncoderV2を指定しましょう。
pragma experimental ABIEncoderV2;