본문 바로가기
etc/블록체인 뉴딜일자리사업

솔리디티 기초: 자료형, 변수, 함수, 모디파이어

by vellahw 2023. 5. 22.

 

💭 서론

교육 14일차

솔리디티 프로그래밍 수업이 시작됐다. 3일간의 스파르타... 강사님께서 3일만에 마스터하는 것은 당연히 불가능하고 솔리디티로 작성된 코드를 분석하고 이해만 할 수 있다면 충분하다고 하셨기에 열심히 들었다. 오늘은 문법 구조?와 자료형, 함수, 배열 등 이론적인 것들을 코드를 보고, 쳐보기도 하며 배웠다. 처음 접하는만큼 문법이 달라 약간은 헤맸지만 킵고잉...

 

 

 

✔️ 솔리디티(Solidity)

  • 솔리디티는 이더리움 등 블록체인 플랫폼에서 스마트 계약 작성과 구현에 사용되는 계약 지향 프로그래밍 언어이다.
  • 이더리움 핵심 기여자들에 의해 이더리움과 같은 블록체인 플랫폼상에 스마트 계약을 작성할 수 있도록 개발되었다.
  • 솔리디티도 자바와 같이 객체 지향 언어이다.
  • 기본적으로 이더(ETH)를 보내고 받는데 필요한 데이터 타입, 함수 등을 제공한다.

 

스마트 컨트랙트 기본 구조

첫 번째 줄은 소스 코드가 GPL 버전 3.0에 따라 라이센스가 부여되었음을 알려준다.

라이센스 지정자는 소스 코드 게시가 기본값인 환경에서 중요하다.

솔리디티 문서에 의하면, 라이센스를 명시해줌으로써 스마트 컨트랙에 대한 신뢰감을 높일 수 있고, 스마트 컨트랙 소스코드가 워낙 오픈되어 있으니 저작권과 같은 관련 문제를 해소하기 위해 명시한다고 기술되어있다.

 

👀 SPDX(The Software Package Data Exchange)는 소프트웨어와 관련된 구성 요소, 라이선스, 저작권, 보안 참조 및 기타 메타데이터를 표현한다. (SPDX 라이센스 목록)

 

두 번째 줄은 솔리디티 컴파일러의 버전을 명시한 것이다. 사진 속 코드는 0.4.16 이상 0.9.0 미만의 버전을 사용한다고 명시되어있다.

pragma solidity ^0.8;

위처럼 버전 앞에 ^를 붙여주면 해당 버전부터 그 이상의 버전 모두를 사용한다는 뜻이다.

 

 

 

✔️ 리믹스 디버거 살펴보기

디버거는 트랜잭션을 진행하는 동안 계약의 상태를 보여준다.

저번주에 리믹스로 잠깐 솔리디티를 찍먹 해봤을 때도 디버거가 궁금 했어서 개인적으로 찾아보았다.

 

ERC20.sol의 디버거

  • Function Stack: 트랜잭션이 상호 작용하는 함수를 나열한다.
  • Solidity Locals: 함수 내부의 지역 변수
  • 그 아래 있는 숫자와 영어 조합을 Opcodes라고 함: 디버거가 현재 있는 단계 번호와 opcode가 표시된다.
  • Solidity State: 컨트랙트의 상태변수
  • Stack: 연산에 필요한 데이타를 저장하는 공간. EVM(Ethereum Virtual Machine) 스택이 표시됨
  • Memory: 함수를 호출하거나 메모리 연산을 수행할때 임시로 사용되는 공간
  •  메모리 패널은 3개의 열로 구성된다.
  •  첫 번째 열은 메모리의 위치이고 두 번째 열은 16진수로 인코딩된 값이다. 세 번째 열은 디코딩된 값인데 아무 것도 없으면 다음과 물음표가 표시됨
  • Call Data: 이더리움에 트랜잭션을 요청했을때 전송되는 데이타들이 저장되는 공간. 함수 매개변수가 포함됨

 

 

 

✔️ 리믹스 로컬pc와 연동하기

리믹스는 웹 IDE이다보니 잘못하다 작업 파일이 다 날아갈 수 있다. 내 컴퓨터와 연동해보자!

우선 노드가 설치되어 있어야 한다. cmd 창을 열어 npm -v 명령어로 노드가 잘 설치되었는지 확인 해준다.

그 후 아래 명령어를 입력하여 리믹스 최신 버전을 설치한다.

npm install -g @remix-project/remixd

 

설치가 완료되면 버전을 확인해주는 remixd -v 명령어를 입력해 잘 설치되었는지 확인한다. 숫자로 버전이 찍히면 잘 설치된 것이다.

 

연동할 폴더를 remix라는 이름으로 만들었다.

cd 명령어를 이용해 해당 폴더로 이동하고, remixd 명령어를 입력하면 연동이 시작된다.

💡 연동을 끊기 전까지 cmd 창을 닫아서는 안 된다!

 

리믹스의 Workspaces에서 connect to localhost를 눌러준다.

 

그 후 파일이든 폴더든 하나 생성 해보면 내 컴퓨터 폴더에도 생성된 것을 확인할 수 있다!

연동을 해제하려면 cmd에서 컨트롤+c를 누르면 해제된다.

 

 

 

✔️ 자료형

솔리디티 자료형은 값 타입(value type)과 참조 타입(Reference type)으로 나뉜다.

 

1. 값 타입 자료형

값이 할당되거나 함수의 인자로 활용되면 해당 값 자체가 복사된다.

 

◎ 불리언(Boolean) 타입 bool

참과 거짓으로 이루어짐

 

정수(Integer) 타입 uint, int

  • 솔리디티는 소수점이 있는 숫자를 지원하지 않는다. (가격, 토큰의 아이디와 같이 숫자로 된 정보를 표현하기 위함)
  • uint은 부호 없는 정수형, int는 정수형이며 둘의 차이점은 음수의 포함 여부이다.

 

 바이트 타입 bytes

 

 문자열 타입 string

 

 주소 타입 address

  • 계정의 주소를 나타내며 크기는 20 바이트로 지정됨
  • 유저의 고유 아이디 또는 배포된 스마트 컨트랙트의 아이디로 볼 수 있으며 이 주소를 통해 암호화폐를 주고받게 된다.

 

2. 참조 타입 자료형

현재 해당하는 값의 주소만 복사된다.

 

 배열 Array

// 배열 정의
타입 [ ] 가시성지정자 배열명;

한 개의 배열에 여러 개의 값을 순차적으로 저장한다.

값을 순차적으로 저장하기 때문에 배열의 길이를 지원함.

 

솔리디티에서 배열은 정적 배열과 동적 배열로 사용할 수 있다.

 

정적 배열

실행 시간에 크기가 결정된다. 즉, 고정된 크기가 없어 계속 커질 수 있다는 의미

 

동적 배열

선언 시 크기가 결정된다. 미리 사용할 배열의 크기를 지정할 수 있다.

자료의 길이는 10이며 uint 자료형을 같는 배열이다.

3개의 값 1, 30, 505가 미리 들어가 있으며 나머지 7개의 공간엔 공백으로 인덱스가 남겨져 있다.

 

배열명.push() 메소드로 배열에 값을 추가할 수 있고

배열명.pop() 혹은 배열명.delete() 로 배열에서 값을 삭제할 수 있다.

  • pop()은 가장 마지막 인덱스의 값과 그 공간을 삭제
  • delete()는 삭제할 인덱스를 지정하여 값을 삭제할 수 있으며 공간은 유지된다.

 

 매핑 Mapping

자바스크립트의 오브젝트처럼 키와 값의 형태로 저장됨

// 매핑 정의
mapping (키 자료형 ⇒ 값 자료형) 가시성지정자 변수명;

( ==> mapping(uint => uint) public a; )

 

👀 코드를 통한 예제

매핑의 대표적인 예시로 유저의 토큰 잔액을 나타낼 수 있다.

매핑 a의 키는 address 자료형, 값은 uint 자료형이다. 

함수 addMapping은 a 매핑에 데이터를 저장하는 함수 (매개변수로 address와 uint 자료형을 받고 있음)

 

💡 솔리디티에서 인자의 이름 앞에 언더바 ( _ )를 붙여주는 것이 관례

 

함수 실행 전 지갑 주소를 복사해두고 deploy 한다.

 

addMapping 함수에 복사한 주소와 정수값을 입력하고 transact 버튼을 클릭

이를 통해 a 매핑에 해당하는 키와 값이 저장된다.

 

입력한 값을 확인하기 위해 getMapping 함수를 실행한다.

키로 입력한 주소값을 넣고 call 버튼을 클릭하면 위 사진과 같이 값으로 넣어준 '3'이 출력된다.

 

매핑에서 값을 삭제할 수도 있다.

위 사진 속 순서와 같이 deleteMapping 함수에 주소를 입력하고 transact 버튼을 누른 뒤, a를 확인하면 0이 출력된다.

매핑의 특성상 저장되지 않은 키에 대응하는 값은 기본적으로 0이 대입되어 있다. (매핑 값이 자료형 uint일 때만 가능)

 

값을 수정할 수도 있다.

키로 주소를 입력하고 값으로 정수를 입력한뒤 transact 한다. 그후 a 매핑을 call하면 100이 출력된다.

 

 구조체 Struct

  • 구조체는 우리만의 타입을 만드는 것 즉, 사용자 정의 자료형이라고 할 수 있다.
  • 자신이 원하는 자료형을 만들어 변수, 배열, 매핑 등과 같이 자료형을 명시해야 하는 곳에 적용할 수 있다.
  • 구조체는 한 개 이상의 변수가 집단으로 구성되어 있다.
  • 컨트랙트 밖에서 선언될 수 있으며 다른 컨트랙트로 imported 가능함
// 구조체 정의

struct 구조체명 {

    자료형 변수명,
    자료형 변수명,
    자료형 변수명
}

자바스크립트 생성자 함수와 비슷한 ..

 

 

 

✔️ 변수

1. 변수 정의 방법

 

💡 가시성 지정자

public, private, internal, external 네 종류가 있으며 변수, 함수, 상수에 지정가능하다.

가시성 지정자.. 단어 자체가 더 어렵게 느껴지는데 코드 배포를 기준으로, 쉽게 말해 public은 남들이 볼 수 있는 것, private은 나만 볼 수 있는 것이다. 

블록체인은 코드를 배포하면 누구나 내 코드를 볼 수 있게 되는데 public으로 지정한 변수, 함수, 상수만 남에게 보여지고 private은 다른 사람은 보이지 않는 것이다!

 

  • public : 외부/내부 접근가능 (변수 적용시 getter 함수가 생성됨)
  • private : 내부 접근만 가능
  • external : 외부 접근만 가능 (변수에 적용 불가능. 단, this 키워드 사용시 내부 접근 가능)
  • internal : 내부 접근만 가능하나 상속 받은 스마트 컨트랙트는 외부 접근 가능

 

2. 변수의 종류 - 상태 변수, 지역 변수, 전역 변수

 상태 변수 (State Variable): 함수 밖에 선언되는 변수

  • 값이 블록체인에 저장돼 영속성을 가지게 

상태변수

 

 지역 변수 (Local Variables): 함수 안에 있는 변수

  • 블록체인에 기록되지 않는다.

지역변수

 

 전역 변수 (Global Variables): 블록체인에 대한 정보를 제공하는 변수

전역변수

block.number : 솔리디티가 제공하는 블록체인에 대한 정보를 얻는 메소드(?)

 

전역 변수 종류

 

✔️ 함수

함수의 기본 형태

funtion 함수명(자료형 매개변수명) 가시성지정자 returns (자료형){
    uint public a = 3;
    return a;
}
  • 자바스크립트 처럼 function으로 시작하여 함수명()과 중괄호가 붙지만 함수명 옆에 가시성 지정자를 붙인다.
  • 매개변수가 있을 경우 자료형과 매개변수명을 함께 써준다.
  • 리턴값이 있을 경우 returns (자료형)을 붙인다.

 

함수 작성 예시

 

 

 

✔️ 모디파이어 Modifier (view, pure, payable)

특정한 기능을 미리 정의해 여러 함수에 적용할 수 있다.

일반적으로 모디파이어를 통해 스마트 컨트랙트를 배포한 사람만 특정 함수를 실행 시키도록 하는 등 함수의 로직에 제약을 준다.

// 모디파이어는 가시성지정자 옆에 기입
function 함수명 public 모디파이어 {
    함수로직
}

 

view

- 함수 내부에서 외부 데이터 값을 변경할 수 없다.

- 거래에서의 사용자 정보(마음대로 바꿀 수 없는 정보) 등에 이용

 

위와 같이 코드를 작성했을 때 view가 적용된 함수는 함수 내부에서 외부 데이터 값을 변경할 수 없기 때문에 fun1() 함수 안에서 상태 변수 a를 재정의 할 수 없다.

 

pure

- 함수 밖에서 선언된 변수를 pure가 적용된 함수 내부로 가져오지 못한다.

- 순수하게 함수 내부에서 정의된 변수

- 매개변수만 함수 내부에서 선언 가능

 

함수 밖에서 선언된 변수를 pure가 적용된 함수 내부로 가져오지 못하기 때문에 변수 a를 재정의 하려고 하면 에러가 발생한다.

또한 pure가 적용된 함수는 외부로 표현할 수 없기 때문에 public 가시성 지정자를 사용할 수 없다

 

💡 가시성 지정자를 생략하면 private이 기본값임

 

 

Payable

Payable은 코인과 상호작용(송금)시 필요한 키워드 
send, trnafer, call을 이용하여 실제로 이더를 보낼때 Payable이라는 키워드가 필요하다.

 

 

 


참고

댓글