Solidity의 스토리지 및 메모리 비밀

이번에는 Solidity 프로그래밍 언어의 저장소 위치, 특히 storagememory 위치에 대해 이야기하겠습니다. 그들이 나타내는 것과 작동 방식을 모르면 스마트 계약에 문제가 발생할 수 있습니다.

저장



스마트 계약의 스토리지는 함수 호출 사이에 데이터를 보관합니다. 우리는 storage가 컴퓨터의 하드 드라이브라고 상상할 수 있습니다. 전원을 꺼도 데이터는 지워지지 않고 그대로 남아 있습니다. 블록체인에서는 저장소에 작성한 내용이 저장됩니다.

기본적으로 저장



상태 변수



기본적으로 Solidity는 스토리지 스마트 계약의 상태 변수를 보관합니다.

contract StorageContract {
  struct LuckyNumber {
    uint256 number;
    string reason;
  }

  mapping(address => LuckyNumber) luckyNumbers;
}


이 예에서 스마트 계약의 상태 변수luckyNumbers는 저장소에 보관되며 데이터는 함수 호출 간에 유지됩니다.

행운의 숫자를 더하고 얻으면 예측 가능한 결과가 나옵니다.

function addLuckyNumber(LuckyNumber memory luckyNumber) external {
  require(luckyNumber.number != 0, "Lucky number can't be 0!");
  require(luckyNumbers[msg.sender].number == 0, "You already have set lucky number. Edit it if you have another one.");

  luckyNumbers[msg.sender] = luckyNumber;
}

function getMyLuckyNumber() external view returns(uint256) {
  require(luckyNumbers[msg.sender].number != 0, "You don't have a lucky number set yet.");

  LuckyNumber memory luckyNumber = luckyNumbers[msg.sender];

  return luckyNumber.number;
}


로컬 함수 변수



구조체, 배열 또는 매핑의 로컬 함수 변수는 기본적으로 저장소에 저장됩니다. 즉, 함수에서 이러한 값을 선언하면 스토리지에 보관되어 추적하기 어려운 예기치 않은 문제가 발생할 수 있습니다.

코드 예제에 함수editLuckyNumber를 추가하고 로컬 복사본을 storage로 표시하면 기대하는 상태 변수가 편집됩니다.

function editLuckyNumber(uint256 luckyNumber) external {
  require(luckyNumber != 0, "Lucky number can't be 0!");
  require(luckyNumbers[msg.sender].number != 0, "You don't have a lucky number set yet.");

  LuckyNumber storage _luckyNumber = luckyNumbers[msg.sender];
  _luckyNumber.number = luckyNumber;
}


메모리



메모리에서 Solidity는 단위, 문자열 등이 될 수 있지만 배열, 구조체 또는 매핑이 아닌 로컬로 정의된 모든 값 유형을 유지합니다. 함수 인수도 메모리에 보관됩니다. memory는 스마트 계약 수준에서 사용할 수 없으며 함수에서 로컬로만 사용할 수 있습니다.

function multiplyByItself(uint256 number) external pure returns(uint256) {
  uint256 result = number * number;

  return result;
}


이 예에서 함수에 전달하는 함수 인수number는 메모리에 저장됩니다. 또한 result의 로컬 정의 변수는 메모리에 저장되었다가 함수 실행이 종료되는 즉시 해제됩니다.

메모리와 스토리지를 사용하는 함정



Solidity 프로그래밍 언어에서 storagememory 키워드를 잘못 사용하는 주요 함정 중 하나는 변수를 깊이 생각하지 않고 storage 또는 memory로 선언한다는 것입니다. 첫째, 데이터를 storage에 보관하면 블록 공간에 대한 비용을 지불해야 하기 때문에 더 많은 가스를 소비합니다. 둘째, 함수 호출 사이에 보관하는 데이터에 액세스해야 하는지 자문해야 합니다. 함수 호출에 의해 두 가지 다른 함수가 있을 수도 있습니다.
_luckyNumber 키워드를 사용하여 함수editLuckyNumber에서 memory를 정의하면 이 함수는 로컬에서만 편집되며 변경 사항은 블록체인에 기록되지 않습니다.

function editLuckyNumber(uint256 luckyNumber) external {
  require(luckyNumber != 0, "Lucky number can't be 0!");
  require(luckyNumbers[msg.sender].number != 0, "You don't have a lucky number set yet.");

  LuckyNumber memory _luckyNumber = luckyNumbers[msg.sender];
  _luckyNumber.number = luckyNumber;
}


이 함수의 결과는 행운의 숫자를 로컬에서만 업데이트하기 때문에 작동하지 않는 편집 결과를 낳습니다.

TL;DR



스마트 계약에서 Solidity 언어를 사용하여 데이터를 저장하는 것은 매우 중요합니다. 값 유형을 사용하면 삶이 더 쉬워지지만 배열, 구조체 및 매핑을 사용하면 더 까다롭습니다. 그렇기 때문에 이러한 변수를 저장하고 싶을 때마다 물어보는 것이 중요합니다. 스마트 계약을 호출하거나 함수를 실행하는 동안 로컬에 저장되는 동안 데이터가 지속되기를 원합니까?

연결


  • Sample code
  • What is the memory keyword? What does it do?
  • Storage vs Memory in Solidity
  • In Ethereum Solidity, what is the purpose of the "memory" keyword?
  • 좋은 웹페이지 즐겨찾기