인턴 Study #6. Smart Contract 와 Solidity

beoms96·2020년 7월 31일
0

인턴 공부

목록 보기
7/11
post-thumbnail

0. 스마트 컨트랙트

스마트 컨트랙트란?

스마트 계약(smart contract)또는 스마트 컨트랙트란 블록체인 기반으로 금융거래, 부동산 계약, 공증 등 다양한 형태의 계약을 체결하고 이행하는 것을 말한다.

1994년, 닉 자보가 처음 제안했고, 2013년 비탈릭 부테린에 의해 이더리움이라는 가상화폐속에서 스마트 계약 기능을 구현했다.

출처: 위키백과

1. EVM

Solidity를 구동할 수 있는 이더리움 가상 머신이다. 이더리움 가상 머신과 관련된 내용이다 보니 이더리움 구조에서 설명한 부분이 중복될 수 있다.

1) 계정

  • 외부 계정: 공개키, 비밀키 쌍으로 동작, 공개키에 의해 정해짐
  • 컨트랙트 계정: 생성되는 시점에 정해짐. (생성한 사용자의 주소, 주소로부터 보내진 트랜잭션의 수 - '논스' 로부터 기반)

모든 계정은 256비트의 문자열들이 서로 키-값으로 영구히 매핑된 스토리지 가지고 있음.

2) 트랜잭션

대상 계정이 코드를 포함하고 있으면 코드는 실행되고 페이로드(Binary Data)는 입력 데이터로 제공
대상 계정이 설정되지 않은 경우 트랜잭션은 새 컨트랙트 생성, 논스의 의해 주소 결정.

각 트랜잭션 생성 데이터 페이로드는 EVM 바이트 코드로 실행되기 위해 사용.
컨트랙트를 만들기 위해 실제 코드를 보내는 대신, 실행될 때의 코드를 리턴하는 코드를 보내야 함.

  • 컨트랙트가 생성되는 동안, 컨트랙트의 코드는 비어있다. 이 때문에 생성자가 실행을 끝낼 때까지 트랜잭션을 다시 호출하면 안된다.

가스 = 가스 가격 * 가스 양 지불

4) 스토리지, 메모리, 스택

  • 스토리지: 데이터 영역, 함수호출과 트랜잭션 사이에서 영구적으로 존재한다.
  • 메모리: 메시지 콜에 대해 초기화된 인스턴스, 메모리는 선형이며 바이트 레벨로 다뤄진다. 변경되지 않은 메모리 워드 영역에 액세스 시 메모리는 256 비트 워드 영역으로 확장하고, 가스 비용을 지불한다.
  • 스택: 모든 연산이 스택이라는 영역에서 처

5) 메시지 콜

컨트랙트가 다른 컨트랙트 호출하거나 컨트랙트 아닌 계정으로 Ether를 송금할 수 있음.
송신자, 수신자, 데이터 페이로드, Ether, 가스와 리턴 값을 가지고 있어 트랜잭션과 유사하다.

  • 델리게이트 콜 / 콜코드와 라이브러리
    델리게이트 콜: 대상 주소의 코드가 호출하는 컨트랙트의 컨텍스트 내에서 실행되고, msg.sender / msg.value 값이 변하지 않는다는 것 외에는 메시지 콜과 동일하다.
    컨트랙트가 실행 중 다양한 주소의 코드를 동적으로 불러온다.

  • 로그
    블록 레벨까지의 모든 절차를 매핑, 특별히 인덱싱된 데이터 구조 데이터를 저장하는 것도 가능하다.
    이벤트를 구현하기 위해 사용하며, 일부 로그 데이터는 bloom filters 안에 저장해 효율적이고 암호화되어있으며 안전하다.

  • 생성
    페이로드 데이터가 실행되고, 결과가 코드로 저장된다, 호출자와 생성자가 스택의 새 컨트랙트 주소를 받는 다는 점이 일반 메시지 콜과 다르다.

  • 비활성화와 자기소멸
    selfdestruct 연산이며 주소에 저장된 남은 ether는 지정된 타켓으로 옮겨지고 스토리와 코드는 해당 상태에서 지워진다.
    비활성화: 내부상태 disable

2. Solidity

4가지의 Keyword

  • natspec: 3개의 슬래시, 유저가 트랜잭션에 대한 확인을 요청 받을 때 보여진다.
  • payable: 이더를 지급하는 것이 가능하도록 한다.
  • modifier: 함수 입력값을 입증하는 편리한 방법이다.
  • internal: 이 컨트랙트 안에서 이것 스스로만 호출 될 수 있다는 의미이다.

3. ERC20 토큰

OpenZeppelin 을 통해 토큰을 생성하는 것을 추천한다. (규격이 정해져있기 때문)

ERC20 토큰을 생성하기 위해 필요한 Solidity 파일 목록들

1. ERC20Basic.sol

Abstract Contract: 구현되지 않은 함수 하나라도 있으면 된다. 이것만 쓰면 컴파일 되지 않는다.
ERC20Basic 컨트랙트는 totalSupply, balanceOf, transfer 함수를 가지고 내부에서 Transfer 이벤트를 발생시킬 수 있다.

transferFrom(제 3자가 대신 송금해주는 기능) 제외

  • totalSupply: 발행한 전체 토큰의 자산
  • balanceOf(who): who 주소의 계정의 자산
  • transfer(to, value): 내가 가진 토큰 value 개를 to 에게 보내라. '나'는 가스를 소모해 transfer 호출한 계정
  • Transfer: 내부 호출되는 이벤트 함수

ERC20 에 따르면 토큰이 이동할 때에는 반드시 Transfer 이벤트 발생 해야 한다.

  • view 함수는 수수료 소모 X
  • pure 함수는 블록체인 데이터와 무관한 함수 (읽어오지도 않음)
  • event 함수는 외부에 신호를 보내기 위한 함수
  • indexed 변수는 검색에 사용될 것임을 명시. 검색을 위한 해시테이블에 저장. 한 개의 이벤트 함수에 최대 3개 변수까지 indexed 가능.

2. BasicToken.sol

  • is: 상속 - ERC20Basic Contract 가 부모 컨트랙트.
  • using A for B - B 자료형에 A 라이브러리 함수를 붙여라.
  • mapping: 하나의 변수에 여러 값을 저장하기 위한 map 변수 타, 다중 map 도 가능.
  • require: 조건이 참인지 체크, 거짓이면 예외처리 (실행 중단, 아예 모든 실행 취소) 발생, 가스 비용 아낄 수 있음.
  • msg.sender: 가스비용을 내고 컨트랙트 함수를 호출한 유저 계정 (EOA), msg.sender 가 CA일 수도 있음. (ICO 과정 때 설명)

2.1. SafeMath.sol

안전한 사칙연산 라이브러리 by OpenZeppelin

3. MyBasicToken.sol

1 ether = 10 ** 18 wei 이기 때문에 보통 18승으로 함.

4. ERC20.sol

  • approve: spender 에게 value 만큼의 토큰을 인출할 권리 부여, Approval 이벤트 함수 꼭 써야함.
  • allowance: owner 가 spender 에게 인출을 허락한 토큰의 개수는 몇개인가
  • transferFrom: from 의 계좌에서 value 개의 토큰을 to 에게 보내라. approve 함수를 통해 인출할 권리를 받은 spender 만 실행가능.

5. StandardToken.sol

  • allowed: approve 함수를 통해 누가 누구에게 얼마의 인출 권한을 줄지 저장한다.

allowed[누가][누구에게] = 얼마;

  • approve: 이더리움의 경우에는 채굴이 되기 전까지는 실행이 되자않기 때문에, 늦게 실행한 코드가 먼저 동작하는 경우 생긴다.
    따라서 인출한 권리를 바꿔줄때 0으로 바꾸고 다른 값으로 변경하기를 추천한다.

  • ERC20 규약에는 X, increaseApproval, decreaseApproval: 0으로 변경하고 다시 변경하는 거 안하고 쉽게 해주기 위해서이다.

출처: Solidity 공식 홈페이지, OpenZeppelin Github

profile
beoms96 개발 노트

0개의 댓글