본문 바로가기
솔리디티/크립토좀비

레슨2 챕터 7, 8 - storage, memory

by 멸치김밥 2022. 2. 12.

storage는 블록체인에 영구적으로 저장되는 변수이고

memory는 호출되었다가 지워지는 임시적인 변수이다

 

storage는 하드디스크, memory는 램과 같다고 보면 된다.

 

보통 함수 외부에서 선언된 변수는 storage로 자동 선언되고 

함수 내부에서 선언된 변수는 memory로 자동 선언된다

 

크립토좀비에서 설명하는 예시를 보면

contract SandwichFactory {
  struct Sandwich {
    string name;
    string status;
  }

  Sandwich[] sandwiches;

  function eatSandwich(uint _index) public {
    // Sandwich mySandwich = sandwiches[_index];

    // ^ 꽤 간단해 보이나, 솔리디티는 여기서 
    // `storage`나 `memory`를 명시적으로 선언해야 한다는 경고 메시지를 발생한다. 
    // 그러므로 `storage` 키워드를 활용하여 다음과 같이 선언해야 한다:
    Sandwich storage mySandwich = sandwiches[_index];
    // ...이 경우, `mySandwich`는 저장된 `sandwiches[_index]`를 가리키는 포인터이다.
    // 그리고 
    mySandwich.status = "Eaten!";
    // ...이 코드는 블록체인 상에서 `sandwiches[_index]`을 영구적으로 변경한다. 

    // 단순히 복사를 하고자 한다면 `memory`를 이용하면 된다: 
    Sandwich memory anotherSandwich = sandwiches[_index + 1];
    // ...이 경우, `anotherSandwich`는 단순히 메모리에 데이터를 복사하는 것이 된다. 
    // 그리고 
    anotherSandwich.status = "Eaten!";
    // ...이 코드는 임시 변수인 `anotherSandwich`를 변경하는 것으로 
    // `sandwiches[_index + 1]`에는 아무런 영향을 끼치지 않는다. 그러나 다음과 같이 코드를 작성할 수 있다: 
    sandwiches[_index + 1] = anotherSandwich;
    // ...이는 임시 변경한 내용을 블록체인 저장소에 저장하고자 하는 경우이다.
  }
}

위 예시의 경우 storage를 사용한 mySandwich는 포인터가 되어

해당 값(Sandwich구조체의 sandwiches 배열의 _index에 해당하는 요소)에 직접 관여를 하게 된다.

memory를 사용한 anotherSandwich는 포인터가 아닌 복사해온 값이 되어

원본 sandwiches 배열에 영향을 주지 않는 차이가 있다

 


챕터 7 답

  // 컨트랙트 외부에서도 사용할 수 있는 feedAndMultiply함수 (public) 
  function feedAndMultiply(uint _zombieId, uint _targetDna) public {
  	// 사용자와 _zombieId로 찾은 zombieToOwner매핑값인 주소가 일치하면 통과
    require(msg.sender == zombieToOwner[_zombieId]);
    // myZombie변수에 zombies배열의 인덱스_zombieId에 해당하는 위치를 저장
    Zombie storage myZombie = zombies[_zombieId];
  }

챕터 8 답

    // 타겟DNA를 10의 16승으로 나눈 나머지로 만듦
    // (17자리 이상의 숫자는 10의16승인 16자리로 나눈 몫이 되므로 16자리로 만들어준다)
    _targetDna = _targetDna % dnaModulus;
    // 새로운DNA는 내좀비DNA와 타겟DNA의 평균
    uint newDna = (myZombie.dna + _targetDna) / 2;
    //  "NoName"이란 이름와 새로운DNA로 새 좀비 생성
    _createZombie("NoName", newDna);

댓글