solidity 내에서도 주석을 사용할 수 있다.
먼저 //
은 한 줄 주석이다. 주석을 달 부분에 //를 추가하면 쉽게 주석을 달 수 있다.
또한 여러 줄의 주석을 사용하고 싶다면 /*
, */
을 사용하면 된다. 두개의 사이에 여러 줄의 주석을 사용하면 된다.
주석을 사용하여 자신이 코드를 작성한 의도를 적는 것이 좋다.
특히, 함수에서 예상되는 행동값을 자네의 코드에 주석으로 설명한다면, 다른 개발자들(또는 6개월 동안 프로젝트를 멈춘 후 자네 자신!)이 코드 자체를 다 읽어보지 않고 훑어보더라도 큰 맥락에서 그 코드를 이해할 수 있다.
Solidity에서는 특수한 형태의 주석을 사용하여 함수, 반환 변수 등에 대한 풍부한 문서를 제공할 수 있다.
이를 위해 NatSpec Format 이라고 한다.
NatSpec Format은 the Ethereum Natural Language Specification Fromat
의 약자로 solidity 커뮤니티에서 표준으로 쓰이는 주석 형식이다.
NatSpec Format으로 만들어진 주석은 컴파일러를 통해 따로 JSON 파일로 추출해 낼 수 있다.
또한 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;
}
}
위 예시에도 나타나 있듯이 NatSpec은 태그를 이용해 문서를 설명한다.
모든 태그들은 선택적이며, 만약 태그가 사용되지 않았다면 컴파일러는 해당 줄을 @notice
로 태그가 지정된 것으로 간주한다.
아래는 각 NatSpec 태그의 용도와 사용 위치를 설명하는 표이다.
Tag | Description | Context |
---|---|---|
@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 |
Solidity 컴파일러는 solidity 코드에서 JSON 출력으로 NatSpec 문서로 전달한다.
출력된 JSON은 최종 사용자에게 직접 제공하거나 일부 전처리를 적용할 수 있다.
예를 들어 어떠한 함수에 다음과 같은 NatSpec이 있다고 하자.
/// @notice This function will multiply `a` by 7
만약 함수가 호출되고 a
에 10이라는 값이 전달 되었다면, 최종 사용자에게는 다음과 같이 표기된다.
This function will multiply 10 by 7
이러한 동적 표현을 지정하는 것은 radspec 프로젝트에 자세하게 설명되어 있다.
NatSpec을 사용하지 않는 함수들은 자동으로 해당 컨트랙트의 기본 함수의 문서를 자동으로 상속한다.
이에 대한 예외는 다음과 같다.:
@inheridoc
태그가 존재할 경우// 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 출력에서는version
및kind
필드도 포함된다.
현재version
은1
로 설정되며,kind
는user
또는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"
}