[Solidity] NatSpec Format

bolee·2022년 12월 25일
0

솔리디티(Solidity)

목록 보기
8/8
post-thumbnail

Solidity Comment

solidity 내에서도 주석을 사용할 수 있다.

먼저 // 은 한 줄 주석이다. 주석을 달 부분에 //를 추가하면 쉽게 주석을 달 수 있다.
또한 여러 줄의 주석을 사용하고 싶다면 /*, */을 사용하면 된다. 두개의 사이에 여러 줄의 주석을 사용하면 된다.

주석을 사용하여 자신이 코드를 작성한 의도를 적는 것이 좋다.
특히, 함수에서 예상되는 행동값을 자네의 코드에 주석으로 설명한다면, 다른 개발자들(또는 6개월 동안 프로젝트를 멈춘 후 자네 자신!)이 코드 자체를 다 읽어보지 않고 훑어보더라도 큰 맥락에서 그 코드를 이해할 수 있다.


NatSpec Format

Solidity에서는 특수한 형태의 주석을 사용하여 함수, 반환 변수 등에 대한 풍부한 문서를 제공할 수 있다.

이를 위해 NatSpec Format 이라고 한다.
NatSpec Format은 the Ethereum Natural Language Specification Fromat의 약자로 solidity 커뮤니티에서 표준으로 쓰이는 주석 형식이다.

NatSpec Format으로 만들어진 주석은 컴파일러를 통해 따로 JSON 파일로 추출해 낼 수 있다.
또한 NatSpec Format은 개발자 중심 메세지와 최종 사용자 대상 메세지로 구분되며, 이러한 메세지는 컨트랙트와 상호작용할 때(즉, 트랜잭션에 서명할 때) 최종 사용자에게 표시될 수 있다.

NatSpec Format 예시

NatSpec Format은 컨트랙트에서 각각 contract, interface, library, function, event, 변수(vaiable)들에서 사용할 수 있다.

한 줄을 위한 NatSpec Format은 ///을 사용하고, 여러 줄을 위한 NatSpec Format은 /**, */을 사용한다.

아래는 NatSpec 예시이다.

/// @title 기본적인 산수를 위한 컨트랙트
/// @author H4XF13LD MORRIS 💯💯😎💯💯
/// @notice 지금은 곱하기 함수만 추가한다.
contract Math {
  /// @notice 2개의 숫자를 곱한다.
  /// @param x 첫 번쨰 uint.
  /// @param y 두 번째 uint.
  /// @return z (x * y) 곱의 값
  /// @dev 이 함수는 현재 오버플로우를 확인하지 않는다.
  function multiply(uint x, uint y) returns (uint z) {
    // 이것은 일반적인 주석으로, natspec에 포함되지 않는다.
    z = x * y;
  }
}

태그(Tags)

위 예시에도 나타나 있듯이 NatSpec은 태그를 이용해 문서를 설명한다.
모든 태그들은 선택적이며, 만약 태그가 사용되지 않았다면 컴파일러는 해당 줄을 @notice로 태그가 지정된 것으로 간주한다.

아래는 각 NatSpec 태그의 용도와 사용 위치를 설명하는 표이다.

TagDescriptionContext
@title컨트랙트, 라이브러리, 인터페이스를 설명하는 제목contract, library, interface
@author저자의 이름contract, library, interface
@notice이것이 무엇을 하는지 최종 사용자에게 제공되는 설명contract, library, interface, function, public state variable, event
@dev개발자에게 제공되는 추가 세부 정보contract, library, interface, function, state variable, event
@param함수 또는 이벤트의 매개변수에 대한 설명(@param 뒤에 매개변수 이름과 그에 대한 설명이 와야 한다.)function, event
@return반환되는 변수에 대한 설명
여러 개의 값을 반환하는 경우 여러면 @return을 사용하여 표기하면 된다.
function, public state variable
@inheritdoc기본 기능에서 누락된 모든 태그들을 복사한다.(@inheritdoc 뒤에 컨트랙트 이름이 와야 함)function, public state variable
@custom:...사용자 정의 태그
뒤에 하나 이상의 소문자 또는 하이픈(-)이 와야 한다. 하지만 하이픈으로 시작할 수 없다.
개발자 문서의 일부이다.
everywhere

Dynamic expressions

Solidity 컴파일러는 solidity 코드에서 JSON 출력으로 NatSpec 문서로 전달한다.
출력된 JSON은 최종 사용자에게 직접 제공하거나 일부 전처리를 적용할 수 있다.

예를 들어 어떠한 함수에 다음과 같은 NatSpec이 있다고 하자.

/// @notice This function will multiply `a` by 7

만약 함수가 호출되고 a에 10이라는 값이 전달 되었다면, 최종 사용자에게는 다음과 같이 표기된다.

This function will multiply 10 by 7

이러한 동적 표현을 지정하는 것은 radspec 프로젝트에 자세하게 설명되어 있다.

Inheritance Notes

NatSpec을 사용하지 않는 함수들은 자동으로 해당 컨트랙트의 기본 함수의 문서를 자동으로 상속한다.

이에 대한 예외는 다음과 같다.:

  • 매개변수 이름이 다른 경우
  • 하나 이상의 기본 기능이 있는 경우
  • 문서 상속의 사용할 컨트랙트를 지정하는 명시적인 태그인 @inheridoc 태그가 존재할 경우

Documentation Output

// ex1.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 < 0.9.0;

/// @title A simulator for trees
/// @author Larry A. Gardner
/// @notice You can use this contract for only the most basic simulation
/// @dev All function calls are currently implemented without side effects
/// @custom:experimental This is an experimental contract.
contract Tree {
    /// @notice Calculate tree age in years, rounded up, for live trees
    /// @dev The Alexandr N. Tetearing algorithm could increase precision
    /// @param rings The number of rings from dendrochronological sample
    /// @return Age in years, rounded up for partial years
    function age(uint256 rings) external virtual pure returns (uint256) {
        return rings + 1;
    }

    /// @notice Returns the amount of leaves the tree has.
    /// @dev Returns only a fixed number.
    function leaves() external virtual pure returns(uint256) {
        return 2;
    }
}

컴파일러에 의해 구문 분석될 때 위와 같은 예제는 두개의 서로 다른 JSON 파일을 생성한다.
하나는 최종 사용자가 기능 실행 시 알림으로 사용하기 위한 것이고, 다른 하나는 개발자가 사용하가 위한 것이다.

다음과 같은 명령어로 생성할 수 있다.

solc --userdoc --devdoc ex1.sol

Note
solidity 0.6.11 버전 이후로 NatSpec 출력에서는 versionkind 필드도 포함된다.
현재 version1로 설정되며, kinduser 또는 dev이어야 한다.
추후 이전 버전을 더 이상 사용하지 않는 새 버전이 도입될 수도 있다.

사용자 문서 예시

{
  "version" : 1,
  "kind" : "user",
  "methods" :
  {
    "age(uint256)" :
    {
      "notice" : "Calculate tree age in years, rounded up, for live trees"
    }
  },
  "notice" : "You can use this contract for only the most basic simulation"
}

개발자 문서 예시

{
  "version" : 1,
  "kind" : "dev",
  "author" : "Larry A. Gardner",
  "details" : "All function calls are currently implemented without side effects",
  "custom:experimental" : "This is an experimental contract.",
  "methods" :
  {
    "age(uint256)" :
    {
      "details" : "The Alexandr N. Tetearing algorithm could increase precision",
      "params" :
      {
        "rings" : "The number of rings from dendrochronological sample"
      },
      "return" : "age in years, rounded up for partial years"
    }
  },
  "title" : "A simulator for trees"
}

참고 자료

0개의 댓글