solidity에서는 문자열끼리 비교가 바로 불가능하다.
그 이유는 solidity가 불확실성을 싫어하는 언어이기 때문이다.
- string은 길이가 불분명(memory)해서 바로 비교 불가
- solidity는 불확실성을 싫어함
- 비교 불가 예시
- string-string (X)
- string to bytes로 변환 후, bytes memory-bytes memory (X)
- 비교 방법 : string → bytes → keccak256 변환 후 해시 함수를 비교해야 함
// 문자열 비교 function compare1(string memory _a, string memory _b) public pure returns(bool){ return keccak256(bytes(_a)) == keccak256(bytes(_b)); } function compare(string memory _a, uint _n1, string memory _b, uint _n2) public pure returns (bool) { return keccak256(abi.encodePacked(_a,n1)) == keccak256(abi.encodePacked(_b,n2)); }
- Keccak 해시 함수 패밀리에 속하는 암호학적 해시 함수
- Ethereum에서 사용되는 해시 알고리즘
- 256bits (32bytes)의 고정 크기 해시 값으로 출력
- keccak256은
bytes
형태의 input만 받음
: string, uint, bytes1 등은 사용 불가- output이 32bytes이므로 returns값을 bytes32로 설정
: bytes memory 사용 불가 (정적-동적 문제 발생)//사용법 function Keccak256() public pure returns(bytes32){ return keccak256(bytes("string")); }
bytes로 바꾸는 방법은 bytes외에도 abi.encodePacked, abi.encode 방법이 있다.
각 방법마다 특징이 있어 상황에 따라 알맞은 것을 사용하면 된다.
bytes가 아닌 값들을 abi.encodePacked, abi.encode, bytes를 통해 bytes형태로 변환할 수 있다. 각 방법의 특징 및 차이점은 다음과 같다. bytes의 경우 동적은 데이터 형태로 정적인 데이터들과는 호환이 불가하다. 이경우 abi를 사용하면 된다.
- EXAMPLE CODE
// keccak256 (abi.encodePacked) function compare1(string memory _a) public pure returns(bytes32){ return keccak256(abi.encodePacked(_a)); } // keccak256 (bytes) function keccak2(string memory _a) public pure returns(bytes32){ return keccak256(bytes(_a)); }