티스토리 뷰

반응형

솔리디티에서 함수를 정의할 때 함수 옆에 붙어서 제약을 걸어주는 키워드들이 존재한다. 이 키워드를 사용하면 그 함수에 부가적인 기능을 추가할 수 있는데 키워드들을 잘 사용하면 컨트랙트의 가스 비용을 줄이거나 간편하게 제약을 걸 수 있다.


view

솔리디티에서 view가 붙은 함수는 블록체인에서 상태를 변경하지 않고 값을 읽기만 하는 함수이다. view 함수는 단순히 데이터를 읽기만 하고 변경하지 않기 때문에, 다른 컨트랙트를 호출할 수 있지만 상태를 변경하는 함수는 호출할 수 없다. 따라서 view 함수는 블록체인 안에서 상태 변경이 발생하지 않으며, 실행될 때 가스비의 없이 무료로 실행된다.

 

다음은 view 함수의 예시이다.

pragma solidity ^0.8.0;

contract Example {
    uint256 public x = 1;
    uint256 public y = 2;

    function sum() public view returns (uint256) {
        return x + y;
    }
}

위 코드에서 sum() 함수는 view로 선언되어 있다. sum() 함수는 x와 y를 읽어서 두 값을 더한 결과를 반환한다. 이때, 반환 값에 필요한 x와 y를 읽어와 사용하기만 할 뿐 x와 y의 값을 변경하지는 않는다. 

 

view 함수 내부에서는 상태를 변경하는 모든 행위(값 변경 함수 호출 또는 전역 변수 값 변경)가 불가능하다. view 함수가 블록체인의 상태값을 변경하는 경우, 해당 함수가 호출되기 전 또는 호출되어 처리 중에 트랜잭션은 실패하게 된다.

 

view 함수는 블록체인의 상태를 변경하지 않기 때문에 호출시 컴파일러에 의해 최적화되어 가스 비용이 들지 않는다. 오직 데이터를 조회하기만 하기 때문에 다른 주소나 컨트랙트에도 영향을 미치지 않는다. 예를 들면, 특정 주소의 잔액을 확인하거나, 특정 토큰의 소유자를 확인하는 등의 작업을 수행할 수 있다.

pragma solidity ^0.8.0;

contract MyContract is ERC165, IERC721 {
    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;
    
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }
}

 

또 view 함수는 상태 변경이 필요하지 않은 읽기 전용 로직을 실행하는데 사용된다. view 함수는 다른 함수 형식과 함께 사용될 수 있으며, 컨트랙트의 변수나 함수를 수정하지 않는 것 외에는 일반적인 함수와 동일하게 작동된다. 

 

view 함수의 특징 요약

  • 상태 변경하지 않음 : view 함수는 함수 내부에서 상태를 변경하지 않고, 오로지 읽기 전용으로만 작동한다. 
  • 결과값 반환 : view 함수는 어떠한 값을 반환할 수 있으며, 함수 내부에서 계산 및 조회된 결과값을 반환한다.
  • 다른 view 함수 호출 가능 : view 함수는 다른 view 함수를 호출할 수 있다. 하지만 상태 변경을 일으키는 함수(payable, set함수 등)는 호출할 수 없다.
  • 가스 소모가 없는 함수 : view 함수는 호출할 때 가스 비용이 들지 않는다(컨트랙트 코드 실행 비용과는 별도).
  • 함수 수정자(modifier) 사용 가능 : view 함수에 modifier 사용가능. modifier는 함수 호출 전에 실행되는 코드로, 함수의 입력값을 체크하거나 로그를 남기는 작업을 수행한다.
  • 외부 데이터 접근 가능 : view 함수는 블록체인 외부에 저장된 데이터에 접근할 수 있다. 외부의 데이터를 읽어서 컨트랙트에서 활용할 수도 있다.

view 함수를 사용하기 적절한 상황

  • 함수 호출로 인해 변화하지 않는 계산이나 연산을 수행해야 하는 경우, view 함수를 사용해서 계산하고 결과를 반환할 수 있다.
  • 외부 컨트랙트나 블록체인의 상태를 읽어와야 하는 경우에 사용할 수 있다.

 


 

pure

솔리디티에서 pure가 붙은 함수는 블록체인에서 상태 변화를 일으키지 않고, 오로지 계산만 수행한다. 함수 내부에서 전역 변수 및 스토리지 변수를 읽지 않는 함수를 정의할 때 사용하는 키워드다. pure 함수는 외부에서 상호 작용할 필요없이, 함수의 매개 변수에 의존하여 반환 값을 돌려준다. 따라서 pure 함수는 자체적으로 스토리지를 읽거나 쓸 수 없고, 외부 컨트랙트나 블록체인의 상태를 변경하는 함수도 호출 할 수 없다. 

 

pure 함수는 view 함수보다 더 엄격한 조건을 가지며, 단순히 상태를 읽는 것 뿐만 아니라 입력값만으로도 반환 값을 계산해야 한다. 만약 pure 함수 내부에서 상태 변수를 읽거나 쓰게되면 컴파일러가 경고를 발생시킨다. 이러한 특징을 통해 함수의 실행 결과를 예측하고 최적화할 수 있게 된다. 

 

다음은 pure 함수의 예시이다.

pragma solidity ^0.8.0;

contract Calculator {
  function add(uint256 x, uint256 y) public pure returns (uint256) {
    return x + y;
  }
}

위 코드에서 add 함수는 두개의 uint256 입력값을 받고, 두 값의 합을 uint256 형태로 반환한다. 이 함수는 pure로 정의되어 있으므로 외부의 상태 변수에 의존하지 않으며, 이를 제외한 다른 함수나 상태 변경을 수행하지 않는다. 

 

pure 함수는 다른 함수 내부에서도 호출될 수 있고, 다른 pure 함수 내부에서도 호출될 수 있다. 또한 view와 pure를 함께 사용하는 것도 가능하다. 그리고 함수가 상태를 읽는 기능을 하지만, 계산을 수행할 때는 상태값을 필요로하지 않는 경우 view pure로 표시할 수 있다.

 

pure 함수는 외부에서 전달된 인자들을 가지고 계산한 결과값을 반환하는데 최적화되어 있으며 상태 변수나 다른 컨트랙트와 상호작용하지 않는다. 또 실행속도가 매우 빠르기에 안정적인 계산이 필요한 경우에 사용하기 좋다. 예를 들면, 덧셈, 뺄셈, 곱셈, 나눗셈과 같은 계산 작업을 수행하는 함수는 보통 pure 함수로 선언된다. 

pragma solidity ^0.8.0;

contract Calculators {
    function add(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    function subtract(uint256 a, uint256 b) public pure returns (uint256) {
        return a - b;
    }

    function multiply(uint256 a, uint256 b) public pure returns (uint256) {
        return a * b;
    }

    function divide(uint256 a, uint256 b) public pure returns (uint256) {
        require(b != 0, "Cannot divide by zero");
        return a / b;
    }
}

위 함수들은 컨트랙트 내부 상태를 변경하지 않기 때문에 pure 수식어를 사용할 수 있으며 이러한 특징 때문에 호출에 의해 발생하는 가스비용을 최소화 할 수 있다. 

 

pure 함수는 스마트 계약을 더 안전하게 만드는 데 사용될 수 있다. 왜냐하면 pure 함수는 다른 함수나 컨트랙트 내부에서 호출해도 안전하며, 실행 결과가 예측이 가능하기 때문이다. 

 

pure 함수의 특징 요약

  • 컨트랙트 내부 상태를 변경하지 않는다.
  • 함수 외부에서 접근이 가능하다.
  • 함수의 호출에 의해 발생한 가스비용이 최소화된다(view 함수보다 가스비용이 적게 든다).
  • 함수에서 반환값을 사용할 수 있다.

 

pure 함수를 사용하기 적절한 상황

  • 입력값에 대한 계산만 필요한 경우, pure 함수를 사용해서 계산하고 결과를 반환할 수 있다.
  • 상태 변경이 필요하지 않은 경우 사용할 수 있다.
  • 외부 호출 없이 로직을 수행하는 경우 사용할 수 있다.
반응형
댓글
공지사항