솔리디티 문법 예제ㅣ변수, 자료형, 값타입, 참조타입, 매핑

인사이트

솔리디티 문법 예제ㅣ변수, 자료형, 값타입, 참조타입, 매핑

2022년 11월 02일

블록체인 이더리움 네트워크에서 스마트 컨트랙트를 개발하는 데 필요한 솔리디티(Solidity) 프로그래밍 언어에 대해 지난 시간 간단하게 소개해드렸습니다.

오늘은 솔리디티 프로그래밍 언어의 기본 문법과 예제에 대해 알아보겠습니다.

솔리디티 문법 예제

솔리디티 문법과 예제 📎

솔리디티는 자료형과 함수를 통해 여러 기능을 개발하고, 이를 통해 트랜잭션을 일으켜 블록체인 상에 데이터를 기록할 수 있게 합니다. 오늘은 변수, 자료형에 초점을 맞추어 살펴보겠습니다.

변수(Variables)

변수는 하나의 특정한 값을 가지는 것이 아니라 변하는 값을 가집니다. 선언하기 위해서는 자료형을 필히 명시해야 합니다. 자료형은 변수에 들어갈 값의 종류입니다. 이는 아래에서 자세하게 다루어 보겠습니다. 먼저, 아래는 예제 코드입니다.

솔리디티 문법 예제-변수

솔리디티의 3가지 변수 타입 💡

지역 변수(local)

함수 안에서 선언됩니다. 블록체인에 기록되지 않습니다.

상태 변수(state)

함수 밖에서 선언됩니다. 블록체인에 저장돼 영속성을 가지게 됩니다. 함수 내부 어디에서든지 사용 가능하며 가시성 지정자에 따라 변수의 접근 범위가 달라집니다.

전역 변수(global)

블록체인에 관한 정보를 제공합니다.
솔리디티 문법 예제-변수

자료형(Data type)

솔리디티 자료형은 크게 값 타입(value type)참조 타입(Reference type)으로 나눌 수 있습니다. 값 타입은 값이 할당되거나 함수의 인자로 활용이 되면 해당 값 자체가 복사됩니다.

참조 타입은 현재 해당하는 값의 주소만 복사됩니다. 즉, 참조형 타입의 특징은 데이터를 어디에 저장할지 명시해야 한다는 것입니다. 기본적으로 참조형은 배열(array), 매핑(mapping), 구조체(Struct)로 구성되어 있습니다.

값 타입(value type) 💡

불리언(Boolean) 타입: bool

참과 거짓으로 이루어진 자료형입니다. 솔리디티에서 불리언은 bool로 표기합니다. 특정한 조건에 발생하는 행동을 통제할 때 쓰이며 주로 비교 연산자, 논리 연산자와 함께 사용됩니다.

정수(Integer) 타입: uint와 int

솔리디티는 기존 프로그래밍 언어와 다르게 소수점이 있는 숫자를 지원하지 않습니다. 정수형의 목적은 가격, 토큰의 아이디와 같이 숫자로 된 정보를 표현하기 위함입니다. 

솔리디티의 정수형 타입은 uint(부호 없는 정수형)와 int(정수형)이며 둘의 차이점은 음수의 포함 여부입니다. 주로 산술 연산자와 비교 연산자에서 함께 사용됩니다.

바이트 타입: bytes

바이트 타입은 고정 크기 바이트(값 타입) 배열과 동적 크기 바이트 배열로 나뉠 수 있는데, 차이점은 고정 크기 바이트 배열은 값 타입이며 사용할 바이트를 미리 지정한다는 점입니다.

동적 크기 바이트는 참조 타입이며 사용할 바이트 값을 지정하지 않아도 됩니다.

문자열 타입: string

동적 크기 UTF-8(Unicode Transformation Format-8)로 인코딩된 배열입니다.

주소 타입: address

계정의 주소를 나타냅니다. 주소형 타입의 크기는 20bytes로 지정되어 있으며 유저의 고유 아이디 또는 배포된 스마트 컨트랙트의 아이디로 볼 수 있습니다. 이 주소를 통해 암호화폐를 주고받게 됩니다.

참조 타입(Reference type) 💡

1. 매핑(Mapping)

매핑은 자바스크립트의 오브젝트와 같이 키와 값의 형태로 저장합니다. 다시 말해 키와 대응하는 값을 저장하므로 원하는 값을 얻기 위해서는 그 값의 올바른 키를 입력해야 합니다.

mapping (key type ⇒ value type) 가시성 지정자 매핑명) 으로 정의됩니다.

key type은 모든 기본 값(정수 등), bytes, string, 컨트랙트가 될 수 있습니다. value type은 다른 매핑과 배열을 포함한 모든 유형이 될 수 있습니다.

대표적인 예시로 각 유저의 토큰 잔액을 나타내는 것을 매핑으로 구현할 수 있습니다. 아래의 예제 코드를 확인해 봅시다.

솔리디티 문법 예제-자료형

매핑에 키와 값을 추가할 수 있습니다. 코드를 보겠습니다.

솔리디티 문법 예제-자료형

보시는 것처럼 myAddr 매핑의 키는 address 자료형이고 값의 자료형은 uint입니다.

addM 함수는 myAddr 매핑에 데이터를 저장하는 함수입니다. 매개변수로 address와 uint 자료형을 받고 있는 것을 확인할 수 있습니다. 코드를 실행하기 전에 키로 넣을 주소를 복사해야 합니다.

솔리디티 문법 예제-자료형

Account 주소를 복사한 뒤 Deploy를 눌러 배포를 진행합니다. addM 함수의 인자로 복사해 두었던 주소와 정수값(ex. 100)을 넣어 줍니다. transact 버튼을 클릭하면 myAddr 매핑에 해당하는 키와 값이 저장됩니다. 이제 이를 확인하는 코드를 실행해 보겠습니다.

복사했던 account 주소를 getM의 매개변수로 입력한 다음, getM 함수를 클릭해 결괏값을 확인합니다.

솔리디티 문법 예제-자료형

결괏값은 100이 나왔습니다. 매핑은 각 주소에 따른 토큰 잔액을 의미하기 때문에 복사한 account 주소에 해당하는 유저가 토큰 100개를 가지고 있다는 뜻이 됩니다. myAddr 역시 복사한 account를 매개변수로 넣으면 같은 결괏값이 나옵니다.

매핑에서는 키와 값을 삭제할 수도 있습니다.

솔리디티 문법 예제-자료형

이전에 진행했던 과정과 같이 account 값을 복사해 키로 지정합니다. 임의의 정수형을 입력한 뒤 addM 함수를 실행합니다. 값이 잘 들어가 있는 것을 확인했다면, account 값을 deleteM 함수의 매개변수에 입력합니다.

솔리디티 문법 예제-자료형

deleteM 함수를 실행한 뒤 getM을 통해 매핑의 값을 출력해 보면, 초깃값으로 넣었던 200이 0으로 나온 것을 확인할 수 있습니다.

매핑의 특성상, 저장되지 않은 키에 대응하는 값은 기본적으로 0이 대입되어 있습니다. 우리는 방금 deleteM 함수를 통해 account 주소에 대응하는 매핑의 값을 0으로 만들었습니다.

확장해서 생각해 봅시다. 삭제하고자 하는 매핑의 값을 기본값인 0으로 변경한다면 어떻게 될까요? 다시 한 번 더 account 주소를 키로 지정하고 값을 넣어 준 뒤 getM 함수를 실행합니다. 반환된 값을 확인한 뒤 deleteM2 함수를 실행합니다.

매핑의 특성상, 저장되지 않은 키에 대응하는 값은 기본적으로 0이 대입되어 있습니다. 우리는 방금 deleteM 함수를 통해 account 주소에 대응하는 매핑의 값을 0으로 만들었습니다.

솔리디티 문법 예제-자료형

값이 정상적으로 0이 된 것을 확인할 수 있습니다. 하지만 이는 매핑 값이 자료형 uint일 때만 가능하다는 점을 유의해야 합니다.

2. 배열(Array)

배열은 어떤 것의 모음집이라고 할 수 있습니다. 참조 타입이며 한 개의 배열에 여러 개의 값을 순차적으로 저장합니다. 값을 순차적으로 저장하기 때문에 배열의 길이를 지원합니다.

기본적으로 타입 [] 가시성 지정자 배열명으로 정의됩니다. 코드를 살펴보겠습니다.

솔리디티 문법 예제-자료형-배열

솔리디티에서 배열은 정적 배열과 동적 배열로 사용이 가능합니다.

정적 배열(static)

실행 시간에 크기가 결정됩니다. 즉, 고정된 크기가 없어 계속 커질 수 있다는 의미입니다.
솔리디티 문법 예제-자료형-배열

동적 배열(Dynamic)

선언 시 크기가 결정됩니다. 미리 사용할 배열의 크기를 지정할 수 있습니다.
솔리디티 문법 예제-자료형-동적 배열

배열의 인덱스에 대응하는 값을 구할 수 있습니다. 먼저, getArrlenggetArr2leng는 배열의 길이를 반환할 수 있는 함수입니다.

솔리디티 문법 예제-자료형-동적 배열
솔리디티 문법 예제-자료형-배열

getArrgetArr2는 매개변수로 _index를 입력받아 해당 인덱스에 저장된 값을 반환합니다. 아래와 같이 입력하고 arr, arr2, getArr, getArr2를 눌러 값을 확인해 봅시다.

솔리디티 문법 예제-배열

arr2getArr2는 해당하는 인덱스의 값 block을 잘 가지고 오는 것을 볼 수 있습니다.

하지만 arrgetArr는 아무런 값도 받지 못했습니다. 왜일까요?

arr 크기가 0이며 값을 저장할 수 있는 공간이 존재하지 않기 때문에 오류가 발생하는 것입니다. 추가적으로 arr2에 인덱스 값으로 10 이상을 넣으면 동일한 오류가 날 것입니다. 이유는 arr의 크기가 10으로 지정이 되어 있기 때문입니다.

배열에 값을 추가할 수 있습니다.

솔리디티 문법 예제-배열
솔리디티 문법 예제-배열

getArrleng, getArr2leng 함수를 통해 각각의 길이 3과 10을 얻을 수 있습니다. 각 배열에 초깃값이 할당되어 있기 때문입니다. plusArr 함수의 push를 통해 배열에 새로운 값을 저장하게 되면 길이가 증가하게 됩니다.

하지만 plusArr2 함수의 주석을 풀면 컴파일러에 오류가 생깁니다. 이유는 무엇일까요?

솔리디티 문법 예제-배열

arr2의 크기가 10으로 고정되어 있어 크기를 변경할 수 없기 때문입니다.

이제 다시 plusArr 함수로 돌아와 값 4를 넣어 실행해 보겠습니다. arr에 값이 새롭게 추가되어 길이가 증가한 것을 확인할 수 있습니다.

솔리디티 문법 예제-배열

이번에는 배열의 값을 변경해 보겠습니다.

changeArr, changeArr2 함수는 각각 두 개의 매개변수를 받고 있습니다. 인덱스와 인덱스에 해당하는 값을 명시합니다.

솔리디티 문법 예제-배열
솔리디티 문법 예제-배열

두 개의 매개변수에 값을 지정하고 함수를 실행하자 해당하는 인덱스의 값이 바뀐 것을 확인할 수 있습니다.

배열의 값을 삭제할 수도 있습니다. 두 가지 방법이 있는데, 이는 pop과 delete입니다.

removeArr 함수의 경우, 배열의 내장 함수인 pop을 이용하여 값을 삭제한다. 마지막 인덱스가 없어짐과 동시에 배열의 크기도 줄어듭니다.

솔리디티 문법 예제-배열

deleteArr 함수의 경우, 함수 내부에 있는 delete arr [_index]를 통해 원하는 인덱스에 저장된 값만 삭제할 수 있습니다. 기존 값이 0으로 삭제가 되었기 때문에 배열의 크기는 그대로입니다.

솔리디티 문법 예제-배열

3. 구조체(Struct)

구조체는 우리만의 타입을 만드는 것입니다. 다시 말해 사용자 정의 자료형이라고 할 수 있습니다.

자신이 원하는 자료형을 만들어 변수, 배열, 매핑 등과 같이 자료형을 명시해야 하는 곳에 적용할 수 있습니다. 구조체는 한 개 이상의 변수가 집단으로 구성되어 있습니다. 컨트랙트 밖에서 선언될 수 있으며 다른 컨트랙트로 imported 역시 가능합니다.

솔리디티 문법 예제-구조체

아래는 구조체를 자료형으로 명시하고, 이를 반환하는 코드 예제입니다. 함께 살펴보겠습니다.

솔리디티 문법 예제-구조체

human2human 자료형 값을 대입하는 함수를 작성해 보고자 합니다.

솔리디티 문법 예제-구조체
솔리디티 문법 예제-구조체

newH2에 나이와 이름, 직업을 적고 transact을 누른 뒤, 초깃값만 들어가 있던 human2의 값을 확인해 봅시다. 50, lee, judge가 잘 들어가 있는 것을 확인할 수 있습니다.

아래 코드는 human1의 직업을 바꾸는 함수입니다.

솔리디티 문법 예제-구조체

changeH1Job 함수를 통해 human1의 job을 변경해 보았습니다. changeH1Job 함수에서 받은 매개변수를 이용해 새로운 값을 할당합니다.

솔리디티 문법 예제
함수, 연산자 편이 이어집니다.

이더리움에서 제공하는 스마트 컨트랙트 개발 언어인 솔리디티 문법 예제, 그 중에서도 변수(Variables)자료형(Data type) 문법 예제를 함께 살펴보았습니다. 다음 시간에는 함수(Function), 연산자(Operator) 문법 예제가 이어질 예정입니다.

 고유진 Blochain Engineer, 양희진 Educational Operation Manager (Blockchain Engineering)
편집 조주연 Content Manager


🚀 블록체인 개발자 커리어의 시작,
블록체인 부트캠프가 더 궁금하다면?

목록 보기

추천글