💡솔리디티 기본 문법 - 자료형
✓ 값 형 데이터 타입 (Value Types)
1. 불 (bool)
bool 로 선언된 변수는 true 나 false 값을 가진다.
bool isOpen = true;
bool isSold = false;
2. 정수 (int, uint)
부호(+, -) 가 있는 경우에는 int, 부호가 없는 0 이상의 값에는 uint를 사용한다. int, uint 뒤에 8~256의 8의 배수의 숫자를 붙여 변수의 크기를 비트 단위로 지정할 수도 있다. (예: int8, int16, int24, uint64, uint128, ...)
각 숫자에 따라 정수는 특정 범위로 제한된다. int16은 -32768 ~ 32767 사이의 정수를 의미하며, uint16은 0~65535 사이의 정수를 의미한다. 일반적으로 뒤에 숫자가 없는 int, uint는 int256, uint256을 의미한다.
int8 seoulTemp = -20
uint16 myAge = 30
3. 주소 (address)
주소 타이은 크게 두 가지 유형으로 나뉜다.
- address: 20바이트의 이더리움 주소 값을 가짐
- address payable: address와 동일한 값을 가지지만 추가 멤버인 transfer, send를 가짐.
주소(address) 객체는 0x 로 시작하고 최대 40자리의 16진수로 구성되는 문자열을 값으로 가진다.
address yourAddress = 0x10abb5efEcdc01234f7b2384912398798E089Ab2;
중요한 것은, 0.8버전부터 address 형식은 송금이 불가능한 주소값이라는 점이다. 스마트 컨트랙트에서 특정 주소 값으로 송금하기 위해서는 **address payable** 형식을 사용해야 한다. address payable 형식에는 이더 송금을 위한 transfer()와 send()함수가 내장되어 있다. address payable 형식 데이터는 address 형식 데이터를 **payable()** 함수에 인자로 담아 만들 수 있다.
address addr1;
address payable p_addr1 = payable(addr1);
uint160 또는 bytes20 형식의 데이터를 address payable로 바꾸기 위해서는 먼저 address()를 사용하여 주소 형태로 만들고, 다시 payable()을 사용해 address payable 형식으로 바꿀 수 있다.
uint160 num;
address addr = address(num);
address payable p_addr = payable(addr);
컨트랙트를 address payable 로 변환할 수도 있다. 만약 컨트랙트가 이더를 받을 수 있는 컨트랙트인 경우, address(컨트랙트)를 수행했을 때 address payable 형식의 주소값을 반환한다.
contract C { // 이더를 받을 수 있는 컨트랙트
constructor () payable { }
}
address payable addr = address(C); // address(C)는 adress payable 형식의 주소값을 반환한다
반면, 컨트랙트가 이더를 받지 않는 컨트랙트인 경우, address(컨트랙트)를 수행했을 때 address 형식의 주소값을 반환한다. 이 경우 결과값을 payable()에 넣어 address payable 형식으로 만들 수 있다.
contract D {. // 이더를 받지 않는 컨트랙트
constructor () { }
}
address addr = address(D); // address(D)는 adress 형식의 주소값을 반환한다
address payable addr_p = payable(addr); // payable()을 사용해 address payable 형식의 주소값을 만들 수 있다.
4. 바이트 배열 (고정 크기)
데이터를 바이너리 형태로 저장하기 위해 사용한다. bytes1 ~ bytes32 까지의 고정된 크기의 배열을 선언하다. 정해진 바이트 크기와 값의 크기가 다르면 에러가 난다.
bytes3 alphabets = 'abc';
alphabets[0] // 'a'
alphabets[1] // 'b'
alphabets[2] // 'c'
5. 열거형 (enum)
열거형(enum)은 특정 값들로 집합을 지정하고, 집합에 있는 데이터만을 값으로 가진다. 각 집합의 데이터는 내부적으로는 순서에 따라 0부터 1씩 올라가는 정수를 값으로 가진다.
enum EvalLevel { Bad, Soso, Great } // 열거형 집합을 지정합니다.
EvalLevel kimblock = EvalLevel.Bad // 열거형으로 변수를 선언합니다.
int16 kimblockValue = int16(kimblock); // kimblock 열거형 값 0을 정수형으로 변환합니다.
✓ 참조형 데이터 타입 (Reference Types)
참조형 변수 (reference type)는 마치 배열과 같이, 연속되어 저장되는 값의 첫번째 메모리의 주소를 값으로 가지는 변수 타입이다. 이를 '참조한다'라고 표현한다. 데이터 저장 영역에는 아래와 같이 세 종류가 있다.
- 메모리: 프로그램이 동작하는 동안에만 값을 기억하고, 종료되면 값을 잃는 데이터 영역
- 스토리지: 블록체인에 기록되어 영구적으로 값이 유지되는 데이터 영역
- calldata: 메모리와 비슷하지만 수정 불가능하고 비영구적인 데이터 영역
참조현 변수를 선언할 때는 메모리에 저장할지 스토리지에 저장할지 명시해야 한다.
(상태변수는 무조건 스토리지에 저장된다)
unction f() {
// 5개의 int32 형태의 데이터를 메모리에 저장하는 변수 fixedSlots 선언
int32[5] memory fixedSlots;
fixedSlots[0] = 13;
}
참조현 변수의 유형은 배열, 바이트크기, 문자열, 구조체, 매핑이 있다.
1. 배열 (array)
배열은 저장하고자 하는 데이터 형식에 []를 붙여 선언한다. 가령 uint8 형식의 데이터를 저장하는 배열을 만드는 경우, uint8[]과 같이 자료형을 작성한다. 배열에는 정적 배열과 동적 배열이 존재한다.
- 정적 배열: uint[4] {배열 이름} 과 같은 형식으로 사용할 배열의 크기를 지정하여 선언한다.
- 동적 배열: uint[] {배열 이름} 과 같은 형식으로 배열의 크기를 지정하지 않고 선언한다. 5개의 동적 배열로 구성된 배열은 uint[][5] 로 작성된다.
new 키워드를 사용해 동적 배열을 메모리에 할당할 수도 있다.
<바이트 배열(가변 크기)>
바이트(bytes)는 특수한 형태의 배열이다. 배열식 표현의 byte[]와 유사하지만 calldata와 메모리를 활용한다는 점이 다르다. bytes로 가변 크기의 배열을 선언한다.
bytes alphabets = 'abc';
<문자열(string)>
문자열 역시 특수한 형태의 배열로써, 바이트 배열(가변 크기)에 기반한 문자열 타입이다. string은 bytes와 동일하지만, index, push, length, concat 등을 지원하지 않는다. 문자열 리터럴로 초기화한다.
string name = 'kimblock';
2. 구조체 (struct)
구조체는 서로 다른 유형의 항목을 포함하는 집합으로, 사용자 정의 형식이다. 구조체는 배열과 매핑의 내부에서 사용할 수 있으며, 반대로 구조체에 배열과 매핑을 포함할 수도 있다. 하지만 구조체가 동일한 구조체 타입의 멤버를 포함할 순 없다. 구조체는 다음과 같이 정의한다.
contract exmapleC {
struct User {
address account;
string lastName;
string firstName;
mapping (uint => Funder) funders;
}
mapping (uint => User) users;
}
구조체를 사용할 때는 각 항목에 대한 값을 객체 형식으로 추가한다.
contract exmapleC {
struct User {
address account;
string lastName;
string firstName;
}
function newUser (address newAddress, string newLastName, string newFirstName){
User memory newOne = User({account: newAddress, lastName: newLastName, firstName: newFirstName});
}
}
3. 매핑(mapping)
매핑은 스토리지 데이터 영역에서 키-값 구조로 데이터를 저장할 때 사용하는 참조형이다. mapping은 다음의 형태로 선언 한다.
mapping({키 형식} => {값 형식}) {변수명}
여기서 키 형식은 매핑, 구조체, 배열을 제외한 유형의 값이 다 될 수 있고, 값 형식은 매핑, 구조체, 배열을 포함한 모든 유형의 값이 다 될 수 있다.
mapping(adddress => int) public userAddress;
매핑은 일반적인 프로그래밍 언어에서의 해시 테이블 또는 딕셔너리와 유사하다. 키 자체가 실제로 저장되지는 않고 키의 keccak256 해시를 이용해 값에 접근한다. 매핑은 오직 스토리지 영역에만 저장될 수 있으므로, 상태 변수, 내부 함수에서의 스토리지 참조 타입, 라이브러리 함수의 매개 변수에만 허용된다.
'블록체인 > WEB3 개발' 카테고리의 다른 글
솔리디티 기본 문법 - 함수 제어자 (0) | 2022.07.08 |
---|---|
솔리디티 기본 문법 - 함수 (0) | 2022.07.08 |
솔리디티 기본 문법 - 연산자 (0) | 2022.07.08 |
솔리디티 기본문법 - 변수 (0) | 2022.07.08 |
솔리디티란? (0) | 2022.07.08 |
댓글