
보통의 코딩언어들은 변수를 선언하면 스택이라던지, 힙이라던지 메모리에 저장되는것이 기본이다.
그러나 솔리디티에서는 어떤 변수들은 메모리가 아닌 파일 시스템에 저장된다.
메모리는 간단히는 컴퓨터의 RAM과 같은 메모리를 말한다. 그러나 솔리디티는 메모리가 아닌 하드 디스크와 같은 파일 시스템에 저장된다.
이해한 대로 내용을 정리해보자면,
먼저 솔리디티에서 변수타입의 종류는 크게 두가지로 나뉜다.
변수타입이나 종류에 따라 기본적으로 저장되는 위치가 정해져 있다.
그래서 이 기본적인 위치를 모르거나, 제대로 위치 저장을 하지 않으면 컴파일 에러를 일으킨다.
변수의 저장위치가 "메모리" 와 파일을 뜻하는 "스토리지" 두가지다.
변수의 종류별 기본 저장 위치는
복합 데이터 변수가 함수의 매개 변수로 쓰이면 기본적으로 저장위치는 "메모리"가 된다. 그러나 이들 복합 데이터 타입은 지시어를 사용하여 저장 위치를 지정 할 수 있다. 예를 들어 함수내 로컬 변수는 기본적으로 스토리지에 저장되지만, 아래와 같이 지시어를 사용하여 메모리에 저장하도록 할 수 있다.
contract Sample {
function Sample {
uint24[3] memory myArray3 = [1, 2, 9999];
}
}
함수 내 로컬변수는 기본적으로 "스토리지"에 저장되지만 지시어인 memory가 쓰여서 저장위치가 스토리지가 아닌 메모리가 된다.
contract의 최상단에 선언된 변수들을 상태변수라고 한다.
즉, 어떤 함수의 속한 변수가 아닌 컨트랙트에 속한 변수를 의미한다.
contract Sample{
int[] myArray = [0, 0];
string myString= "Solidity";
function Sample(uint index, int value){
myArray[index] = value;
int[] myArray2 = myArray;
uint24[3] memory myArray3= [1, 2, 9999];
uint8[2] myArray4= [1,2];
string myString2= myString;
string memory myString3= "ABCDE";
myString3= "XYZ";
string myString4= "Example";
}
}
위 코드에서 myArray 와 myString이 상태변수가 된다. 상태 변수의 기본 저장위치는 "스토리지" 이다.
즉 메모리가 아닌 파일에 저장된다.
int[] myArray = [0, 0]; 은 동적 배열을 상태 변수로 선언한 것이고, 여기서 [0, 0] 과 같이 배열 리터럴이 상태 변수에 나타나면 이 리터럴은 스토리지에 저장되고, 함수 내부에 나타나면 메모리에 저장된다. 따라서 이 코드의 경우 모두 스토리지에 저장된다.
uint24[3] memory myArray3 = [1, 2, 9999];
함수내에 위와 같이 선언된 것은 로컬변수이다. 즉, 상태 변수가 아닌 것이다.
로컬 변수의 기본 저장 위치는 스토리지 이다.
배열의 리터럴은 함수 내부에 나타나면 메모리에 저장된다고 했다. 그래서 위 경우는 메모리에 있는 값을 스토리지에 넣는 것이므로, 컴파일 에러가 발생해야 하는데 myArray3 변수에 memory 지시어를 사용하여 저장 위치를 메모리로 변경시켰기 때문에 에러가 발생하지 않는다.
하지만, 그아래의
uint8[2] myArray4 = [1, 2];
코드는 컴파일 에러가 발생한다. 왜냐면, 메모리에 있는 값을 스토리지에 넣으려고 했기 때문이다.
문자열도 배열과 동일하다. 문자열이 상태변수에 나타나면 스토리지에 저장된다.
contract Sample{
int[] myArray = [0, 0];
string myString= "Solidity";
...
}
코드 문자열 리터럴 "Solidity"는 스토리지에 저장된다.
string myString4 = "Example";
위코드는 컴파일 에러가 발생한다.
문자열 리터럴 "Example"은 함수 내부에 나타나므로 메모리에 저장된다.
그러나 myString4 는 함수 내부의 로컬변수 이므로 스토리지에 저장된다. 즉, 메모리에 있는 값을 스토리지에 넣으려고 하기 때문에 어레메시지가 발생한다.
Error: Type string memory is not implicitly convertible to expected type string storage pointer.