はじめに
solidityのバイトデータの扱いについて、byte[]・bytes・bytes32などの理解があいまいだったので整理しました。
bytes・byte[]の違い
任意の長さの生のバイトデータを扱える点で、bytesとbyte[]は似ている。
byte[] は要素間を埋めるのに31バイト追加が必要になるので、データ格納の効率が悪い。
そのため、byte[]よりもbytesを使うことが推奨されている。
全般的なルールとして、任意の長さの生のバイトデータにはbytesを利用する。
bytes1~bytes32
1バイトから32バイトまでのバイト列を保持できる。
非常に低コストなので、バイト長を制限できるならば、bytesではなくbytes1~bytes32を利用する。
bytes1 data1 = 0xff;
bytes4 data4 = 0x12345678;
bytes32 data32 = 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef;
lengthで要素の長さを取得できる。
bytes1 data1 = 0xff;
data1.length --> 1
bytes4 data4 = 0x12345678;
data1.length --> 4
bytes32 data32 = 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef;
data1.length --> 32
indexで要素にアクセスすることができる。
bytes1 data1 = 0xff;
data1[0] --> 0xff
bytes4 data4 = 0x12345678;
data1[3] --> 0x78
bytes32 data32 = 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef;
data1.length[31] --> 0xef
bytes
bytesも、bytes1~bytes32と同じように、lengthの利用や、indexでのアクセスが可能。
// 64バイト
bytes byteData = 0xf0f1f2f3f4f5f6f7f8f9e0e1e2e3e4e5e6e7e8e9d0d1d2d3d4d5d6d7d8d9c0c1c2c3c4c5c6c7c8c9b0b1b2b3b4b5b6b7b8b9a0a1a2a3a4a5a6a7a8a999989796;
byteData.length --> 64
byteData[0] --> 0xf0
byteData[63] --> 0x96
bytes1[]~bytes32[]
固定長のバイト列が配列になっている場合も、lengthの利用や、indexでのアクセスが可能。
bytes4[2] byteData;
byteData[0] = 0xa1a2a3a4;
byteData[1] = 0xb1b2b3b4;
byteData[0][0]; ---> 0xa1
byteData[1][3]; ---> 0xb4
byteData[1].length ---> 4
参考
https://solidity-jp.readthedocs.io/ja/latest/types.html
https://medium.com/nayuta-inc/ethereum-solidity-%E5%9B%BA%E5%AE%9A%E9%95%B7%E3%83%90%E3%82%A4%E3%83%88%E5%88%97-813e925f49be