solidity 적응기 1. 어렵지 않아요 헤치지 않아요.(기초 구조)

2022. 8. 15. 17:33NFT/Solidity

당황하지 말아요!

 

대망의 solidity를 처음으로 해봤습니다.

자료형을 쭉 읊어봤자 의미 없는 것 같고 일단 구조부터 크게 이해를 하고 넘어가는게 좋을 것 같습니다.

 

먼저, 이 시리즈는 개인적으로 이해한 내용을 가볍게 풀어낸 내용임을 설명드립니다.

실제와 약간 틀리거나 다른 부분이 분명 존재합니다. 언제든지 피드백은 환영합니다!

 

1. solidity의 목적과 특징

solidity는 프로그래밍 언어입니다. 제가 느끼기에는 javascript와 동작구조가 비슷한 것 같아요.

각 언어에는 최적화된 목적이 있죠. C는 임베디드, javscript는 웹, python은 데이터 분석이나 매크로등

solidity는 스마트 컨트랙트를 구현하기 위한 언어입니다. (이더리움 기반입니다.)

EVM이라는 머신 안에서 동작을 하고 remix라는 브라우저 IDE에서 간단한 동작을 확인할 수 있습니다.

https://remix.ethereum.org/

 

Remix - Ethereum IDE

 

remix.ethereum.org

 

스마트 컨트랙트로 뭐가 가능한가요?

Web3.0의 가장 큰 특징인 개인화에 가장 잘 맞습니다.

기존엔 어떤 플랫폼에서 정한 규칙대로, 혹은 어떤 인증기관의 인증을 통해서 개인간의 계약이 가능합니다.

이런 걸 개인이 이더리움을 사용해서 사전 정의해놓은 contract를 통해서 거래를 할 수 있습니다.

 

예를 들어볼까요?

당신은 이더리움 기반의 e스포츠 토토를 열어보려고 합니다. (불법입니다.)
LCK 경기의 경기 결과와 배당률에 따라 수익을 얻을 수 있습니다. 다음과 같은 조건으로 말이죠.

1. 경기를 참여하기 위해선 1 ether를 내야하고 스코어를 냅니다.(2:0, 2:1 등)
2. 배팅된 결과에 따라 가중치를 둬서 배당률이 계산됩니다.
3-1. 결과를 맞췄을 경우, 배당률에 해당하는 수익을 돌려받습니다.
3-2. 결과를 스코어까지 정확히 맞췄을 경우, 배당률에 해당하는 수익에 추가로 토큰을 받습니다.

 

이런 간단한 규칙을 정했다면, 각 규칙으로 여러분 입맛에 맞는 contract를 만들 수 있겠군요.

 

2. solidity의 기본적인 구조

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Contract {
	constructor() {}
}

 

컴파일 시에 오류를 줄여주는 목적으로 주석을 꼭 달아줘야합니다!

다음으론 solidity의 버전을 정의해줍시다. 0.7.0 버전부터 0.9까지 동작이 가능한 코드라고 적어줬네요.

그리고 꼭 class 처럼 목적에 맞는 기능을 묶어주는 contract로 묶어줍니다.

 

constructor의 실행

constructor가 생성자라는건 누가봐도 알겠군요.

다만 실행 타이밍은 일반적인 경우와 약간다릅니다.

 

일반적으로 생성자는 인스턴스가 생성될 때 한 번 실행됩니다.

다만, solidity의 특징이라 할 점은 contract가 배포될 때 인스턴스가 한 번만 실행된다는 점입니다.

 

이게 되게 별거 아닌 것 같은데, 이런 식의 활용도 가능합니다.

배포할 때 account라는 변수에 생성자에 배포할 지갑 주소로 초기화하는 코드를 넣어놓는다면,

이 컨트랙트의 함수를 쓰려는 어떤 지갑 주인도 그 account에 접근하려고 한다면, 배포한 사람의 지갑 주소에 접근할 수 있습니다. 이런식으로 다양하게 활용될 수 있습니다.

 

 

인출함수를 만들고 인출할 계좌를 배포자의 계좌로 해두면,

어떤 유저든지 와서 이더를 자기 계좌로 인출해갈 수도 있겠네요.

 

3. 변수와 함수의 선언 방법

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Contract {
    uint256 private myNumber = 1;
    int256 private myNumber2 = -1;
    address private address = 0xf8dyhgf88cgf3gfvvdge8vgds;
    string myString = "Welcome!";
    bool isTrue = true;

    constructor() {}
}

 

역시 Web3.0 시대의 언어라 그런지, 접근 제한자가 타입의 뒤에 붙습니다. 힙하네요.

먼저 자료형을 써 준다음에 접근제한자를 붙혀주고 변수명을 붙힙니다.

초기화는 선언 때 해줘도 되고, 함수나 생성자에서 해줘도 문제 없습니다.

 

각 자료형에 대해서 약간의 설명이 필요하겠네요. 기본적인 자료형들이고 많이 사용합니다.(bool은 생략합니당)

 

1. 정수형 자료형 uint와 int

자연수라면 uint를 사용합시다.

정수(음수 등)라면 int를 사용합시다.

비트수에따라 uint8, uint16, uint32, uint256까지 저장이 가능합니다.

각각 0 ~ 255, 0 ~ 65,535, 0 ~ 2,147,483,647, 0 ~ (5.78 * 10^76) - 1까지 저장이 가능합니다.

int의 경우도 마찬가지지만 -128 ~ 127 이런식으로 절댓값 기준으론 범위가 절반으로 줄어듭니당.

 

2. 문자열 자료형 string

함수 외부에서 선언해줄 때는 string 변수이름 으로 선언해도 문제가 없지만,

로컬에서 선언해줄 때는 string memory 변수이름 이런식으로 선언해줍시다! (파라미터로 줄 때도 마찬가지입니다.)

 

string의 reference 유형을 정리해두었습니다.

더보기

storage: 영속적으로 저장이 됩니다. 함수 외부에서 선언한 변수엔 자동으로 storage가 붙습니다.

memory: 함수 내부에서 파라미터, 리턴값, 레퍼런스 등으로 사용됩니다.

colldata: external 함수의 파라미터에서 사용됩니다.(interface 등에서 implementation 시 무조건 적어줘야하는 함수등)

 

3. 계좌 정보를 저장할 수 있는 address

계좌 주소인 20byte짜리 address를 저장할 수 있습니다.

나중에 설명할 입금함수나 출금함수를 만들때 꼭 이 유형의 자료형을 사용해야하기 때문에 string 이렇게 저장하지 말고 address로 저장해줍시다!

 

이 외에도 mapping 등의 자료형이 있지만, 일단 이렇게 먼저 알아두자구요!

 

4. 함수의 선언에 대해서

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Dicegame {
    uint256 mynumber = 1;

    constructor() {}
    
    function getNumber() public view returns(uint256) {
    	return mynumber;
    }
}

 

함수는 보시는 것 처럼 javascript 처럼 선언해줍니다. 다만, 접근 제한자가 역시 뒤에 붙고 여러 속성들이 있네요.

정리하면 이렇습니다.

 

1. public | private: 접근제한자입니다. public 시 contract 외부에서도 접근 가능합니다.
2. view | pure: 함수 외부 변수 read 여부입니다. pure는 외부 변수를 읽는 기능이 없는 함수에 붙여줍니다.
3. payable: 만약 결제 기능(send, transfer, call)이 있는 함수를 호출한다면 붙여줍니다.
4. returns(TYPE): return이 있는 함수의 경우 return 타입을 명시해줍니다. void는 안적어줘도 됩니다.

 

자 이제 기본적으로 solidity에 대해서 알아봤습니다.

다음엔 간단한 예제를 통해서 제가 정의한 스포츠 토토 프로그램을 한 번 같이 만들어 보죠!

 

그럼 이만!

다음에 봐요~