티스토리 뷰

카테고리 없음

솔리디티

감자형 2018. 5. 8. 19:01


문제 설명

이더리움 솔리디티 실습에 오신 것을 환영합니다.
이 강의는 솔리디티를 활용하여 DApp을 단계별로 구현해보는 강의입니다.

솔리디티(Solidity) 언어란?

솔리디티는 이더리움 블록체인 플랫폼에서 스마트 계약(Smart Contract)를 정의하는 언어입니다.
솔리디티 문법은 자바스크립트 문법과 유사합니다. 다만, 정적 타입 언어1라, 자료형을 명시해주어야 합니다.

DApp이란?

스마트 계약을 구현한 블록체인 기반의 탈중앙화2 애플리케이션입니다.


다음 코드는 솔리디티로 작성된 가장 간단한 형태의 계약(Contract) 코드입니다. 
가볍게 한번 둘러보세요!

직접 해보기
  • [실행]을 누르면 getMessage 함수가 실행됩니다. message에 들어있는 값을 변경하면서 실행해 보세요.

  • 아래 내용을 구현하고 [제출] 해 보세요.

    • 이름을 저장 하는 string 타입의 상태 변수 name을 선언해보세요.
    • getMessage 함수를 참고하여 name을 반환하는 getName 함수를 작성해보세요.

  1. 정적 타입 언어(Statically Typed Language) : C언어나 Java와 같이 자료형을 명시해 주어야 하는 언어. 

  2. 블록체인의 가장 큰 특징으로 중앙 시스템이 아니라 분산된 환경에서 모든 거래가 이루어집니다. 




제 설명

솔리디티는 다른 언어와 마찬가지로, 다양한 자료형을 지원합니다.
※ 단, 부동소수점 자료형(float)은 지원하지 않습니다.

주요 자료형
  • uint : 부호가 없는 정수형
  • int : 정수형
  • bool : 논리 자료형
  • string : UTF-8 인코딩 문자열
  • bytes : 바이트
  • address : 이더리움 주소 값 (0xaDc7192A0…)
레퍼런스 자료형
  • 배열 : 자료형이 같은 데이터를 묶은 자료 구조입니다.
  • 구조체1 : 다양한 자료형의 데이터를 묶은 자료 구조입니다.

다음 코드에서 솔리디티의 다양한 자료형을 사용해보세요!


직접 해보기
  • [실행]을 누르면 public으로 선언된 상태 변수의 값을 확인해 볼 수 있습니다. public 상태 변수의 값을 바꾸면 어떤 값이 출력되는지 확인해보세요!

  • 아래 내용을 구현하고 [제출] 해보세요.

    • uint 타입의 year를 반환하는 getYear() 함수를 만드세요
    • bool 타입의 isHappy를 반환하는 getHappy() 함수를 만드세요.

솔리디티가 부동소수점을 지원하지 않는 이유

부동소수점 타입으로는 수를 정확하게 표현하지 못합니다.
수를 정확히 다룰 수 없는 타입은 이더(Ether)2를 다룰 수 없어, 솔리디티는 부동소수점을 지원하지 않습니다.

더 알아보기

솔리디티의 정수 자료형은 그 크기를 명시할 수 있습니다. 예를들어,

  • uint: uint8uint256와 같이 크기도 명시 가능
  • int: int8int256와 같이 크기 명시 가능

  1. 구조체는 후속 강의에서 다룹니다. 

  2. 이더(Ether, ETH): 이더리움 블록체인 네트워크상의 암호화폐(Cryptocurrency) 






문제 설명

솔리디티에서는 연산자와 제어문을 사용할 수 있습니다.

솔리디티의 연산자(Operator)
  • 논리 연산자: !&&||
  • 비교 연산자 : <=<==!=>=>
  • 비트 연산자: &|^<<>> (시프트 연산자)
  • 단항(unary) 산술 연산자: +-
  • 이항(binary) 산술 연산자: +-*/ (몫), % (나머지), ** (거듭 제곱)
제어문(Control Structures)
  • 조건문: ifelse? : (삼항 연산자)
  • 반복문: whiledofor
  • 반복문 분기: breakcontinue
  • 반환문: return

※ 여타 언어의 switch/case나 goto 문은 지원하지 않습니다.
※ 솔리디티는 자동 형 변환(type conversion)을 하지 않습니다. 예를 들어 if (true) { ... }는 허용하지만 if (1) { ... }는 허용하지 않습니다.


직접 해보기
  • [실행]을 누르면 playground 함수가 실행되어, playground 함수의 반한값을 확인할 수 있습니다. playground 함수 안에서 연산자와 제어문을 마음껏 사용해 보세요.
    단, playground 함수는 int와 bool을 반환해야 합니다.

  • 아래 내용을 구현하고 [제출]해 보세요.

    • 본 강의에서는 구현할 내용이 없습니다.
    • playground함수가 int와 bool을 반환하면 [제출]에 성공합니다.


문제 설명

사람 뿐만 아니라, 스마트 계약도 내부적으로 이더리움 계정1를 가집니다. 스마트 계약은 계약 계정를 통해 이더를 거래합니다.
예를 들어, 계약을 통해 A가 B에게 10 이더를 보내는 계약을 호출할 때, 이더는 사실 다음과 같이 이동합니다.

  1. A가 A 계정에서 계약 계정으로 10 이더를 송금
  2. 계약이 계약 계정에서 B 계정으로 10이더를 송금

Payable 키워드

payable 키워드는 계약 계정에 외부에서 이더를 송금 받을 수 있도록 합니다. 즉, 계약이 A에게 송금을 받으려면 A가 호출하는 함수에 payable 키워드가 있어야합니다.
payable 함수는 다음과 같이 사용합니다.

function 함수이름() payable public {
    //함수 내용
}

직접 해보기

A 계정에서 계약 계정으로 10 이더를 송금 하려고 합니다.

  • 함수에 payable 키워드를 선언하세요.
    • [실행]을 누르면 sending() 함수가 자동 호출됩니다. 출력으로 함수 호출 전후 A의 계좌와 계약 계정의 잔고를 확인 할 수 있습니다.
    • 키워드를 선언하지 않으면, 계약에게 이더를 보낼 방법을 찾지 못해, No events were emitted 라는 경고 메세지가 보입니다.

  1. 이를 계약 계정(Contract Accounts, CA)라고 합니다. 



문제 설명

이전 강의에서는 payable 키워드를 통해 A 주소에서 계약 주소로 10 이더를 송금 하는 방법을 알아보았습니다.
이번 강의에서는 계약이 이더를 보낸 사람을 파악하는 법을 알아봅니다.

메세지 프로퍼티(Message Properties)

계약은 msg 프로퍼티를 사용해 계약을 호출한 사람이 보낸 메세지를 확인합니다. msg 프로퍼티는 다음과 같은 정보를 담습니다.

정보타입설명
databyte호출 데이터
senderaddress계약을 호출한 이더리움 주소
valueuint계약 주소로 보낸 Ether 량
gasuintgas limit1에서 함수를 호출하고 남은 가스

직접 해보기
  • [실행]을 누르면 A가 계약에게 5 이더를 보내는 checkMsg()가 자동 호출됩니다.
  • [실행]을 누르면 A가 보낸 msg의 property가 출력됩니다. 확인해보세요.

Block, Transaction 등의 더 많은 프로퍼티를 알고 싶다면 솔리디티 문서를 방문하세요.


  1. 그 계약에서 한번 호출로 소비할 수 있는 최대의 가스 양 





문제 설명
복습

A가 계약을 통해 B에게 10 이더를 보내면, 이더는 다음과 같이 이동합니다.

  • A가 계약에게 10 이더를 송금
  • 계약이 B에게 10 이더를 송금

이번 강의에서는 스마트 계약이 B에게 이더를 송금 하는 법을 배워봅시다.

Transfer 함수

transfer 함수를 사용하면 계약이 다른 이에게 이더를 전송합니다. transfer 함수는 다음과 같이 사용합니다.

<받는 사람의 주소>.transfer(<송금할 금액>);

예를 들어, 다음은 계약이 seller에게 10 만큼의 이더를 전송하는 함수, buy를 구현한 예입니다.

function buy() public {
    seller.transfer(10)
}

직접 해보기

msg.sender에서 friend로 이더를 송금하는 transfer()함수를 작성해보세요.

  • 각 계정은 100 이더를 초기값으로 가집니다.
  • [실행]을 누르면 A가 msg.value에 이더를 넣어 transfer 함수를 호출합니다.
  • [실행]을 누르면 송금 전후의 계좌 잔액을 출력합니다.

Note

[실행] 결과가 이상해요!

  • Q. friend에게 돈을 보내지 않았는데, msg.sender의 돈이 빠져나갔어요.
    A. transfer를 하지 않아도 msg.sender는 계약 주소(CA)에 10 이더를 보냅니다.
    msg.sender의 10 이더는 계약 주소에 있습니다!

  • Q. 왜 transfer 후 msg.sender의 잔고가 10 이더 보다 더 빠져나갔나요?
    A. msg.sender가 함수를 호출 할 때 수수료1를 지불했기 때문입니다!


  1. 수수료는 후속 강의에서 다룹니다. 

실행 결과    
실행 결과가 여기에 표시됩니다.



문제 설명
스마트 계약은 어떻게 실행될까?

작성된 스마트 계약은 EVM1 타깃으로 컴파일된 후, 이더리움 네트워크에 배포됩니다. 
이렇게 배포된 스마트 계약 코드는 Gas라는 수수료를 내야 사용할 수 있습니다.

수수료는 왜 나가나요?

스마트 계약은 실제로 블록체인을 관리하는 노드들에 의해 실행됩니다. 이때 노드는 데이터를 검증하고, 기록하는 등 다양한 일을 해줍니다.
따라서 이 일을 해주는 대가로 Gas라고 부르는 수수료를 내야 합니다.
스마트 계약에 명령어가 많은 수록 Gas를 더 많이 내야 합니다.


직접 해보기
  • 코드의 count 값을 바꿔가며, 수수료가 얼마나 나가는지 확인해보세요.
  • [실행]을 누르면 다음 정보를 알 수 있습니다.
    • 실행 전에 내가 보유한 잔액
    • 실행 결과 트랜잭션으로 소비된 Gas
    • 실행 후에 내가 보유한 잔액

※ 이 실습의 코드는 테스트 환경에서 동작합니다.
※ 테스트 환경에서는 실행을 누를 때마다 잔액이 초기화됩니다.


Note

Q. 왜 count 값이 커지면 Gas도 더 많이나가나요?

Gas는 작업량이 많을수록 더 많이 소모됩니다.
따라서 계약이 명령어를 많이 실행할 수록 Gas 도 많이 내야합니다.


  1. EVM: Ethereum Virtual Machine 



문제 설명

우리는 지금 스마트 계약을 통해 A에서 B로 이더를 보내는 방법을 배웠습니다.
이번 시간에는 계약이 성사되고 남은 영수증을 확인하는 방법을 알아봅시다.

트랜잭션 확인하기

스마트 계약을 실행하면 이더리움 블록체인에 기록이 남습니다. 이 기록은 트랜잭션(Transaction) 이라는 특수한 형태로 저장되는데요. 트랜잭션은 계약을 수행하는데 든 수수료(가스) 등 다양한 정보를 담고 있습니다.

[실행] 버튼을 눌러, 이 계약을 실행해서 만들어진 트랜잭션을 확인해보세요.


트랜잭션이 담은 정보
  • transactionHash : 트랜잭션의 해시값
  • transactionIndex : 트랜잭션의 인덱스 값
  • blockHash : 이 트랜잭션이 추가된 블록의 해시값
  • blockNumber : 이 트랜잭션이 추가된 블록의 번호
  • gasUsed : 이 트랜잭션 호출에 소비한 가스양
  • cumulativeGasUsed : 누적으로 사용된 가스량
  • contractAddress : 계약의 주소
  • logs : event로 로깅된 정보 ( 후속 강의로 다룰 예정 )

  • 이런 트랜잭션들이 모여 하나의 블록(block)을 이룹니다.
    이더리움 네트워크 상에는 이러한 블록들이 체인처럼 엮인 모습을 하고 있기 때문에 블록체인(blockchain)이라고 부릅니다.

  • 블록체인을 더 자세히 알고 싶다면 클릭하세요!


문제 설명

지금까지 솔리디티의 기초적인 문법들을 만나보셨습니다. 
이제는 솔리디티 문법과 DApp(탈중앙화 애플리케이션) 개발을 익혀보려고 합니다.

중개자의 개입이 필요 없는 크라우드펀딩1 Dapp 만들기

우리는 이더리움 블록체인 네트워크상에서 스마트 계약(Smart Contract)으로 중개자나 중개 플랫폼 없이 모든 요구사항을 만족하는 DApp을 만들려 합니다.

이 크라우드펀딩 서비스에는 다음 기능이 있어야 합니다.

  • 누구나 아이디어를 등록할 수 있습니다.
  • 캠페인에는 목표 금액과 종료 기간이 있습니다.
  • 등록된 캠페인 기록은 지워지지 않습니다.
  • 누구나 원하는 금액만큼 캠페인에 펀딩할 수 있습니다.
  • 펀딩을 해준 사람에 대한 기록이 남습니다.
  • 목표 금액을 달성했다면 펀딩 자금은 아이디어 등록자가 가집니다.
  • 목표 금액을 달성하지 못했다면 펀딩 자금은 환불됩니다.

시작하기
  1. 코드 가장 윗부분에 솔리디티 버전 pragma solidity ^0.4.18;을 명시하고,
  2. 다음 줄에 Crowdfunding이라는 이름의 계약(Contract) 선언하세요.

  1. 크라우드펀딩(Crowdfunding): 아이디어를 다수의 개인에게 공개하고 투자를 받아 자금을 모으는 펀딩 방식입니다. 유명한 크라우드 펀딩 사이트로는 텀블벅킥스타터 등이 있습니다. 


문제 설명
접근 제어자

솔리디티에선 접근 제어자(Visibility Modifiers)를 통해 상태 변수와 함수에 접근 범위를 제한 할 수 있습니다. 솔리디티에서 사용할 수 있는 접근 제어자는 다음과 같습니다.

  • public 접근 제어자
  • internal 접근 제어자
  • private 접근 제어자
  • external 접근 제어자

각 접근 제어자의 차이점은 강의 노트 하단을 참고하세요.

사용 예시
// 상태 변수에서의 접근 제어자 사용
string private secret = "i like u";

// 함수에서의 접근 제어자 사용
function f() public returns (uint) {
    // 어쩌고저쩌고
}

직접 사용해보기
  • Host 컨트랙트에 uint 타입의 age를 public으로 선언해보고 초기값을 대입해보세요.
  • grade와 age가 Caller 컨트랙트에서 어떻게 호출되는지 살펴보세요.

접근 제어자 별 차이점
  • public 접근 제어자
    이 접근 제어자가 선언된 함수는 외부에서 호출할 수 있습니다.
    또한, 이 접근 제어자로 상태 변수를 선언하면 자동으로 Getter 함수를 생성해 줍니다.
    ※ 접근 제어자를 명시하지 않은 함수는 public으로 선언됩니다.

  • internal 접근 제어자
    이 상태 변수/함수를 선언한 계약과 그 계약을 상속1 받은 계약에서만 호출할 수 있습니다.
    ※ 접근 제어자를 명시하지 않은 상태 변수는 internal로 선언됩니다.

  • private 접근 제어자
    이 접근 제어자가 선언된 상태 변수/함수는 해당 계약에서만 호출할 수 있습니다. 
    상속 받은 계약도 private으로 선언된 상태 변수/함수를 호출할 수 없습니다.

  • external 접근 제어자
    인터페이스2 의 함수를 의미합니다. 
    이 상태 변수/함수를 선언한 계약 내부에서는 이 상태 변수/함수를 호출할 수 없습니다.


  1. 상속(Inheritance): 후속 강의에서 다룹니다. 

  2. 인터페이스(Interface): 후속 강의에서 다룹니다. 



문제 설명

우리는 이더리움 블록체인 네트워크상에서 스마트 계약으로 중개자나 중개 플랫폼 없는 DApp을 만들고 있습니다. 이 크라우드펀딩 서비스에는 다음 기능이 있어야 합니다.

요구사항
  • 이번 강의에 구현할 내용
    • 누구나 아이디어를 등록할 수 있습니다.
  • 추후 구현할 내용
    • 캠페인에는 목표 금액과 종료 기간이 있습니다.
    • 등록된 캠페인 기록은 지워지지 않습니다.
    • 누구나 원하는 금액만큼 캠페인에 펀딩할 수 있습니다.
    • 펀딩을 해준 사람에 대한 기록이 남습니다.
    • 목표 금액을 달성했다면 펀딩 자금은 아이디어 등록자가 가집니다.
    • 목표 금액을 달성하지 못했다면 펀딩 자금은 환불됩니다.

DApp에 적용해보기

본 강의에서는 크라우드 펀딩을 생성하는 코드를 만듭니다.
펀딩을 생성할 때에는, 계약에 크라우드 펀딩 캠페인을 만든 사람의 이름을 저장해야 합니다.

  • 생성자의 주소를 저장할 상태 변수를 선언하세요.

    • 상태 변수의 이름은 creator여야 합니다.
    • 상태 변수는 public으로 선언하여 Getter 함수가 만들어지도록 해야 합니다.
    • 상태 변수는 address 타입이어야 합니다.
  • 펀딩을 생성하는 함수를 만들어주세요.

    • 함수의 이름은 createCampaign()이어야 합니다.
    • 함수는 public으로 접근할 수 있어야 합니다.
    • 함수는 상태 변수 creator에 msg.sender를 저장해야 합니다.

문제 설명

스마트 계약은 실행하는데 수수료가 듭니다. 기왕이면 수수료는 적게 내는게 좋겠지요. 데이터를 읽기만 하는 단순 작업은 가스를 소모하지 않게 설정 해줍시다.

View 함수

수수료를 아끼려면 view 키워드를 붙여 함수를 선언해보세요. View 함수의 특징은 다음과 같습니다.

  • 상태를 변경하지 않습니다: 블록체인 네트워크 상의 데이터를 읽기만 할 수 있고 데이터를 수정할 수 없습니다.
  • 가스를 소모하지 않습니다: 호출할 때 Gas를 사용하지 않습니다.

다음은 View 함수 사용 예시입니다.

contract Variables {
    uint year = 2018;

    function get() public view returns (uint) {
        return year;
    }
}

직접 해보기
  • isLeapYear 함수를 수정하세요.

    • 현재 isLeapYear 함수는 가스를 호출할 때마다 가스를 소비합니다.
    • 가스를 소비하지 않도록 일반 함수를 view 함수로 수정하세요.
    • isLeapYear 함수는 윤년인지 여부를 bool 타입으로 반환해야 합니다.
  • [실행]을 누르면

    • isLeapYear()의 반환값을 알 수 있습니다.
    • isLeapYear()함수 호출 전/후로 소유한 이더량을 알 수 있습니다.


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함