Solidity로 Smart Contract 구축하기4 - Solidity의 메모리 구조

2022. 9. 2. 15:36Block Chain

Solidity를 공부하면서 D_One님의 유투브를 참고하면서 공부하였습니다.

D_One님의 인프런 무료 강의도 있으니 참고하시면 좋을 것 같습니다.

 

D_One

솔리디티

 

이번 포스팅에서는 Solidity의 메모리 구조에 대해 알아보겠습니다.

메모리 구조

  1. storage
    • 전역 변수 및 함수들이 저장되며 영속적으로 저장되어 가스 비용이 비쌈
  2. memory
    • 함수의 지역 변수, 파라미터, 리턴값, 레퍼런스 타입이 주로 저장
    • 영속적으로 저장되지 않아서 가스 비용이 storage보다 쌈
  3. calldata
    • 함수의 파라미터 값을 주로 저장하며 memory와 비슷하게 동작함
    • 수정할 수 없고(non-modifiable), 영속적이지 않음(non-persistent)
  4. stack
    • EVM(Ethereum Virtual Machine)에서 stack data를 관리할 때 쓰는 영역, 1024MB로 제한적

위 내용은 D_One님의 유투브 내용과 다소 차이가 있습니다.

공식 문서에 따르면 0.6.9 버전 이전에는 reference-type arguments가 external fucntions의 경우 calldata로, public functions의 경우 memory로, internal and private functions는 memory or storage로 제한되었지만, 현재는 functions의 visibility에 관계없이 memorycalldata를 사용할 수 있습니다.

또한 calldata와 같은 경우 불변을 보장해주고 복사를 방지할 수 있기 때문에 calldata를 사용하기를 권장하고 있습니다.

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

contract C {
    // The data location of x is storage.
    // This is the only place where the
    // data location can be omitted.
    uint[] x;

    // The data location of memoryArray is memory.
    function f(uint[] memory memoryArray) public {
        x = memoryArray; // works, copies the whole array to storage
        uint[] storage y = x; // works, assigns a pointer, data location of y is storage
        y[7]; // fine, returns the 8th element
        y.pop(); // fine, modifies x through y
        delete x; // fine, clears the array, also modifies y
        // The following does not work; it would need to create a new temporary /
        // unnamed array in storage, but storage is "statically" allocated:
        // y = memoryArray;
        // This does not work either, since it would "reset" the pointer, but there
        // is no sensible location it could point to.
        // delete y;
        g(x); // calls g, handing over a reference to x
        h(x); // calls h and creates an independent, temporary copy in memory
    }

    function g(uint[] storage) internal pure {}
    function h(uint[] memory) public pure {}
}

위 코드는 Solidity의 공식 문서에서 발췌하였습니다. 공식 문서에 따르면

  • storage에서 memory로 혹은 memory에서 storage로 (혹은 calldata로부터) 변수를 할당할 경우 각각의 독립된 복사본을 만듭니다. (x, function h)
  • memory에서 memory로 변수를 할당할 경우 사본이 아닌 reference가 생성됩니다. 즉, 한 변수를 수정하면 같은 참조값을 갖고 있는 다른 모든 변수에도 반영됩니다.
  • storage에서 local의 storage로 변수를 할당할 경우에도 reference가 생성됩니다. (y, function g)
  • 이 외의 모든 storage로 변수를 할당하는 경우에는 복사본이 생성됩니다.

 

이번에는 Solidity의 메모리 구조에 대해 알아봤습니다. 혹시 어려운 점이나 틀린 부분이 있다면 댓글 부탁드립니다.

 

감사합니다.