바이트: bytes와 bytes32
bytes 는 텍스트가 아닌 원시 바이트 데이터(raw binary) 를 다루는 타입입니다.
해시값, 서명, 인코딩된 데이터처럼 사람이 읽지 않는 이진 데이터를 저장할 때 사용합니다.
크게 두 가지 형태가 있습니다.
- 고정 크기
bytes1~bytes32: 정해진 길이의 바이트 묶음(값 타입) - 가변 크기
bytes: 길이가 변하는 바이트 배열(참조 타입)
데이터 크기가 32바이트 이하로 고정되어 있다면 bytes32 가 string 보다 가스 효율이 좋습니다.
고정 크기 bytesN
bytes1 부터 bytes32 까지는 길이가 컴파일 타임에 정해진 값 타입입니다. EVM 의 기본 워드가
32바이트라서 bytes32 가 한 슬롯에 딱 맞아 가장 자주 쓰입니다. 16진수 리터럴로 직접 값을 줄 수
있으며, 인덱스로 개별 바이트에 접근할 수 있습니다(data[0]).
언제 무엇을 쓰나
해시값(예: keccak256 결과)은 항상 32바이트이므로 bytes32 에 딱 맞습니다.
반면 길이가 미리 정해지지 않은 임의의 바이너리 데이터에는 가변 bytes 를 사용합니다.
가변 bytes 는 참조 타입이라 함수 인자·반환에서 memory/calldata 위치를 명시해야 합니다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract BytesExample {
bytes32 public hash = keccak256("hello"); // 항상 32바이트 → bytes32
bytes1 public flag = 0xff; // 1바이트 고정
bytes public data = hex"001122"; // 가변 길이 바이트
function firstByte() public view returns (bytes1) {
return data[0]; // 인덱스로 개별 바이트 접근
}
}string 과 가변 bytes 는 내부 구조가 비슷하지만 의도가 다릅니다. string 은 사람이 읽는
텍스트이고, bytes 는 기계가 다루는 이진 데이터입니다. 텍스트 길이를 세거나 비교할 때 흔히
bytes(myString).length 처럼 잠깐 bytes 로 변환해 다룹니다.