본문 바로가기

블록체인_9기/⛓ BlockChain

62강_230920_Blockchain(이더리움(ethereum)백서, Web3을 이용해 간단하게 이더리움 맛보기)

728x90

 

 

 

 


이더리움 백서

이더리움이 발표되기(2015) 전, 창시자인 비탈릭 부테린에 의해 발간된 백서이다.(2014) 이 백서는 발간된지 몇 년이 지났음에도, 유용한 참고문헌이 되고 있다고 한다. 백서를 통해 이더리움에 대해 알아보고자 한다.

 


차세대 스마트 컨트렉트 &  탈중앙화 어플리케이션 플랫폼

사카시 나카모토는 2009년 화폐 시스템의 혁명적 발견이라고 인정받는 비트코인을 개발했다. 이 화폐는 지지 또는 내재가치가 없는 동시에 중앙화된 발행자 또는 관리자가 없는 디지털 자신의 첫 사례이다.

비트코인이 각광을 받으며 비트코인의 기술적 배경인 블록체인 기술은 세간의 관심을 받게 되었다. 블록체인 기술의 또다른 응용 예시로 인용되는 어플리케이션들이 있는데 어플리케이션은 다음과 같다.

사용자 정의 화폐와 금융 상품을 블록체인 위로 표현하기 위한 컬러 코인
실제 기기의 소유권을 표현하는 스마트 프로퍼티
 도메인 이름과 같은 비동질적 자산을 기록하는 네임 코인
임의의 코드가 적용되어 직접 컨트롤되는 디지털 자산 스마트 컨트랙트
블록체인 기반의 탈중앙화 및 자동화된 조직(DAO)

이더리움에서 제공하고자 하는 것은, ' 컨트랙트(계약)'를 만드는 데 사용될 수 있는 튜링완전 프로그래밍 언어가 내장된 완성형 블록체인이다. 이 점은 이더리움이 비트코인과 어떻게 다른지를 확인할 수 있는 부분인데, 비트코인과 이더리움의 차이점은 다음과 같다.

비트코인은 '결제'라는 포커스에 맞춰져 구현을 했다면, 이더리움은 탈중앙화한 어플리케이션을 제안했다고 보면 된다.

튜링 완전 프로그래밍 언어는 코딩된 규칙에 따라 어떤 상태를 다르게 변환시키는 기능이 포함된 계약을 만든다. 이 계약은 유저들이 작성할 수 있게 하여, 사용자들이 자신의 요구사항에 따라 스마트 컨트렉트를 작성하고 실행할 수 있도록 한다. 더 나아가, 이더리움의 목표는 사용자들이 아직 상상하지 못한 어플리케이션을 상대적으로 쉽게 만들 수 있도록 돕는 것이다.

 

🙄 튜링 완전??
 튜링 완전(Turing Complete)이란, 어떤 프로그래밍 언어나 추상 머신이 튜링 머신과 동일한 계산 능력을 가진다는 의미의며 튜링 머신으로 풀 수 있는 문제. 즉 계산적인 문제를 그 프로그래밍 언어나 추상 머신으로 풀 수 있다는 의미이다.

그렇다면 튜링 머신이 뭐지?? 🤷‍♀️
수학자이자 컴퓨터과학자인 엘런 튜링이 1936년에 제시한 개념으로, 계산하는 기계의 일반적인 개념을 설명하기 위한 가상의 기계이며 오토마타의 일종이다. 튜링은 원래 a-machine이라 호칭되었지만, 튜링 사후에 창시자의 이름을 따 튜링 머신이라고 부르게 되었다.

 

 


비트코인 및 기존 암호화폐의 히스토리

탈중앙화된 디지털 화폐 개념은 수십 년 동안 존재해왔던 개념이다. 하지만 사회는 중앙화된 중개자에게 의존했기 때문에 거래량을 확보하는 것에 실패했다. 아래의 개념들은 지금까지의 탈중앙화 개념이 나오기까지 시도되었던 개념들이다.

  1. b-머니 : 1998년, Wei Dai가 탈중화된 합의 뿐만 아니라 계산 퍼즐을 해결함으로써 돈을 만들어내는 아이디어를 처음으로 제시했다. 하지만, 실제로 어떻게 탈중앙화를 가능하게 하는지에 대한 설명이 부족했다.
  2. 재사용 가능한 작업 증명 : 2005년, Hal Finney가 소개한 개념이다. 이 시스템은 b-머니의 아이디어와 함께 Adam Back의 계산적으로 어려운 해시 캐시 퍼즐을 사용하여 암호화폐에 대한 개념을 만들었다. 하지만, 신뢰할 수 있는 컴퓨팅을 백엔드로 사용한다는 점에서 한계를 가졌다.

 

출처 : https://m.blog.naver.com/bodoblock00/221657805838

이 과정 이후로 2009년 사토시 나카모트는 공개키 암호화를 기반으로 하는 소유권 관리와 '작업증명'이라고 알려진 소유자 추적을 위한 합의 알고리즘(POW)을 결합해 탈중앙화 화폐를 최초로 구현했다. 여기서 작업증명을 가능하게 하는것은 혁신이었는데, 혁신이라 칭하게 되는 이유는 두 가지 문제를 해결했기 때문이다.

  1. 합의 알고리즘 제공 : 네트워크를 구성하는 노드들이 비트코인 원장의 상태에 대한 정식 업데이트들에 동의하는 방식의 간단하고 효과적인 알고리즘을 제공했다.
  2. 누구나 합의 프로세스 참여 : 합의 프로세스에 참여하는 이를 제한하지 않으므로써, 합의 참여자를 결정하는 정치적 문제를 해결하면서 동시에 시빌 공격(sybil attacks)을 예방하였다.

POW는 보안성이 높다는 장점이 있지만, 에너지 소모가 크고 블록 생성 시간이 길어 트랜잭션 처리가 느리다는 단점이 있다. 채굴자가 많아 질수록 채굴 난이도는 높아지기 때문에 트랜잭션 속도는 더욱 느려지고 채굴에 들어가는 전력은 더욱 많아지게 된다. 환경에 악영향을 끼치고 트랜잭션 속도가 느려지기 때문에 확장성 또한 낮아지게 된다. 또한 누구나 합의 프로세스에 참여할 수 있기 때문에 컴퓨터 파워가 많이 올라가다보니 채굴에 급급한 마이너들이 그룹을 만들어 자기들끼리 보상을 나누어가는 형태가 되었다. 이런 형태가 거대해지만 결국엔 이 그룹이 중앙화의 형태를 띌 수 있기 때문에 문제점으로 지적되었다.

 

출처 : https://m.blog.naver.com/bodoblock00/221657805838

이러한 문제를 해결하기 위해 이더리움은 지분 증명(POS)이라는 새로운 방식의 합의 알고리즘으로 바꾸는 방법을 선택하게 된다. 연산을 통해 블록을 검증하는 POW와 달리, 가상자산 보유량에 비례해 검증할 수 있는 권한을 부여하는 POS 방식은 이전 방식에 비해 전력 사용량이 적다. 

 

 


상태 전환 시스템으로써의 비트코인

사실 이 부분은 아직 제대로 된 이해가 되질 않아 수업 때 받아적은 내용을 기입한다. 추후 다시 살펴보도록 하자!

  • 이더리움 백서에서는 비트코인의 트랜잭션을 상태변환 시스템이라고 한다.
  • 비트코인의 트랜잭션은 UTXO인데 이더리움은 트랜잭션의 내용을 상태 처리라고 하고 있다.
  • 우리가 배운 내용에서 쉽게 보자면, 추상적으로 '리액트의 상태' 라고 봐도 무방하긴 하다.
  • 상태에 대해 간단히 설명하면, 쇼핑몰을 만들었는게 상품을 구매하는 프로세스에서 상품의 현재 상태를 나타낼 테이블을 하나 만들었다.
    • 상품 테이블에 주문이라는 상태가 있다.
    • 보통 주문의 흐름은 ' 주문 접수 -> 결제 확인 -> 상품 준비 -> 상품 출고 -> 배송중 -> 배송완료 -> 수령완료 ' 로 진행된다.
    • order (주문 테이블) -> state (상태 컬럼)
    • UTXO -> Transaction -> UTXO
    • 우리가 UTXO를 통해 계정의 Account들의 balance를 구했다.
    • 새로운 트랜잭션 처리가 되면 새로운 UTXO를 만들어 주는 것을 상태에 비유했다.

 

 


비트코인_스크립팅

비트코인의 경우 정말 낮은 수준이지만 '스마트 컨트랙트'를 지원하고 있다. 비탈릭 부테린의 경우, 서명에 관한 로직을 스마트 컨트랙트라는 시점으로 바라보고 있다. 비트코인의 UTXO는 공개키만으로 해당 계정의 잔액을 조회할 수 있다. 뿐만 아니라 간단한 스텍 기반의 프로그래밍 언어로 구현되는 조금 더 복잡한 스크립트에 의해서도 소유되어 있다. 기본적으로는 한 명의 서명을 만들어 트랜잭션 생성을 처리하는데, 비트코인에서는 2, 3개의 개인키를 가지고 서명을 만들어서 검증을 할 수 있도록 간단한 스크립팅을 작성할 수 있다. 하지만 이런 방법은 어렵고 실용성이 없기 때문에 실제로 사용하는 플랫폼은 없다.

비트코인 상에서 구현된 스크입트 언어는 몇 가지의 치명적인 단점이 존재한다.

  • 튜링 완전의 부재 : 비트코인 스크립팅 언어는 다양한 로직 연산을 지원하지만, 모든 연산이 가능한 것은 아니다. 그 중 하나 예시를 들자면 비트코인 스크립팅은 거래 검증 과정에서 무한 루프를 피하기 위해 루프 처리가 불가능하다. 이 단점은 if문을 사용해 기본 코드를 여러번 반복하면 극복할 수는 있지만, 불필요하게 길어진 코드가 발생하게 된다.
  • Value-blindness : 하나의 UTXO 스크립트가 얼마를 인출할 수 있는지에 대한 세세한 제어를 제공하는 것은 불가능하다.
  • 상태의 부재 : UTXO는 소비되거나 소비되지 않거나 둘 중 하나의 상태이기 때문에 이외의 다른 내부적인 상태를 가지도록 하는 멀티 스테이지 계약이나 스크립트를 만드는 것은 불가능하다.  
  • Blockchain-bilndness : UTXO는 블록의 논스, 타임스탬프, 해시 등과 같은 정보를 담고 있지 않는다. 잠재적으로 유용하게 쓰일 수 있는 랜덤성이라는 가치를 스크립팅 언어로 부터 제외시키기 때문이다.

 

 


이더리움

이더리움 백서에 따르면, 이더리움의 목적은 탈중앙화된 어플리케이션을 만들기 위한 대체 프로토콜을 만드는데 있으며, 이는 특히 짧은 개발 시간, 규모가 작고 많이 사용되지는 않는 어플리케이션에서의 보안, 다른 어플리케이션과의 효율적인 연결이 중요한 다양한 탈중앙화와 어플리케이션들에게 유용한 다른 형태의 트레이드오프를 제공할 것이라고 한다. 

비트코인은 예금이나 보험 및 금융 상품, 사이트 및 게임에 적용하기 힘들다. 여러가지 이유가 있지만, 대표적으로 비트코인 자체가 결제 시스템에 포커스가 맞춰져 있어 결제에 관련된 부분만 처리를 하고 있기 때문에 이자의 부분은 따로 구현해서 처리해야 한다.

하지만 이더리움의 경우 분산 어플리케이션(Dapp)을 이용해서 적은 시간으로 탈중앙화를 사용해 데이터를 저장하는 사이트 혹은 게임을 만들수 있다. 이더리움은 탈중앙화랑 통신할 수 있는 프로토콜을 유저가 쉽게 구현할 수 있도록 도와주며 탈중앙화에 데이터를 저장할 수도 있는 것이다. 이를 스마트 컨트랙트라 말하기도 한다. 따라서, 이더리움은 비트코인의 UTXO 형식적인 데이터가 아닌 상태에 대한 변화를 만들어서 다양한 데이터를 저장하고 사용할 수 있도록 트랜잭션의 구조를 완전히 바꾼 것이다.

 

 


이더리움 어카운트

이더리움의 상태(state)에는 ' account '(계정)라고 하는 객체로 구성되어 있다. 각 계정은 20바이트 크기의 주소와 계정들 간에 이루어지는 가치 및 정보의 직접적인 거래를 뜻하는 상태 전환을 담고 있다. 이더리움 계정은 다음의 프로퍼티를 가진다.

  interface Account {
    nonce: number; // 트랜잭션의 횟수 카운터 (이중지불 방지 용도)
    balance: string; // 이더리움의 잔액
    storageRoot: string; // account의 상테 저장 공간(초기에는 비어있다.)
    codeHash: string; // 스마트 컨트랙트 계약의 코드
  }

 

이더리움의 '계정'이라고 하는 개념은 우리가 일반적으로 인터넷에 접속할 때 사용하는 ID계정이라고 생각하면 된다. 다음은 프로퍼티에 대한 간단한 설명이다.

  • 논스
    • 탈중앙화된 이더리움 환경에서 프로그램이 실행되거나 어떠한 요청이 왔을 때 처리해주기 위한 중요한 장치이다.
    • 탈중앙화된 방식에서는 순차적인 처리가 쉽지 않은데, 채굴자들이 사용자들의 요청을 처리할 때 이 논스(nonce)값을 확인하여 일종의 프로그램 처리에 대한 순차적인 규칙을 정한다.
  • 이더 잔고
    • 비트코인의 UTXO 방식과 달리 이더리움에서는 이더의 잔고를 직접적으로 확인할 수 있다.
  • 저장공간
  • 계약코드
    • 스마트 컨트랙트의 실행코드가 저장되고, 여기에 기록된 코드를 통해서 스마트 컨트랙트 프로그램이 실행된다.

이더리움에는 ' 이더(ETH) '라는 이더리움 플랫폼의 화폐가 있다. 이 이더는 트랜잭션을 발생시킬 때 수수료를 지불하는데, 이더리움 네트워크는 ' 이더 '라는 화폐가 없으면 코드를 실행할 수 없게 하기 위해 만들었다. 데이터 또한 저장할 수 없다.

 

💡 Account의 두 가지 개념

👩‍🏫 EOA(외부 소유 계정 / Externally owned account)

  • 주소와 비밀키로 구성되어 있다.
  • 프라이빗 키에 의해서 통제되는 외부 소유 어카운트이다.
  • 다른 계정으로 이더를 송금하고 수신할 수 있다.
  • 개인키가 존재하고 개인키를 가지고 서명을 해서 트랜잭션을 생성한다.
  • 스마트 컨트랙트에 트랜잭션을 보낼 수 있다.
  interface Account {
    nonce: number; // 트랜잭션의 횟수 카운터 (이중지불 방지 용도)
    balance: string; // 이더리움의 잔액
    storageRoot: string; // ❌사용❌
    codeHash: string; // ❌사용❌
  }

 

👩‍🏫 CA(컨트랙트 계정 / Contract account)

  • 컨트랙트 코드에 의해 통제되는 컨트렉트 어카운트이다.
  • 스마트 컨트랙트를 블록체인에 배포할 때 생성된다.
  • 개인키가 없어 전송이 불가하며, 메시지를 발생시킬 수 없다.
  • CA는 Message라는 것을 받으면 CA가 자신의 코드를 활성화 시키고, Message가 어떤 값인지를 보고 읽거나 상태 변수의 내용을 변경할 수 있으며 보낼 수도 있다.
  interface Account {
    nonce: number; // 트랜잭션의 횟수 카운터 (이중지불 방지 용도)
    balance: string; // 이더리움의 잔액
    storageRoot: string; // account의 상테 저장 공간(초기에는 비어있다.)
    			// value 상태 변수를 키가 값의 형태로 데이터 저장을 한다.
    codeHash: string; // 스마트 컨트랙트 계약의 코드. 코드를 컴파일해서 결과를 저장한다.
  }
  
  // 솔리디티 언어
    pragma solidity ^0.8.0

  contract testContract {
    uint256 value;          // 상태 변수 선언
    function setValue(unit256 newValue) public {
        value = newValue;       // 상태 변수를 변경
        function getValue() public view returns (uint256){
            return value;       // 상태 변수 조회
        }
    }
  }

 

 


메시지와 트랜잭션

이더리움에서 트랜잭션EOA에 의헤 서명되며 자금 이체, 계약 데이터 업데이트 또는 다른 스마트 계약과의 상호 작용과 같이 Ethereum 블록체인의 전역 상태에 대한 변경이 필요한 작업에 사용된다. 메시지는 이더리움의 상태계 내에서 다른 스마트 계약이나 계정과 통신해야 할 때 스마트 계약(CA)에 의해 생성된다. 메시지는 실행 중인 계약의 코드에 의해 제어되므로 서명되지 않는다.

interface Message {
  from: string; // 메시지를 보내는 account or 컨트랙트의 주소
  to: string; // 메시지를 받는 어카운트 or 컨트랙트 주소
  gas: number; // 메시지를 처리하기 위해 사용할 가스의 양
  gasPrice: number; // 가스 당의 가격
  value: number; // 메시지와 함께 전송할 이더 량
  data: string; // 메시지 데이터
  nonce: number; // 메시지를 전송한 account의 nonce값
}

interface Transaction extends Message {
  v: number; // 서명 v 값.
  r: string; // 서명 r 값.
  s: string; // 서명 s 값.
}

// 가스는 이후에 우리가 좀 더 진행을 하면서 추가로 알아볼건데
// 예를 들어, 우리가 차를 끌고 주유소에 가서 리터 당 얼마인지 확인을 한다.
//// 1L 당, 2000원
//// 알기로는 byte당 5gas로 측정된다.

 

 

 


Web3을 이용해 간단하게 이더리움 맛보기

ganache 설치

먼저 가상의 이더리움 네트워크를 생성해 스마트 컨트랙트를 실행하기 위해 ganache 모듈을 다운받고 실행해 가상의 공개키와 비밀키를 받는다. 10개의 주소를 생성해주며, 각 주소마다 100ETH가 주어진다.

# ganache 설치
npm i -g ganache-cli

# ganache 실행
npx ganache-cli
# 실행 시 터미널에 뜨는 결과화면이다.
	Available Accounts
        ==================
        (0) 0xA0A7e3f7eD2726ff500cfE409981aB2De64328e6 (100 ETH)
        (1) 0x1C2AbdE613628eDe5575210399c98724816608EF (100 ETH)
        (2) 0xD7a1e4a97F9EE8BAd5C9fbbB3938495158C02Ddd (100 ETH)
        (3) 0xf50CE8305cd526680146C51ee2D809aAFFD183B8 (100 ETH)
        (4) 0xC3343BA734E693c48D50045f038bf22be3f9C378 (100 ETH)
        (5) 0x1D928592d24272b932cc48DC193EEB4B35f74cC6 (100 ETH)
        (6) 0x3862bAf03bcb6DE04064e5D404e180137f948CB2 (100 ETH)
        (7) 0xA5B191e1224572a4AAAeE44280b2Bba2Fffe8719 (100 ETH)
        (8) 0xb8C7068C71268986712c36B2C90Fa258EF33FbcC (100 ETH)
        (9) 0x6ea0c70f7d6F7C968Fee4192cBA0EEF7c697c69e (100 ETH)

        Private Keys
        ==================
        (0) 0xbbc7f76cdd99c2f8d740f96bc8f24a7d4a8d1bc8564e04b6a7c96d199d264d52
        (1) 0x7246f51424328022950d391a29608a66fa0112f7163db03312c00c94399baef0
        (2) 0x6c9ff1135108757ec83c213453a35515abc66d9c6b905c5e0e4163090c18b082
        (3) 0xc52482370f6478fe78b9f78bd7df2ac0cb55e29c0b58d8aeb70cced6bbdc8611
        (4) 0xaaf498156208ba98c22c846fb36dcce65ed8b91f975755939ef952abe12e09ea
        (5) 0xbc3ef7bc70ee9490306d250ba7875eeaa59b2de5360ffecd19902686a2c134a2
        (6) 0x29255fd5a23642dd6908a693472bd16464cc75be6c15487afa91a137c5cd8ced
        (7) 0x2fc74c5c230d0a7cc9e36297adbaeebbc53723933933929f40d809e91e1ada59
        (8) 0x6cb00fffdeea0f5f0b73139945df6b2ad4213867917209f377bbe65a208007e8
        (9) 0xeca677d0f1b425be37862a6b1f6e3a8baf83ce403ade616aaa337092b466ca33

        HD Wallet
        ==================
        Mnemonic:      undo salmon expect awake spirit reject rain harbor guide shed decline move
        Base HD Path:  m/44'/60'/0'/0/{account_index}

        Gas Price
        ==================
        20000000000

        Gas Limit
        ==================
        6721975

        Call Gas Limit
        ==================
        9007199254740991

        Listening on 127.0.0.1:8545

 

특정 호스트 IP 주소로 Ganache CLI를 시작할 수 있도록 터미널에 명령어를 입력한다. ' -h 0.0.0.0 '명령으로 Ganache CLI가 바인딩 하는 호스트 IP 주소를 지정한다. ' 0.0.0.0 '으로 설정하여 Ganache CLI가 사용 가능한 모든 네트워크 인터페이스를 수신하도록 한다.

npx ganache-cli -h 0.0.0.0

 

Web3 초기화

Web3 라이브러리의 새 인스턴스를 생성하고 요청할 네트워크의 URL을 설정한다.

    const web3 = new Web3("http://127.0.0.1:8545");

 

이더리움 계정을 불러오기

' web3.eth.getAccount() '를 사용하여 로컬 블록체인 환경에서 사용가능한 이더리움 계정 목록을 불러온다.

    web3.eth.getAccounts().then(console.log);
    /* 결과
        (10) ['0xA0A7e3f7eD2726ff500cfE409981aB2De64328e6', 
        '0x1C2AbdE613628eDe5575210399c98724816608EF', 
        '0xD7a1e4a97F9EE8BAd5C9fbbB3938495158C02Ddd', 
        '0xf50CE8305cd526680146C51ee2D809aAFFD183B8', 
        '0xC3343BA734E693c48D50045f038bf22be3f9C378', 
        '0x1D928592d24272b932cc48DC193EEB4B35f74cC6', 
        '0x3862bAf03bcb6DE04064e5D404e180137f948CB2', 
        '0xA5B191e1224572a4AAAeE44280b2Bba2Fffe8719', 
        '0xb8C7068C71268986712c36B2C90Fa258EF33FbcC', 
        '0x6ea0c70f7d6F7C968Fee4192cBA0EEF7c697c69e']
    */

 

이더리움 계정 잔액 가져오기 및 단위 변환

' web3.eth.getBalance() ' 메소드를 사용하여 특정 이더리움 계정의 잔액을 검색한다. 이더리움의 공개키를 메서드의 매개변수에 문자열로 넣어준다. 계정의 잔액은 Wei 단위로 반환된다.

' web3.utils.fromWei() ' 메소드를 사용해 매개변수로 받은 Wei 단위의 값을 10진수로 반환해준다.

    web3.eth
      .getBalance("0xA0A7e3f7eD2726ff500cfE409981aB2De64328e6")
      .then((data) => {
        console.log(data);
        /* 결과
            100000000000000000000 */
        // wei라는 단위로 뜨는데
        // 10 ** 18으로 측정이 됩니다.
        // 이 단위가 있는 이유는 가스비 연산에 사용하기 위해서

        // 단위 변환
        const value = web3.utils.fromWei(data);
        console.log(value);
        /* 결과
            100 */
      });

 

 

 

 

 

 

더보기
728x90