티스토리 뷰
문제 설명
이더리움 솔리디티 실습에 오신 것을 환영합니다.
이 강의는 솔리디티를 활용하여 DApp을 단계별로 구현해보는 강의입니다.
솔리디티(Solidity) 언어란?
솔리디티는 이더리움 블록체인 플랫폼에서 스마트 계약(Smart Contract)를 정의하는 언어입니다.
솔리디티 문법은 자바스크립트 문법과 유사합니다. 다만, 정적 타입 언어1라, 자료형을 명시해주어야 합니다.
DApp이란?
스마트 계약을 구현한 블록체인 기반의 탈중앙화2 애플리케이션입니다.
다음 코드는 솔리디티로 작성된 가장 간단한 형태의 계약(Contract) 코드입니다.
가볍게 한번 둘러보세요!
직접 해보기
[실행]을 누르면
getMessage
함수가 실행됩니다.message
에 들어있는 값을 변경하면서 실행해 보세요.아래 내용을 구현하고 [제출] 해 보세요.
- 이름을 저장 하는
string
타입의 상태 변수name
을 선언해보세요. getMessage
함수를 참고하여name
을 반환하는getName
함수를 작성해보세요.
- 이름을 저장 하는
정적 타입 언어(Statically Typed Language) : C언어나 Java와 같이 자료형을 명시해 주어야 하는 언어. ↩
블록체인의 가장 큰 특징으로 중앙 시스템이 아니라 분산된 환경에서 모든 거래가 이루어집니다. ↩
제 설명
솔리디티는 다른 언어와 마찬가지로, 다양한 자료형을 지원합니다.
※ 단, 부동소수점 자료형(float)은 지원하지 않습니다.
주요 자료형
uint
: 부호가 없는 정수형int
: 정수형bool
: 논리 자료형string
: UTF-8 인코딩 문자열bytes
: 바이트address
: 이더리움 주소 값 (0xaDc7192A0…)
레퍼런스 자료형
- 배열 : 자료형이 같은 데이터를 묶은 자료 구조입니다.
- 구조체1 : 다양한 자료형의 데이터를 묶은 자료 구조입니다.
다음 코드에서 솔리디티의 다양한 자료형을 사용해보세요!
직접 해보기
[실행]을 누르면
public
으로 선언된 상태 변수의 값을 확인해 볼 수 있습니다. public 상태 변수의 값을 바꾸면 어떤 값이 출력되는지 확인해보세요!아래 내용을 구현하고 [제출] 해보세요.
uint
타입의year
를 반환하는getYear()
함수를 만드세요bool
타입의isHappy
를 반환하는getHappy()
함수를 만드세요.
솔리디티가 부동소수점을 지원하지 않는 이유
부동소수점 타입으로는 수를 정확하게 표현하지 못합니다.
수를 정확히 다룰 수 없는 타입은 이더(Ether)
2를 다룰 수 없어, 솔리디티는 부동소수점을 지원하지 않습니다.
더 알아보기
솔리디티의 정수 자료형은 그 크기를 명시할 수 있습니다. 예를들어,
- uint:
uint8
,uint256
와 같이 크기도 명시 가능 - int:
int8
,int256
와 같이 크기 명시 가능
문제 설명
솔리디티에서는 연산자와 제어문을 사용할 수 있습니다.
솔리디티의 연산자(Operator)
- 논리 연산자:
!
,&&
,||
- 비교 연산자 :
<=
,<
,==
,!=
,>=
,>
- 비트 연산자:
&
,|
,^
,<<
,>>
(시프트 연산자) - 단항(unary) 산술 연산자:
+
,-
- 이항(binary) 산술 연산자:
+
,-
,*
,/
(몫),%
(나머지),**
(거듭 제곱)
제어문(Control Structures)
- 조건문:
if
,else
,? :
(삼항 연산자) - 반복문:
while
,do
,for
- 반복문 분기:
break
,continue
- 반환문:
return
※ 여타 언어의 switch
/case
나 goto
문은 지원하지 않습니다.
※ 솔리디티는 자동 형 변환(type conversion)을 하지 않습니다. 예를 들어 if (true) { ... }
는 허용하지만 if (1) { ... }
는 허용하지 않습니다.
직접 해보기
[실행]을 누르면
playground
함수가 실행되어,playground
함수의 반한값을 확인할 수 있습니다.playground
함수 안에서 연산자와 제어문을 마음껏 사용해 보세요.
단,playground
함수는int
와bool
을 반환해야 합니다.아래 내용을 구현하고 [제출]해 보세요.
- 본 강의에서는 구현할 내용이 없습니다.
playground
함수가int
와bool
을 반환하면 [제출]에 성공합니다.
문제 설명
사람 뿐만 아니라, 스마트 계약도 내부적으로 이더리움 계정1를 가집니다. 스마트 계약은 계약 계정를 통해 이더를 거래합니다.
예를 들어, 계약을 통해 A가 B에게 10 이더를 보내는 계약을 호출할 때, 이더는 사실 다음과 같이 이동합니다.
- A가 A 계정에서 계약 계정으로 10 이더를 송금
- 계약이 계약 계정에서 B 계정으로 10이더를 송금
Payable 키워드
payable
키워드는 계약 계정에 외부에서 이더를 송금 받을 수 있도록 합니다. 즉, 계약이 A에게 송금을 받으려면 A가 호출하는 함수에 payable
키워드가 있어야합니다.payable
함수는 다음과 같이 사용합니다.
function 함수이름() payable public {
//함수 내용
}
직접 해보기
A 계정에서 계약 계정으로 10 이더
를 송금 하려고 합니다.
- 함수에
payable
키워드를 선언하세요.- [실행]을 누르면
sending()
함수가 자동 호출됩니다. 출력으로 함수 호출 전후 A의 계좌와 계약 계정의 잔고를 확인 할 수 있습니다. - 키워드를 선언하지 않으면, 계약에게 이더를 보낼 방법을 찾지 못해,
No events were emitted
라는 경고 메세지가 보입니다.
- [실행]을 누르면
이를 계약 계정(Contract Accounts, CA)라고 합니다. ↩
문제 설명
이전 강의에서는 payable
키워드를 통해 A 주소에서 계약 주소로 10 이더를 송금 하는 방법을 알아보았습니다.
이번 강의에서는 계약이 이더를 보낸 사람을 파악하는 법을 알아봅니다.
메세지 프로퍼티(Message Properties)
계약은 msg
프로퍼티를 사용해 계약을 호출한 사람이 보낸 메세지를 확인합니다. msg
프로퍼티는 다음과 같은 정보를 담습니다.
정보 | 타입 | 설명 |
---|---|---|
data | byte | 호출 데이터 |
sender | address | 계약을 호출한 이더리움 주소 |
value | uint | 계약 주소로 보낸 Ether 량 |
gas | uint | gas limit1에서 함수를 호출하고 남은 가스 |
직접 해보기
- [실행]을 누르면 A가 계약에게
5 이더
를 보내는checkMsg()
가 자동 호출됩니다. - [실행]을 누르면 A가 보낸
msg
의 property가 출력됩니다. 확인해보세요.
Block, Transaction 등의 더 많은 프로퍼티를 알고 싶다면 솔리디티 문서를 방문하세요.
그 계약에서 한번 호출로 소비할 수 있는 최대의 가스 양 ↩
문제 설명
복습
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를 지불했기 때문입니다!
수수료는 후속 강의에서 다룹니다. ↩
문제 설명
스마트 계약은 어떻게 실행될까?
작성된 스마트 계약은 EVM1 타깃으로 컴파일된 후, 이더리움 네트워크에 배포됩니다.
이렇게 배포된 스마트 계약 코드는 Gas라는 수수료를 내야 사용할 수 있습니다.
수수료는 왜 나가나요?
스마트 계약은 실제로 블록체인을 관리하는 노드들에 의해 실행됩니다. 이때 노드는 데이터를 검증하고, 기록하는 등 다양한 일을 해줍니다.
따라서 이 일을 해주는 대가로 Gas라고 부르는 수수료를 내야 합니다.
스마트 계약에 명령어가 많은 수록 Gas를 더 많이 내야 합니다.
직접 해보기
- 코드의
count
값을 바꿔가며, 수수료가 얼마나 나가는지 확인해보세요. - [실행]을 누르면 다음 정보를 알 수 있습니다.
- 실행 전에 내가 보유한 잔액
- 실행 결과 트랜잭션으로 소비된 Gas
- 실행 후에 내가 보유한 잔액
※ 이 실습의 코드는 테스트 환경에서 동작합니다.
※ 테스트 환경에서는 실행을 누를 때마다 잔액이 초기화됩니다.
Note
Q. 왜 count
값이 커지면 Gas도 더 많이나가나요?
Gas는 작업량이 많을수록 더 많이 소모됩니다.
따라서 계약이 명령어를 많이 실행할 수록 Gas 도 많이 내야합니다.
EVM: Ethereum Virtual Machine ↩
문제 설명
우리는 지금 스마트 계약을 통해 A에서 B로 이더를 보내는 방법을 배웠습니다.
이번 시간에는 계약이 성사되고 남은 영수증을 확인하는 방법을 알아봅시다.
트랜잭션 확인하기
스마트 계약을 실행하면 이더리움 블록체인에 기록이 남습니다. 이 기록은 트랜잭션(Transaction) 이라는 특수한 형태로 저장되는데요. 트랜잭션은 계약을 수행하는데 든 수수료(가스) 등 다양한 정보를 담고 있습니다.
[실행] 버튼을 눌러, 이 계약을 실행해서 만들어진 트랜잭션을 확인해보세요.
트랜잭션이 담은 정보
transactionHash
: 트랜잭션의 해시값transactionIndex
: 트랜잭션의 인덱스 값blockHash
: 이 트랜잭션이 추가된 블록의 해시값blockNumber
: 이 트랜잭션이 추가된 블록의 번호gasUsed
: 이 트랜잭션 호출에 소비한 가스양cumulativeGasUsed
: 누적으로 사용된 가스량contractAddress
: 계약의 주소logs
: event로 로깅된 정보 ( 후속 강의로 다룰 예정 )
이런 트랜잭션들이 모여 하나의 블록(block)을 이룹니다.
이더리움 네트워크 상에는 이러한 블록들이 체인처럼 엮인 모습을 하고 있기 때문에 블록체인(blockchain)이라고 부릅니다.블록체인을 더 자세히 알고 싶다면 클릭하세요!
문제 설명
지금까지 솔리디티의 기초적인 문법들을 만나보셨습니다.
이제는 솔리디티 문법과 DApp(탈중앙화 애플리케이션) 개발을 익혀보려고 합니다.
중개자의 개입이 필요 없는 크라우드펀딩1 Dapp 만들기
우리는 이더리움 블록체인 네트워크상에서 스마트 계약(Smart Contract)으로 중개자나 중개 플랫폼 없이 모든 요구사항을 만족하는 DApp을 만들려 합니다.
이 크라우드펀딩 서비스에는 다음 기능이 있어야 합니다.
- 누구나 아이디어를 등록할 수 있습니다.
- 캠페인에는 목표 금액과 종료 기간이 있습니다.
- 등록된 캠페인 기록은 지워지지 않습니다.
- 누구나 원하는 금액만큼 캠페인에 펀딩할 수 있습니다.
- 펀딩을 해준 사람에 대한 기록이 남습니다.
- 목표 금액을 달성했다면 펀딩 자금은 아이디어 등록자가 가집니다.
- 목표 금액을 달성하지 못했다면 펀딩 자금은 환불됩니다.
시작하기
- 코드 가장 윗부분에 솔리디티 버전
pragma solidity ^0.4.18;
을 명시하고, - 다음 줄에
Crowdfunding
이라는 이름의 계약(Contract) 선언하세요.
크라우드펀딩(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 의 함수를 의미합니다.
이 상태 변수/함수를 선언한 계약 내부에서는 이 상태 변수/함수를 호출할 수 없습니다.
문제 설명
우리는 이더리움 블록체인 네트워크상에서 스마트 계약으로 중개자나 중개 플랫폼 없는 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
- 학교
- BFS
- 텐서플로우
- 백준알고리즘
- TensorFlow
- MVC
- 알고리즘
- node.js
- 코드엔진
- Controller
- Spring
- 스프링
- C언어
- programming
- C langauge
- 노드
- Algorigm
- 안드로이드
- Android
- db
- 복습
- 감자코딩
- 리버싱
- 초보자를 위한 C언어 300제
- 백준
- 머신러닝
- 감자개발자
- node
- 프로그래밍
- 개발하는 관광이
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |