前書き
Solidityについて勉強しているうちに気になることが出てきました。それは「よくわかんないで使っていたabi.encodePacked()って実際なんなん?」ということでした。私は初心者プログラマーで、abi.encodePacked()をググって、ヒットしたものを読んでみてもちんぷんかんぷんだったので、実際に自分でコードを書いて(簡単にですが)検証してみました。
検証
TestAbiEncodePacked.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract TestAbiEncodePacked {
//試しに一回
function testAbiEncodePacked1() public pure returns (bytes memory) {
return abi.encodePacked("AAA", "BBB", "CCC");
// -> bytes: 0x414141424242434343
}
//違う文字列たちでもう一回
function testAbiEncodePacked2() public pure returns(bytes memory) {
return abi.encodePacked("DDD", "EEE", "FFF");
// -> bytes: 0x444444454545464646
}
//引数の個数を変えてもう一回
function testAbiEncodePacked3() public pure returns(bytes memory) {
return abi.encodePacked("DDD", "EEE");
// -> bytes: 0x444444454545
}
//引数の個数をもう一度変えてみる
function testAbiEncodePacked4() public pure returns(bytes memory) {
return abi.encodePacked("DDD");
// -> bytes: 0x444444
}
//何となく
function testAbiEncodePacked5() public pure returns(bytes memory) {
return abi.encodePacked("DDDEEE");
// -> bytes: 0x444444454545
}
//string型にキャスト
function testAbiEncodePackedWithStringCasting() public pure returns (string memory) {
return string(abi.encodePacked("AAA", "BBB", "CCC"));
// -> string: AAABBBCCC
}
//あらかじめ結合した文字列をBytesにしてみる。
function testStringToBytes() public pure returns (bytes memory) {
return bytes("AAABBBCCC");
// -> bytes: 0x414141424242434343
}
//こっちでも代用可能
function stringLine() public pure returns (string memory) {
return "AAA" "BBB" "CCC";
}
// 文字列→Bytes, Bytes→文字列は当然内容の変化はない。
}
わかったこと1
abi.encodePacked()の戻り値はbytes型
testAbiEncodePacked1/2関数を定義するときreturnsの型を設定しますが、bytesでコンパイルが通り、実行できました。
わかったこと2
引数の文字列を結合したものをBytes型に変換する。
結合した文字列の長さによりBytesの長さが変わる。(当たり前)
わかったこと3
戻り値をstring型にキャストすると、引数の文字列を結合しただけの文字列が返ってくる。
わかったこと4
わかったこと3の機能は下のようにして代用可能。それぞれの文字列が結合される。
return "AAA" "BBB" "CCC";
まとめ
abi.encodePacked()はstring型にキャストすることで引数の文字列を結合する働きを持っているようです。意外と単純な機能でした。