dev/Solidity

Storage, Memory and Calldata

_April 2022. 3. 27. 03:57

Variables are declared as either storage, memory or calldata to explicitly specify the location of the data.

  • storage - variable is a state variable (store on blockchain)
  • memory - variable is in memory and it exists while a function is being called
  • calldata - special data location that contains function arguments

 

-스토리지가 당연히 가스비가 제일 많이든다.

 

-메모리

이때 말하는 메모리는 evm의 메모리

https://ethereum.org/en/developers/docs/evm/#evm-instructions

During execution, the EVM maintains a transient memory (as a word-addressed byte array), which does not persist between transactions.

evm이 실행되면 임시메모리를 유지한다. 이 메모리는 임시이기 때문에 트젝간 유지/공유되지 않는다.

 

-calldata

The Calldata is a read-only byte-addressable space where the data parameter of a transaction or call is held

데이터 파라미터 = 아규먼트

calldata is where data from external calls to functions is stored.

When such an external call happens, the data of that call is stored in calldata.

 

 

https://docs.soliditylang.org/en/v0.8.13/types.html#data-location

모든 복합 타입은 자신이 메모리 나 스토리지 중 어디에 저장되었는지를 나타내는 "데이터 위치"가 추가적으로 존재합니다.

Calldata is a non-modifiable, non-persistent area where function arguments are stored,

and behaves mostly like memory.

 

✅If you can, try to use calldata as data location because it will avoid copies

and also makes sure that the data cannot be modified.

Arrays and structs with calldata data location can also be returned from functions,

but it is not possible to allocate such types.

가능하면 콜데이터를 써라. 카피를 피하고, 데이터 변경을 막기 때문임

->콜데이터 타입의 어레이와 스트럭(데이터) 는 펑션으로부터 리턴될수 있다.

그러나 그런타입을 할당할 수 없다...? 무슨말이지..?

 

✅Prior to version 0.6.9 data location for reference-type arguments was limited to calldata in external functions, memory in public functions and either memory or storage in internal and private ones. Now memory and calldata are allowed in all functions regardless of their visibility.

 

옛날엔 콜데이터와 메모리, 스토리지의 사용처가 엄격하게 제한되었다.

이제는 콜데이터와 메모리를 모든 visibility 상관없이 모든 펑션에서 쓸수있다.

 

✅Prior to version 0.5.0 the data location could be omitted, and would default to different locations depending on the kind of variable, function type, etc., but all complex types must now give an explicit data location.

옛날엔 데이터 로케이션 지정을 안해도 됐다.

변수 종류/ 펑션 타입따라 기본 로케이션이 있었기 때문이었음

그러나 모든 컴플렉스타입은 data location 을 꼭 지정해야함

Complex types, i.e. types which do not always fit into 256 bits have to be handled more carefully than the value-types we have already seen. 

솔리디티 기본 데이터타입(bool, integer, comparison 이런거..) 말고 

  • Arrays
  • Structs
  • Mapping

이런거의 경우 꼭 지정하라는말임

 

 

데이터 위치와 assignment(배치)행위

데이터 위치설정은 -데이터의 지속성, -할당의 의미 와 관계가 있다.

  • Assignments between storage and memory (or from calldata) always create an independent copy.
  • Assignments from memory to memory only create references.
    This means that changes to one memory variable are also visible in all other memory variables
    that refer to the same data.
  • Assignments from storage to a local storage variable also only assign a reference.
  • All other assignments to storage always copy.
    Examples for this case are assignments to state variables or
    to members of local variables of storage struct type, even if the local variable itself is just a reference.

 

전역변수는 무조건 스토리지에 저장됨. 데이터 로케이션 생략 가능

  • Assignments between storage and memory (or from calldata) always create an independent copy.

스토리지-메모리(콜데이터)간 배치는 무조건 독립된 카피를 야기한다.

 -스토리지데이터 x= 메모리어레이 줄에서 어레이의 카피가 일어남

 

  • Assignments from memory to memory only create references.
    This means that changes to one memory variable are also visible in all other memory variables
    that refer to the same data.

메모리-메모리간 assignment는 레퍼런스만 만든다. (포인터를 지정해서 메모리 참조만 한다는 뜻인듯)

그래서 한쪽 메모리할당된 값을 변경하면 다른쪽에서도 변경된 값을 볼수있음

 - 예시가 좀 이상함.. 메모리- 메모리 간이라고 해놓고 예시는 스토리지- 스토리지간임

   스토리지에 저장된 x와 스토리지에 저장된 y 를같다고 assign 하면 포인터로 가리키게됨

 - 예시로 y를 pop하든, x를 del하든 상호 값이 동기화됨을 보여줌

 -스토리지-스토리지 간 assignment도 레퍼런스만 만드나봄..

 

  • Assignments from storage to a local storage variable also only assign a reference.

스토리지 - 로컬스토리지간 어사인먼트도 포인터만만듬

 -functiong g 얘기인듯 

 -local storage variable is a variable defined inside a function. (The scope of the variable is limited to the function)

 

  • All other assignments to storage always copy.
    Examples for this case are assignments to state variables or
    to members of local variables of storage struct type, even if the local variable itself is just a reference.

다른 경우의 storage 어사인먼트는 무조건 카피를 발생시킨다.

이 경우 로컬 변수 자체가 참조에 불과하더라도 상태 변수 또는 스토리지 구조 유형의 로컬 변수 멤버에 대한 할당이 해당됩니다.

 

 

2019자료 확인필요

 

어렵넹