본문 바로가기
Programing/Solidity

[Solidity] string memory와 bytes

by AustinProd 2022. 3. 10.

이번 시간에서 솔리디티 문법 중, 문자열(string)바이트(bytes) 코드에 대해 알아보자.

 

솔리디티 코드에는 가스(Gas)라는 비용이 포함된다. 개발자가 솔리디티 코드를 작성하는 목적은 이더리움 스마트 컨트렉트 구현에 있는데, 스마트 컨트렉트는 곧 블록체인을 수정(Update)하는 것으로 이더리움 네트워크에서 가스(Gas)라는 비용을 청구받게 된다. 달리 표현하면, 솔리디티 코드로 스마트 컨트렉트를 구현할 때, 해당 컨트렉트가 얼마만큼 이더리움 블록체인에 개입하는지에 따라 요금을 내야하는 것이다. (= 트렌젝션(Transaction) 복잡성과 가스(Gas)는 비례한다.)

 

왜 가스가 발생하는지, 트렌젝션 복잡성은 무엇인지에 대한 설명이 궁금하다면, Ethereum 카테고리를 참고하면 된다.

 

이번에 알아보는 문자열(string)과 바이트(bytes), 그리고 덧붙여 설명한 메모리(memory)에 대한 개념이 이와 직접적인 관계가 있다. 코드가 블록체인에 개입(Update)하는 정도를 감소시키기 위해 솔리디티는 문자열을 저장할 때 메모리를 활용하며, 문자열을 가공할 때 바이트로 치환한다.

 

빠른 이해를 위해 작성한 테스트 코드를 참고해 개념을 정리해보고자 한다.

 

// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.7.0 < 0.9.0;

contract learnStrings {   
    string favoriteColor = 'blue';

    function getColor() public view returns (string memory) {
        return favoriteColor;
    }

    function changeColor(string memory _color) public {
        favoriteColor = _color;
    }

    function getColorLength() public view returns (uint) {
        bytes memory stringToBytes = bytes(favoriteColor);
        return stringToBytes.length;
    }    
}

 

위 코드는 문자열의 길이(length)를 계산하는 컨트렉트다. 구성은 다음과 같다.

 

state 변수 = favoriteColor
getter 함수 = getColor
setter 함수 = changeColor
변수에 대한 길이 반환 함수 = getColorLength

 

예제 코드에서 집중해서 보아야할 부분은 setter 함수인 changeColor 의 문자열 파라미터 선언부와 길이 반환 함수 getColorLength 의 바이트 치환 로직이다.

 

string memory

문자열이 파라미터로 입력되거나 함수의 지역변수로 선언될 때, 솔리디티에서 memory 라는 옵션을 변수 선언부에 추가하도록 강제한다. 이 memory 옵션 태그는 해당 변수 데이터를 메모리에 저장할 것임을 명시하는 옵션으로 스토리지(Storage 혹은 이더리움 블록)에 포함시키지 않겠다는 뜻이다.

 

메모리에 데이터를 저장하면 어떻게될까? 메모리는 휘발성 저장소로 컨트렉트가 실행됐을 때 데이터를 저장되기 시작하지만, 로직이 종료되면 저장된 데이터는 날아간다. 컨트렉트 구현에 꼭 필요한 데이터라면 메모리에 저장하면 안되지만, 그렇지 않은, 즉, 함수 실행에만 필요한 데이터는 메모리에 잠시 저장해두었다가 사용하는 것이다.

 

솔리디티에 기본적인 데이터 타입 uint, bool, string 중 string에서만 memory 옵션 태그가 강제되는 건 문자열 데이터 타입이 uint, bool 타입에 비해 상대적으로 무겁기 때문이다. 이러한 이유로 이어서 살펴볼 바이트(bytes) 역시 memory 옵션이 붙는다.

 

bytes memory & bytes()

서론부에서 컨트렉트가 얼마나 블록체인에 개입하는지에 따라 가스(Gas)라는 비용 비례된다고 설명했다. 이는 "얼마나 컴퓨터 자원(Computational Work)을 잡아먹는가?"에 대한 또 다른 표현이다. 솔리디티에서 바이트(bytes)가 필요한 이유가 여기에 있다.

 

위 코드 예시에서 bytes는 문자열 길이를 반환하기 위해 중간에서 데이터를 치환하는 역할을 한다(string -> bytes). 이러한 이유는 string 형태에서 문자열 길이를 반환하는 컴퓨터 자원보다 bytes 형태에서 문자열 길이를 구하는 기대값이 높기 때문이다. 추가로 덧붙여, bytes 역시 문자열을 치환한 값이고, 스토리지에 직접 저장할 필요가 없는 데이터를 다루고 있기에 memory 옵션이 추가되었다. 

 

 

 

 

이상으로 string memory와 bytes에 대한 개념을 간단하게 살펴보았다. 위 내용을 한 줄로 요약하면, "솔리디티에서 컨트렉트를 구현할 때 컴퓨터 자원 사용을 최소화하기 위해 무거운 데이터 타입은 memory 라는 옵션과 바이트 코드를 활용한다."고 할 수 있겠다.

댓글