금붕어의 솔리디티 문법 사전 - Solidity syntax

2022. 3. 30. 11:10프로그래밍/도서관

728x90

Version Pragma

이 코드가 컴파일 될 수 있는 솔리디티 버전을 뜻한다.
버전이 다르면 컴파일이 불가능할수도 있기 때문.

// 코드 최상단에 작성

// 특정 버전
pragma solidity 0.4.19;

// 특정 버전 이상
pragma solidity ^0.4.19;

주석 (Comment)

주석은 자바스크립트와 동일하다.

// 이 내용은 주석입니다.

/*
   이 줄은 여러줄의 주석입니다.
*/

/// @title 제목. 설명
/// @author 작성자 이름
/// @notice 사용자에게 이 컨트랙트/함수가 무엇을 하는지 알려준다.
contract Math {
    // 여기부터는 함수 natspec
    
    /// @notice 함수에_대한_설명
    /// @param 인자명 인자에_대한_설명
    /// @return 반환변수명 반환내용에 대한 설명
    /// @dev 개발자가 읽으라고 써놓는 것
    function multiply(uint x, uint y) returns (uint z) {
        // 이것은 일반적인 주석으로, natspec에 포함되지 않는다.
        z = x * y;
    }

}

 


변수

변수 선언은 C와 유사하며,
'자료형 변수명'으로 적는다.
뒤에 =을 붙여서 초기값을 설정할 수 있다.

storage: 블록체인 상에 영구적으로 저장됨.
외부 호출이 종료되어도 값이 유지된다.
함수 외부의 상태 변수는 storage가 기본값이다.

memory: 임시적으로 저장되며,
외부 호출이 끝나면 사라진다.
함수 내부의 변수는 memory가 기본값이다.

uint a = 10;
uint storage b;
uint memory c;

배열

특정 자료형 여러개를 하나의 변수명으로 사용.

정적 배열: 크기가 정해져있으며, 자로형 뒤에 [n]과 같이 적는다.
동적 배열: 크기가 사용할수록 늘어나며, 자료형 뒤에 []와 같이 적는다.

// 정적 배열
uint[5] a;

// 동적 배열
uint[] b;

// 맨 마지막에 삽입
a.push(1);

// 삽입 후 총 길이 가져오기
uint length = a.push(2);

메모리에 배열 선언하기

메모리에 선언된 배열은 가스를 소모하지 않는다.
(실제 storage의 값을 변경하지 않기 때문)

메모리에 배열을 선언할 때는 이 세가지를 기억하자.

1. new 키워드를 사용한다.
2. 크기를 정해준다.
3. 변수명 앞에 memory를 붙여준다.
uint[] memory values = new uint[](3);

자료형

자료형 설명 예시
uint 부호 없는 정수 uint a = 8;
int  부호 있는 정수 int b = -7;
string 문자열 string c = "abc";
address 계정의 주소 address sender = msg.sender;

구조체

여러가지 변수를 담는 복잡한 변수이다.
자료형의 일부이므로 다른 자료형과 동일하게 사용하면 된다.

객체 생성시, 구조체에서 선언한 순서대로 인자를 넣어야 한다.

// 선언
struct Test {
  uint id;
  string name;
}

// 변수 선언
Test test;

// 객체 생성
test = Test(_id, _name);

매핑

key-value 형식의 자료구조.

// 매핑 형식
mapping (key_자료형 => value_자료형) 접근제어자 변수명;

// 매핑 선언 예시
mapping (address => uint) public accountBalance;

// 사용법
accountBalance[someAddress] = 10;

접근제어자

Public: 다른 스마트 컨트랙트에서 접근할 수 있다.
Private: 다른 스마트 컨트랙트에서 접근할 수 없다.

internal: 상속한 컨트랙트에서 사용 가능하다. 그 외에는 private과 동일.
external: 내부에서 호출할 수 없다. 그 외에는 public과 동일.

// 변수 접근제어자
uint public id1 = 10;
uint private id2 = 7;

// 함수 접근 제어자 (public이 기본값)
// private 함수는 _로 시작하는 것이 관례
function _foo() private {}
function bar() public {}

함수

함수는 로직을 묶어서 반복할 수 있게 해준다.

// 형식
function 함수명(자료형 _인자명1, 자료형 _인자명2, ...) 접근제어자 함수제어자 returns (반환자료형) {}

함수명: private이면 앞에 _를 붙이는 것이 관례
인자명: 앞에_를 붙이는 것이 관례
접근제어자: private / public / external / internal
함수제어자
 - view: 컨트랙트 내의 값을 조회만 하는 경우 (작성 X)
 - pure: 컨트랙트 내의 값을 조회도 하지 않고, 인자로만 작동하는 함수 (작성, 조회 X)
 - 커스텀 함수제어자: modifier로 선언된 함수 제어자.
반환자료형: uint, int, string 등

// 예제
function _sayHello(string _a) private returns (string) { return _a; }

// 호출
sayHello("Hello world");

함수 - 다중 반환

여러개의 값들을 반환할 수 있다.
Javascript와 TypeScript의 Tuple과 같다.
순서에 따라서 대입되는 값이 달라진다.

function foo() returns (
  uint a,
  string b,
  int c
) {
  return (1, "b", 3);
}

함수 - 함수 제어자

함수 제어자는 4가지 종류가 있다.

1. view: 조회만 하는 함수.
2. pure: 인자로만 산출하는 함수.
3. payable: ether(이더) 소모를 할 수도 있는 함수
4. 사용자 지정 함수 제어자: 직접 작성할 수 있는 함수 제어자.

사용자 지정 함수 제어자는 다음의 문법으로 선언한다.

// 인자 없는 함수 제어자 선언
modifier foo() {}

// 인자 없는 함수 제어자 호출
function fooBar() foo {}

// 인자 있는 함수 제어자 선언
modifier foo(uint bar) {
  ... something
  
  // _;은 이 함수 제어자를 호출한 함수로 돌아가는 코드다.
  _;
}

// 인자 있는 함수 제어자 호출
function fooBar() foo(10) {}

함수 - 구조체 인수로 전달하기

storage 키워드와 함께 전달하면
storage의 포인터가 전달되어
실제 storage의 값을 수정할 수 있다.

function _doStuff(Zombie storage _zombie) internal {
  // 실제 스토리지도 업데이트
  _zombie.name = "abc";
}

형변환

'자료형(값)'의 형태로 변환한다.

uint8 a = 5;
uint b = 6;
// b를 uint -> uint8으로 형변환
uint8 c = a * uint8(b);

이벤트

이벤트는 사용자가 특정한 액션을 했을 때 호출하는 함수다.

컨트랙트에서는 정의와 호출만 한다.
유저단에서는 이벤트를 구독한 후, 이벤트가 호출되면 구독한 함수가 실행된다.


require

자바스크립트의 if와 throw를 합쳤다.
참이면 문제없이 지나가고,
거짓이면 에러와 함께 실행이 중단된다.

특정 조건을 만족하는지 확인할 때
주로 사용한다.

// 문자열 비교.
require(keccak256(a) == keccak256(b));

// 기타 비교
require(a == b);

상속

부모 컨트랙트의 일부를 사용할 수 있다.
(private 제외)

// 부모 컨트랙트
contract A { }

// 자식 컨트랙트 (부모의 public 변수, 함수 사용 가능)
contract B is A {}

// 다중 상속
contract B is A, C {}

import

다른 파일을 불러올 수 있다.
한 파일에 있는 것과 같은 효과를 가질 수 있다.
단, 모듈 단위로 import하진 않는다.

import "./zombiefactory.sol";

전역 변수 (msg)

전역에서 사용할 수 있는 변수다.
외부 호출한 사람등을 알 수 있다.

// 호출한 사람(계정)의 주소
msg.sender (address 형식)

컨트랙트

솔리디티 구조의 기본이다.

contract A {

}

인터페이스

컨트랙트와 형식은 같지만,
정의가 아닌 선언만 한다.

외부 블록의 컨트랙트와 통신할 때 사용된다.

'이런 형식의 함수를 호출할 것이다'를 알려주는
일종의 프로토콜이다.

// 인터페이스 선언
contract TestInterface {
  // 정의 없이 형식 선언만 한다.
  function getNum(address _myAddress) public view returns (uint);
}

// 인터페이스 사용
// 인터페이스 객체 생성시, 외부 주소로 초기화한다.
contract TestContract {
  address targetAddress = ...;
  TestInterface testInterface = TestInterface(targetAddress);

  function foo() public {
    // 인터페이스 객체를 통해 통신한다.
    uint num = testInterface.getNum(msg.sender);
  }
}

for 문법

솔리디티의 for문법은 자바스크립트와 유사하다.

for (uint i = 0; i < zombies.length; i++) {

}

시간 단위

솔더리티에서는 연, 주, 일, 시, 분, 초에 해당하는 시간 단위를 지원해준다.

1 years: 1년
1 weeks: 1주
1 days: 1일
1 hours: 1시간
1 minustes: 1분
1 seconds: 1초

// 예제
return now >= lastUpdated + 5 minutes;

now 전역변수로 현재 시간을 UNIX 타임스탬프로 얻을 수 있다.
(now는 기본적으로 uint256이므로 다른 타입에 대입할때는 형변환이 필요하다)

now

컨트랙트에 쌓인 이더리움 가져오기

this.balance

해당 주소로 이더 전송하기

address a = ...;
a.transfer(...)

라이브러리 & using

라이브러리 선언은 library 키워드를 이용해서 한다.
라이브러리는 특정 native 타입에 함수를 붙일 수 있다.

// 컨트랙트와 위치가 같음
library MyLibrary { }

다른 컨트랙트에서 라이브러리를 사용할 때는 using을 사용한다.

import "./mylibrary.sol";

contract Test {
  using ??? for uint64;
}

 

 

'프로그래밍 > 도서관' 카테고리의 다른 글

[단어장] Bundler, Transpiler, Loader  (0) 2023.01.15
[단어장] Glossary, Consensus  (0) 2023.01.08
금붕어의 웹 사전  (0) 2021.12.13
금붕어의 데이터베이스 사전  (0) 2021.12.13
금붕어의 React 사전  (0) 2021.12.13