[솔리디티] 기초 문법 - 1

근상·2025년 1월 7일

솔리디티 기초

목록 보기
2/7

그래도 가장 기본적인 것들이다.
이 포스트 내용이 모두 크게 자료형이다.

이 언어만의 특별하게 사용되는 키워드를 알아보자.


값 자료형

Bool

대부분의 언어와 비슷하다.

bool private bool_data1 = true;
bool private bool_data2 = false;

ture/false는 소문자로 작성해야한다.

Integer

int는 0과 음/양의 정수이고

실생활에 사용할 정수에는 양의 정수 사용 비율이 높다.

이 때 uint라는 것을 사용한다.

uint256이라는 것도 있는데 이는 uint와 같다. 하지만 256표기하는 것이 더 좋다.
또 uint8도 있다. 이것은 메모리 용량을 줄이기 위함으로 작은 값을 사용할 때 쓴다.

그래서 정수 int/uint를 골라 사용하고 메모리 또한 고려해서 사용하면 된다.

//사용 예시
int private data1 = -100000;
uint priavte data2 = 1000000;

uint256 private data3 = 100000000000;
uint8 private data4 = 10;
String

흔히 다른 언어에서도 사용하는 문자열이다.

string private data1 = "Hi HI HI HI HI hI hiihihihhiihihihi";

하지만 중요한 점은
이 string타입은 bytes값으로 변환돼 메모리에 저장된다.

Bytes
bytes private data1 = "Hi there!";

값을 또한 갖는데 그냥 사용할 때는 가변적인 성질을 띤다.

하지만 bytes값이 고정된 경우에는 정수형과같이 숫자와 함께 사용한다.

bytes20 public data1 = (주로 주소);
bytes32 public data2 = (주로 트랜잭션 해시);

//hex를 사용하면
bytes20 public data3 = hex"0x제외한주소";
// 이런식으로 사용할 수 있다.
Address

아무래도 솔리디티 개발을 하려면 주소를 사용할 일이 빈번하기 때문에
아예 자료형을 만들었다.

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

// 이더스캔에서 아무 주소를 들고와보겠다.
address private addr1 = 0x4838B106FCe9647Bdf1E7877BF73cE8B0BAD5f97;

이런식으로 사용할 수 있다.
자주 사용할 수밖에 없는 타입이다.


연산자

기본적으로

uint private data1 = 0;

data = data + 1;
data += 1;
data++;

//모두 사용가능 (곱셈, 나눗셈, 뺄셈) 다 포함이다.

하지만 솔리디티는 이더를 처리 해야한다.
그럴 때 제곱연산이 필요하다.

// 기본적으로 wei단위를 사용한다.
// 하지만 유저들에게는 eth단위가 필요하다.
// 그래서 단위 변환을 해준다.

uint256 public wei_data = 1;

uint256 public gwei_data = wei_data / (10**9);

uint256 public eth_data = wei_data / (10**18); 

//하지만 이 코드를 계산하면 정수가 아니기 때문에 그냥 연산 구조만 이해하자.

논리 & 비교 연산도 다른 언어와 똑같다.

bool public data_true = true;
bool public data_false = false;

if (data_true) {}
else {}
//이런식으로도 사용가능

if (data_true && data_false) {}
if (data_true || data_false) {}
if (data_true == data_false) {}

// 비교연산도 가능하다.

uint8 public data1 = 10;
uint8 public data2 = 5;
if (data1 < data2) {}
if (data1 > data2) {}
if (data1 <= data2) {}
if (data1 >= data2) {}
if (data1 == data2) {}
if (data1 != data2) {}
// 처럼 다 가능하다.

마지막으로 변수 타입을 알아보자
지역변수, 상태변수, 전역변수가 있다.

상태 변수: 함수 밖 선언이며,
블록체인에 저장돼 불변성과 영속성을 갖는다.
함수 내부 어디서든 사용 가능하고 사용범위를 지정할 수 있다.

지역 변수 : 함수 안에서 선언되고, 블록체인에 기록 안됨.

전역 변수 : 블록체인에 관한 정보를 제공한다.

contract Example1{

	// 블록체인 내에 기록될 상태 변수다.
	string public data1 = "Hi there";
    uint8 public data2 = 3;
    
    function getEx1() public {
    	// 함수 안에서 선언된 지역변수다.
    	uint8 data3 = 1;
        
        // 구체적인 내용들을 나중에 알겠지만
        // 전역 변수 선언이다.
        uint data4 = block.timestamp;
        address data5 = msg.sender;
    }
}

함수

기본적인 함수 구조를 알아보자
c++성질처럼 자료형을 맞추는 것이 매우 중요하다!

uint8 public data = 128;

function setData(uint8 _data) public {
	data = _data;
}

// 리턴을 꼭 할 필요는 없지만 해야할 경우에는
// 꼭 자료형을 표기해야한다.

function getData() public view returns(uint8){
	return data;
}

다음은 접근 제한자다.

함수나 상태 변수에 적용된다.

public, private, external, internal로 4가지가 있다.

public: 어디서든 호출 가능
private: 선언된 컨트랙트 내부에서만 호출 가능
internal: 선언된 컨트랙트와 상속받은 컨트랙트 내부에서만 호출 가능
external: 컨트랙트 외부에서만 호출 가능

function fn1() public {}
function fn2() private {}
function fn3() external {}
function fn4() internal {}

이런 식으로 사용 하면 된다.

당연히 처음 개발할 때부터 접근 제한을 적절하게 잘 하는 것이 좋지만
확시하지 않은 부분들이 존재한다면 public으로 두고
여러 차례 테스트를 진행해 변경해 나가는 것도 팁이다.

View vs Pure

위 함수 구조 코드를 보면 리턴하는 부분에서 view라는 것을 사용했다.

둘의 가장 큰 차이는 상태 변수를 처리하는 부분이다.
view는 상태 변수를 조회하고 Pure는 말 그대로 순수하게 처리하지 않는다.

상태변수의 값을 변경할 경우에는 view 또한 적지 않는다.

예를보자

uint8 private data1 = 10;

// view를 사용한다.
// data1이 상태 변수이기 때문이다.
function fn1() public view returns(uint 8){
	return data1;
}

// 상태변수가 아니기(지역변수임) 때문에 pure를 사용한다.
function fn2() public pure returns(uint 8) {
	uint8 data2 = 3;
    return data2
}

하지만 여기서 의문이 들 경우가 있다.
둘의 구분은 알겠는데 그냥 만약 상태 변수를 처리할 일이 없는 함순데
그냥 pure를 안 쓰면 되는 것 아닌가 라는 생각이 들었다.

이것을 사용해야 보안성이 더 좋고, pure 단어를 쓰게 되면
전체적인 코드를 봤을 때 한 눈에 상태 변수 처리 하지 않는 함수 파악도 가능하고
마지막으로 가장 중요한 가스비 절약이된다.

Storage vs Memory

Storage는 블록체인에 영구적으로 저장되는 공간이고,
Memory는 임시적인 메모리 공간이다.

contract Ex {
    uint storage publicbalance; // 스토리지에 저장된 상태 변수

    function deposit(uint memory amount) public {
        balance += amount; // balance는 스토리지에 저장된 값을 변경
    }

    function getBalance() public view returns (uint memory) {
        uint tempBalance = balance; // tempBalance는 메모리에 저장된 임시 변수
        return tempBalance;
    }
}

이 둘 또한 굳이 쓸 필요 없다.
자동으로 상태 변수는 스토리지로, 나머지는 메모리로 저장된다.

하지만 가독성 향상, 오류 방지 등의 이유로
사용할 경우가 있다는 것을 알아두자.


시리즈

  1. 현재
  2. 참조 자료형
  3. 블록 & 트랜잭션
  4. Modifier & Error Handling
  5. 컨트랙트 상속
  6. 컨트랙트 호출

0개의 댓글