레이블이 블록체인인 게시물을 표시합니다. 모든 게시물 표시
레이블이 블록체인인 게시물을 표시합니다. 모든 게시물 표시

2022년 12월 1일 목요일

truffle, solidity, 이더리움을 활용한 스마트 계약 개발환경 설치 및 구현 방법

이 글은 truffle, solidity를 활용한 스마트 계약 개발환경 구축 및 구현 방법을 간략히 설명한다.

머리말
일반적으로 계약은 다자간 요구사항들을 만족하는 컨센서스(합의) 절차와 가치 교환 알고리즘이 포함된 프로그램이다. 다음 그림은 이를 잘 보여준다.
일반적인 계약 구조

솔리디티는 계약을 디지털화하기 위한 유명한 스마트 계약 언어 중 하나이다.
스마트 계약 개발 언어들

여기서는 솔리디티 언어를 사용해 간단한 스마트 계약 프로그램을 개발하고, 이를 배포해 본다.

개발환경 설치
다음과 같이 개발환경을 설치한다.
sudo npm install -g truffle
truffle init

스마트 계약 개발
다음과 같이 솔리디티 언어로 코딩한다. 자세한 내용은 여기를 참고한다. 
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;

contract Hero{
    address owner;
    string hero;
    constructor(string memory _hero)
    {
        owner=msg.sender;
        hero=_hero;
    }
    
    function setHero(string memory _hero)public
    {
        require(msg.sender==owner,"Not the owner");
        hero =_hero;
    }
    function getHero() public view returns(string memory)
    {
        return hero;
    }
}

truffle-config.json 파일을 다음과 같이 생성한다.
module.exports = {
  compilers: {
    solc: {
      version: "0.8.1",   
    }
  },
};

다음과 같이 컴파일한다.
truffle compile


다음과 같이 컴파일된 결과를 build폴더에서 확인할 수 있다. 

배포를 위해 이더리움 시뮬레이터인 Ganache를 다운로드한다.


다음과 같이 실행 권한으로 파일을 수정한다.
chmod +x ganache-2.5.4-linux-x86_64.AppImage 

해당 파일을 실행하고, 퀵스타트 버튼을 클릭한다. 10개의 월렛이 리스트될 것이다.

배포를 위해, truffle-config.js 파일을 다음과 같이 업데이트한다.
module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 7545,
      network_id: "*"
    }
  },
  compilers: {
    solc: {
      version: "0.8.1",   
    }
  },
};

레퍼런스

2021년 4월 8일 목요일

대체불가능 토큰 NFT 개념과 직접 만들어보기

이 글은 대체불가능 토큰 NFT 만드는 방법을 간략히 설명한다. 

최근, 언론에 작가 비플이 NFT 기술을 접목해 만든 이미지 파일 한 점이 2021.11 미국 뉴욕 크리스티 경매에서 약 780억원에 낙찰된것으로 알려지면서 NFT에 대한 관심이 많아지고 있다. 비플 말고도, 트레버 존슨의 '비트코인 천라'라는 작품들 중 하나는 428만원에 거래되는 등 거래량도 늘어나고 있다. 엘론 머스크의 아내이자 가수인 그라임스도 대체불가능한 토큰(NFT)으로 20분 만에 65억을 벌었다. 

이 글은 NFT 개념과 만드는 방법을 간략히 이야기한다.

Everydays: The first 5000 days (NFT)
The Bitcoin Angel

머리말
대체 불가능한 토큰 (NFT) 은 독립형 암호화 토큰 유형이다. 대체 불가능한 토큰은 검증 가능한 디지털 컨텐츠 희소성을 보장하는 데 사용될 수 있다. 

비트코인은 1BT가 동일한 가치를 보장해, 코인 간 서로 대체가 가능한 토큰인 반면, NFT는 각 토큰이 서로 다른 가치를 저장할 수 있다. 서로 다른 가치를 토큰이 가지므로, 토큰끼리는 서로 대체 불가능하다. NFT는 1 토큰 당 가치가 모두 다르다. 

NFT도 물론 블록체인속에 저장 및 기록되어, 소유권 확인 및 추적, 거래 내역 등을 지원한다. NFT는 어떤 종류의 고유한 항목이 필요한 산업에 유용 할 수 있다. 예를 들어 예술 작품이나 사용자의 고유한 업적을 식별하는 데 사용된다. 

다른 지갑에 두 개의 비트 코인이 있다면 완전히 동일하다. 두 개의 NFT는 내부 값이나 토큰 특이성에서 개별적으로 서로 같지 않다. 구별은 대체 불가능한 토큰에 할당된 해시값으로 처리한다. 

블록 체인 세계에 구축되고있는 금융 시스템은 큰 단점이 있다. 예를 들어, 부동산 자산은 산업 요구 사항에 따라 설정된 자산별 복잡성 및 보안 요구사항으로 인해 블록 체인에서 디지털 정보로 완전히 표현할 수 없는 경우가 많다. 기존 자금 조달 프로세스(IPO), 블록 체인 산업(ICO, IEO, STO)에 대해서도 마찬가지이다. 

현재 시가 총액은 아직 매우 적다. 자산에 대한 현물 가격이 부족하기 때문에, 암호 화폐 시장에 비해 측정하기가 더 어렵다. 2차 거래량(peer-to-peer)을 기준으로 월별 수치는 $2-3백만에 가깝다. 2018년 크립토 키티(CryptoKitties)의 광고 이후 NFT와 상호 작용하는 사용자의 수는 느리지만 지속적으로 증가하고 있다.

Standard를 통해 개발자는 자산별로 동작을 프로그래밍하고, NFT를 기반으로 하는 자산의 기능과 상호작용하는 방법에 대한 자세한 지침을 설정할 수 있다.
NFT 개발방법

이런 표준 및 코딩 없이도 NFT 생성을 지원하는 서비스를 사용해, 자신의 컨텐츠를 NFT화할 수 있다. 다음은 NFT 지원 서비스 웹사이트이다.
  • Opensea: 암호화된 디지털 아이템 판매 마켓
  • Mintable: 블록체인 아이템 판매 마켓
  • SuperRare: 디지털 예술품 소장 및 거래 

NFT 표준 개념
이 표준은 CryptoKitties에서 처음 사용되었다. ERC-721은 대체 불가능한 디지털 자산 생성을위한 최초의 규약이다. 언급된 표준의 가장 큰 이점은 개발자가 간단히 OpenZeppelin도구를 통해 ERC-721호환 계약을 작성할 수 있다는 것이다. 이 규약은 계정 간의 가치를 교환하는 다음과 같은 인터페이스를 구현해야 한다.

    function balanceOf(address _owner) external view returns (uint256);
    function ownerOf(uint256 _tokenId) external view returns (address);
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function approve(address _approved, uint256 _tokenId) external payable;
    function setApprovalForAll(address _operator, bool _approved) external;
    function getApproved(uint256 _tokenId) external view returns (address);
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);

ERC-721은 transferFrom 메소드를 사용하여 이러한 자산을 전송하는 방법도 제공한다.
여기에서 ERC-721 에 대한 자세한 내용 (기술 사양 포함)을 확인할 수 있다.

ERC-1155
ERC-1155를 개발 한 Enjin 팀은 NFT 에 반 대체성에 대한 아이디어를 가져 왔다. 표준은 단일 자산이 아닌 여러 자산 그룹을 나타낼 수 있다.  
여기에서 ERC-1155 에 대한 자세한 내용을 확인할 수 있다 .

Non-Ethereum Standards
블록 체인 중 하나인 FLOW는 NFT 프로젝트에 개방되어 있으며 이미 NBA , UFC 및 기타 유명 기업과 제휴하여 이러한 브랜드의 팬들을 위한 공동 독점 NFT 아이템을 개발했다. 여기에서 FLOW 블록 체인으로 NFT를 만드는 방법에 대해 자세히 알아볼 수 있다 .

직접 만들어보는 NFT
원래는 NFT를 만들기 위해서, 이더리움 가스(GAS)나 이더(ETH)를 구입해 비용을 지불해야 한다. 하지만, Mintable에 NFT를 생성하면, 가스를 지불하지 않고도 작업을 시작할 수 있다. 

전체 NFT 개발 순서는 다음과 같다.

전자지갑 개설(은행계좌 개설) - 지갑 연결 및 생성 - 판매 아이템 등록 - 아이템 판매

다음과 같이 서비스 무료 계정을 생성한다. 이메일 주소로 전송된 인증 코드를 입력한다.

이제, MetaMask 지갑을 만들자. 크롬에서 여기를 클릭해, 브라우저 확장을 설치한다.

새로운 MetaMask 지갑을 시작한다.

지갑을 설정하려면 비밀번호를 제출해야한다. 그 답례로 12 개의 무작위 단어 목록 인 "시드 문구"를 받게된다. 어딘가에 적어 둔다. 이후, 다음을 클릭해, 해당 시드 문구를 확인해야 한다. 통과하면 다음 메시지를 만나게 된다.

그리고, 보유한 이더(ETH)를 확인할 수 있다.

이제, Mintable로 돌아가서“Mint an item”을 클릭한다. 

지갑에 NFT가 이미 존재하는지 (존재하지 않음) 또는 새 지갑을 생성하는지 (현재 존재 함)를 선택하라는 메시지가 표시된다. 

Mintable은 기본적으로 가스없는 NFT로 설정된다. 여기서 원하는 것을 업로드 할 수 있으며, 판매 또는 양도 될때까지 블록 체인에 들어 가지 않는다(물론, 수수료가 발생하지 않는다). 만약, 예전 방식으로 작업을 수행하려면 슬라이더를 클릭하고, 고급 모드로 이동하여 트랜잭션 모델을 선택할 수 있다(대신 수수료 지급해야 함).

다음과 같이 MetaMask와 지갑을 연결한다.

이제, 다음과 같이, 자신의 컨텐츠를 NFT로 생성할 수 있는 아이템 작성 및 판매 화면이 보일것이다. 

이제, 가치가 있는 자신의 컨텐츠를 업로드하고, 개별 파일이 있다면 추가하면 된다. 그 결과 다음과 같이 대체불가능한 토큰으로 처리된 작품이 등록된다. 여기서는 강선우가 작업 디자인한 The Beatles 패러디 작품을 등록해 보았다. 그 결과는 다음과 같다.
마무리
NFT의 모든 규약을 마스터하고, NFT를 만들수도 있지만, 그렇지 않고, 이를 지원하는 서비스를 이용해 만들 수도 있다. NFT는 아직 초기 단계이므로, 여러가지 이슈가 있다. NFT를 판매할 때는 비용 구조를 완벽히 이해해야 한다. 판매 시 가스 수수료, 거래 수수료 등을 지급해야 한다. 이런 부분을 이해하지 않고, 진행하면 손해를 볼 수도 있다. 

현재 NFT로 팔리는 것은 상상을 초월한다. TZCOLORS는 색상도 판매하고 있는 데, 1111XTZ는 한화 500만원에 팔리기도 했다. 앞으로 NFT는 어느 정도로 성장할지는 확실치 않지만, 사람들이 많은 관심을 가지리라는 것은 예상할 수 있다.

레퍼런스

2018년 12월 27일 목요일

직접 간단히 만들어보는 블록체인과 가상화폐


이 글은 블록체인 동작 메커니즘 이해하고자 하는 싶은 분을 위해 핵심 개념만 간단히 개발하는 과정을 공유한다.

좀 더 자세한 내용은 아래 링크를 참고한다.

우선 요구사항을 정해보자
블록체인 개발전에 블록체인 개념을 내포하는 몇가지 요구사항을 정의해야 한다.
  • 가상화폐: 가치 교환을 위한 디지털 가치 보관 수단
  • 지갑: 개인이나 조직 가상화폐를 보관하는 전자 계정
  • 트랜잭션: 데이터의 변화를 기록한 단위
  • 블록: 트랜잭션을 기록한 단위. 데이터 변조를 막기 위해 해쉬 암호화 사용
  • 마이닝: 블록을 관리하는 컴퓨팅 소모 자원에 대한 대가 지급
  • 스마트 계약: 상호간 거래시 계약 불이행을 방지하기 위한 수단

간단히 만들어 보는 블록체인 
우선 요구사항을 바탕으로 아키텍처를 디자인해보자.

요구사항에 해당하는 객체를 모두 클래스화한다. 그리고, 각 클래스간 관계를 디자인한다. 예를 들어, 코인과 화폐는 서로 관계가 있다.

코인은 가치를 보관하는 개념이다. 트랜잭션은 쌍방간의 계약중 하나이며, 가치의 변경을 담는 역할이다. 블록은 트랜잭션의 변화를 기록한다. 블록은 링크드리스트(linked list) 자료구조로 정의된다. 블록의 위변조는 해쉬값으로 알 수 있다. 블록체인은 블록을 생성하고 관리한다. 스마트계약은 트랜잭션을 발생시킨다.

이를 디자인하면 다음과 같다.
클래스 디자인(UML)

앞의 디자인을 반영해 중요한 부분만 코딩하면 다음과 같다.
 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class coin
{
public:
   double value = 0;
}

class wallet
{
public:
   string accountAddress;
   coin coin;
}

class transaction
{
public:
   string fromAcccount, toAccount;
   coin trasnferValue;
   string calculateHash() {return SHA256(this)};
}

class block
{
public:
   const int MAX_BLOCK_TRANSCTION 40
   int countTransaction = 0;
   transaction[MAX_BLOCK_TRANSACTION];
   block* previousBlock = NULL;
   block* nextBlock = NULL;

   int insertTransaction(transaction& t);
   string calculateHash();
}

class blockChain
{
public:
   block* createGenesisBlock();
   coin* miningBlock(int hash, block& block);
   block* insertBlock(block* b);
}

class smartContract
{
public:
   void setScript(string code);
   bool execute();

private:
   string code;
   python contractScript;
}
style by hilite

마무리
이 글은 블록체인과 스마트 계약 구현 원리를 이용해 보기 위해 간단히 아키텍처를 디자인해보고, 코드로 구현해 보았다. 사실, 이외 여러 기능과 구성요소가 필요하나, 다양한 블록체인 플랫폼의 핵심적인 내용은 비슷하다. 좀 더 상세한 내용은 다음 레퍼런스를 참고하길 바란다. 

레퍼런스

2018년 11월 3일 토요일

간단한 BIM 기반 스마트 계약 개발하기

이 글에서는 BIM 기반 스마트 계약을 개발할 때, 어떤 방식으로 진행하는 지를 간략히 설명한다.

스마트 계약 개발 절차
개발은 보통 요구사항 정의, 분석, 설계, 개발 및 테스트로 진행된다.  요구사항 정의 시 사용되는 방법 중 하나가 유스케이스 분석이다. 유스케이스 분석을 통해, 실제 사용 사례와 시나리오를 정리한다.

유스케이스 정의
BIM의 경우 제일 큰 이슈 중 하나가 디지털 모델 변경이 다수 관계자간에 진행되어, 모델의 신뢰성 보장이 어렵다는 것이다. 신뢰성 보장을 위해서는 모델에 대한 이슈 발생과 처리 시 과정을 추적할 수 있어야 한다. 이슈 관리 이력을 분산원장(블록체인)에 저장해, 모델 변경 이력을 추적할 수 있도록 하고, 모델에 대한 신뢰성을 확보한다. 그래서, 유스케이스를 BIM 협업 상황에서 모델 변경 관련된 모델링 이슈 이력 관리로 한다. 모델 변경 시 관련 트랜잭션 정보는 다음과 같이 가정한다.

1. BIM file URL = resource_type://address+directory
2. Issue No = IS###
3. Issue reason = enum {element_collision, element_missing, invalid_data, etc}
4. Sender = email
5. Receiver = email
6. Date = YYYY/MM/DD
7. State = enum {open, progress, solved, close}

구현해 보기
앞의 유스케이스를 스마트 계약으로 구현해 보면 다음과 같다.

pragma solidity ^0.4.0;
contract BIM_modeling_issue {
    struct Issue {
        uint no;
        string url;
        uint reason;
        string sender, receiver;
        string date;
        uint state;
    };
    Issue[] issues;

    /// Create a issue
    function BIM_modeling_issue(uint8 num) public {
        issues.length = num;
    }

    function findIssueBySender(string sender) public Issue returns (Issue _is) {
        for(uint8 i = 0; i < issues.length; i++)
        {
            if(issues[i].sender == sender) { 
               _is = issues[i];
            }
        }
    }
}



BIM 모델링 이슈 데이터를 관리하는 Issue 구조체를 정의하고, issues 배열을 만든다. sender가 생성한 issue를 찾는 findIssueBySender라는 간단한 함수를 만들어 보았다. 이 스크립트는 Solidity 계약 개발을 지원하는 REMIX등에서 실행할 수 있다.


레퍼런스
Welcome to Remix documentation!
Create Your First Smart Contract In Ethereum With Ganache And Remix IDE
Build Your First Ethereum Smart Contract with Solidity — Tutorial


2018년 2월 26일 월요일

이더리움 소스 빌드 및 스마트 계약 개발 소개

이 글은 우분투에서 이더리움 소스코드 빌드 실행 방법과 스마트 계약 개발 방법을 간략히 소개한다.
스마트 계약(Smart Contract)이란 블록체인 기반으로 금융거래, 부동산 계약, 공증 등 다양한 형태의 계약을 체결하고 이행하는 것을 말한다(wikipedia). 스마트 계약은 1996년 닉 자보(Nick Szabo)가 처음 제안했다.

만약, A, B간에 날씨에 따른 스마트 계약을 하였을 때는 계약이 참여자간 분산되어 실행되며, 참여자간 동의 없이 취소될 수 없고, 계약 실행 조건이 변경될 수 없다. 이를 위해, 계약은 프로그램으로 작성되며, 계약과 거래는 분산 저장된다. 다음 영상은 그 개념을 보여준다.
스마트 계약 개념

이더리움은 비탈릭 부테린이 개발한 블록체인 기반 스마트 계약 개발 지원 분산 플랫폼이다. 이더리움 화폐 단위는 이더(ETH)이다. 이더리움은 블록체인 기반 암호 화폐거래 기술을 스마트 계약(smart contract) 플랫폼으로 확장했다. 이런 이유로 전세계에 많은 컨소시엄이 만들어졌고, 블록체인 기반의 계약에 대한 관심을 크게 촉발시켰다. 현재, 스마트 계약과 관련된 많은 어플리케이션이 개발되고 있다.
블록체인 기반 스마트 계약 개념
이더리움 기반 투표 어플리케이션 예(Full Stack Hello World Voting Ethereum)

이더리움에서 스마트 계약을 개발하기 위해서는 솔리디티(solidity)와 LLL(Low-level Lisp-like Language)언어를 사용해야 한다. 이 부분은 차후에 좀 더 다뤄보기로 한다.

PPA(Personal Package Archives) 설치
이더리움 PPA는 다음과 같이 설치한다.
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

설치 후 노드에 계정을 생성하기 위해 다음 명령을 실행할 수 있다. 
geth account new



이더리움 네트워크에 연결하기 위해 geth 명령을 실행한다. 

소스 코드 다운로드 및 빌드
다음과 같이 소스 코드를 다운르드한다.
git clone https://github.com/ethereum/go-ethereum

이더리움은 가상머신에서 동작하며, Go, C, Python과 같은 다양한 언어로 개발되었다.
작업이 쉬운 Go언어로 개발된 이더리움을 빌드하기 위해 Go, C 컴파일러를 설치한다.
sudo apt-get install -y build-essential golang

golang는 1.7버전 이상이 필요하다. 혹시, 제대로 설치되지 않으면, 링크(1.7)를 참고해 설치한다. 이제 다음과 같이 다운로드된 소스 폴더에서 빌드한다.
cd go-ethereum
make geth

이제 build/bin/geth 폴더에서 다음 명령을 실행할 수 있다.
geth

 

이더리움과 스마트 계약 개발 방식
이더리움은 이더리움 가상 머신(EVM) 기반으로 동작한다. 이 가상머신 기반으로 실제 스마트 계약 모델을 개발하는 방법은 사실 쉽지는 않다. 이런 이유로 솔리디티(solidity)가 개발되었다. 솔리디티 설치는 다음 링크를 참고한다.
솔리디티는 객체지향언어와 유사하다. 계약은 솔리디티 계약이나 이더리움 트랜잭션을 통해 외부에서 만들어 질 수 있다. 다음 그림은 스마트 계약 개발을 위해 사용되는 솔류션 조합의 예를 보여준다.
스마트 계약 개발을 위한 솔류션 조합(Distributing Business Processes using Finite State Machines in the Blockchain)

다음은 간단한 스마트 계약 클래스 정의 예이다.

contract SimpleStorage {
   uint storedData;
   function set(uint x) {
      storedData = x;
   }
   function get() constant returns (uint) {
      return storedData;
   }
}

다음 영상은 날씨에 따른 스마트 계약 개발의 예를 보여준다.

솔리디티 기반 계약 개발의 좀 더 자세한 방법은 아래 링크를 참고한다.
LLL은 리습과 유사한 언어고, 마찬가지로 스마트 계약 모델 개발 시 활용한다. 이 두가지 개발 언어는 작성된 계약 모델이 빌드되면 가상 머신 코드로 전환된다. 참고로, 솔리디티보다 LLL이 생성된 코드는 30% 효율적이다. 다음은 LLL 예시와 관련 튜토리얼 영상이다.

(def 'only-node-owner (node)
  (when (!= (caller) (get-owner node))
    (panic)))


Remix(리믹스)와 같은 도구를 이용해 개발할 수도 있다. 이더리움에서 프로그래밍으로 계약 개발하는 방식은 JavaScript API web3.js 사용 방법이 있다. web3.eth.Contract를 사용한다.

이더리움 스마트 계약에 대한 좀 더 상세한 내용은 아래 링크를 참고한다.

레퍼런스

2018년 2월 22일 목요일

비트코인 소스 코드 빌드, 사용 및 블록체인 코드 구조 분석

얼마전 BIM principle에 올린 블록체인과 BIM - 스마트 계약을 위한 블록체인 기술에 대한 기고 요청이 있었다. 이 글은 4차 산업혁명의 핵심 키워드로 알려진 블록체인 응용인 비트코인 정체와 내부 메커니즘을 좀 더 깊이 확인하고 설명하기 위해, 개발용 소스 빌드, 설치 및 사용 과정을 수행하고, 블록체인 핵심 구조 및 코드에 대한 분석 내용을 간단히 요약한다. 이 과정을 통해, 블록 체인 개념과 실제 구현을 이해할 수 있고, 기술을 제대로 응용할 수 있을 것이다.
스마트 계약 개발 시 주로 많이 활용되는 이더리움에 대해서는 아래 글을 참고하길 바란다.
블록체인 개념을 좀 더 요약한 슬라이드 자료가 있다.
블록체인의 핵심 개념은 중앙에서 거래(트랜잭션)의 신뢰성과 추적성을 관리하는 것이 아니라, 거래 참여들이 트랜잭션 정보를 분산 저장하여, 신뢰성과 추정성을 확보하는 것이다.

참여자간 거래 내역을 블록체인으로 보관(MIT Technology Review)

이를 위해, 각 참여자들은 블록을 연결해, 트랜잭션의 변화를 관리한다.

블록체인을 이용한 비트코인 기본 동작 과정은 다음과 같다. 참고로, 사토시가 쓴 논문(한글버전)과 이더리움 위키을 읽으면 전체 개념을 알기 쉽다.
1. A가 B에게 송금
2. 블록(장부)가 생성됨
3. 생성된 블록이 블록체인 참여자들에게 전파됨
4. 참여자들이 해당 거래의 신뢰성을 체크함
5. 신뢰성이 확보되면, 해당 블록은 기존 블록체인에 추가됨
6. 양쪽의 거래 완료

주요 활용 개념은 다음과 같다.

암호화: A, B가 가진 전자지갑 계좌에 금액 이체 등 거래를 하려면, 각자가 발행한 공개키 암호키가 있어야 한다. 본인의 계좌를 상대방에게 전달할 때는 본인임을 증명할 수 있는 키를 함께 전달한다.

블록체인과 해쉬: 참여자간 거래를 담고 있는 것이 블록이다. 블록(장부)은 여러개의 거래를 기록한다. 거래는 위변조 안되도록 거래 데이터를 이용해 해쉬값이 생성되어 덧붙여진다. 기록된 블록은 블록체인에 참여한 서버들에게 분산 저장된다.

P2P: 블록체인은 참여자간에 분산 저장된다. 거래가 발생하여 블록에 추가될 때 합리적인 상황인지를 참여자들 간에 합의과정을 거쳐야 한다. 이 과정은 예전 P2P방식 파일 공유와 구조가 매우 유사하게 진행된다. 이는 마치 민주주의에서 의사결정시 합의(컨센서스) 과정을 거치는 것과 유사하다.

통화발행정책: 여기서 블록을 생성하는 역할을 마이너가 수행한다. 마이너는 블록을 생성하기 위해서는 블록을 유일하게 증명하는 해쉬를 생성해야 한다. 비트코인은 블록의 해쉬를 푸는 마이너에게 비트코인으로 보상한다. 마이너가 풀어야 하는 해쉬 문제는 시간이 지나면서 난이도가 높아져 인플레이션을 방지하도록 되어 있다.

여기서는 블록체인 소스코드가 어떻게 앞의 블록체인 개념을 구현하고 있는 지 분석한다. 분석을 위해 구글링을 통해 발견한 비트코인 빌드 관련 가장 잘 설명되어 있는 링크1링크2를 참고한다. 비트코인 프로토콜은 여기를 참고한다. 클래스 멤버 설명은 비트코인 doxygen 위키를 참고한다. 설치 과정은 다음과 같다.

블록체인 소스 빌드
블록체인 소스 빌드를 위해 우분투 운영체계를 미리 준비한다. 만약, 윈도우에서 우분투 설치하려면, Hyper-V, VirtualBox, VMware 등 가상머신 위에서 처리해도 된다. 여기에서는 우분투 16.04를 사용하였다.

개발용 소스 빌드 설치 시스템 업그레이드를 한다.
sudo apt-get update
sudo apt-get upgrade

아래 패키지를 설치한다. 디펜던시 에러가 알 수 있다. 에러는 로그를 확인해 해결하도록 한다. 
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
sudo apt-get install libboost-all-dev
sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler
sudo apt-get install libqrencode-dev autoconf openssl libssl-dev libevent-dev
sudo apt-get install libminiupnpc-dev

Bitcoin 소스를 다운로드 한다.
cd ~
git clone https://github.com/bitcoin/bitcoin.git

Bitcoin 은 버클리 데이터베이스 4.8을 사용한다.

이를 설치한다. 단, 경로 지정시 theusername 부분은 로그인한 계정 이름과 소스 설치 경로를 고려해 수정하라. 참고로, 버클리 데이터베이스는 메모리 상에서 계산 처리하는 방식을 취해 처리 속도가 매우 빠르다.
cd ~
mkdir bitcoin/db4/
cd bitcoin/db4
wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
tar -xzvf db-4.8.30.NC.tar.gz
cd db-4.8.30.NC
mkdir build_unix
cd build_unix
../dist/configure --enable-cxx --disable-shared --with-pic --prefix=/home/theusername/bitcoin/db4/
make install

Bitcoin, Berkley DB 4.8 을 컴파일한다.
cd ~/bitcoin/
./autogen.sh

디펜던시 에러가 나면, 아래 명령을 실행해 본다.
./configure LDFLAGS="-L/home/theusername/bitcoin/db4/lib/" CPPFLAGS="-I/home/theusername/bitcoin/db4/include/"

그리고 다시 /autogen.sh 를 실행한다.  이제 컴파일을 한다.
make -s -j5

제대로 빌드되었다면, 다음 화면을 볼 수 있다. 

아래 폴더에 바이너리 파일이 있다면 성공한 것이다.
cd ~/bitcoin/
./src/bitcoind
./src/qt/bitcoin-qt
./src/bitcoin-cli

블록체인 사용
블록체인은 일반적인 블록체인 네트워크와 테스트용 네트워크를 제공한다.

1. 일반 네트워크 서버 실행
\빌드된 블록체인을 서비스하는 서버를 실행해 본다.
$ ./bitcoind -daemon
Bitcoin server start

그리고, 다음 명령을 이용해 동기화된 블록수를 확인해 본다.
$ ./bitcoin-cli getblockchaininfo

그럼 다음과 같이 표시되고, 블록수가 출력된다.

백그라운드로 실행되고 있는 bitcoin-d를 다음 명령으로 프로세스 번호를 확인한다.
$ ps -ef | grep bitcoin

확인된 프로세스를 다음과 같이 실행 종료 시킨다.
$ kill -process_number

2.  테스트 네트워크 서버 실행
블록체인 테스트 네트워크 망에서 거래를 테스트해보자. 이를 위해 다음 명령을 실행한다.
$ ./bitcoind -regtest -daemon

3. 블록 생성
101개 블록을 생성한다. 거래는 이 블록에 이력 기록된다.
$ ./bitcoin-cli -regtest generate 101

블록 수를 확인해 본다.
$ ./bitcoin-cli -regtest getblockcount
101

4. 타 계좌 생성
계좌를 생성한다(ktw를 사용하고 싶은 다른 이름을 변경한다).
$ ./bitcoin-cli -regtest getnewaddress ktw
2N8Bm2d2mGFAF7z2FZSRHvdpSNUt39zWa5X

기본 잔고 BTC를 확인해 본다.
$ ./bitcoin-cli -regtest getbalance
50.00000000

앞서 생성한 계좌의 잔고를 확인해 본다.
$ ./bitcoin-cli -regtest getbalance ktw
0.00000000

5. 송금 
10 BTC 송금하기 위해 송금처, 송금액을 지정해 트랜잭션을 발생한다. 이 결과로 트랜잭션 식별번호(txid)가 리턴된다.
$ ./bitcoin-cli -regtest sendtoaddress [앞에서 생성한 계좌번호] 10

트랜잭션을 확인해 본다.
$ ./bitcoin-cli -regtest listunspent
[
]

미확정된 트랜잭션을 다시 확인해 본다.
$ ./bitcoin-cli -regtest listunspent 0

송금자의 잔고를 다시 확인해 본다.
$ ./bitcoin-cli -regtest getbalance
49.99996240

미확정 트랜잭션을 확정하기 위해 채굴을 실행한다. 이 결과로 블록체인에는 채굴로 인한 트랜잭션이 블록에 저장되고, 트랜잭션이 블록에 저장되어 송금이 확정된다.
$ ./bitcoin-cli -regtest generate 1
[
 "36254b11d6c28434b0e14a2a84d633d38e46177d9298a56e132346a3d340be0c"
]

송금 확정되었는 지 다시 확인해 본다.
$ ./bitcoin-cli -regtest listunspent

이런식으로 거래 이력이 블록에 기록되고, 참여자간 거래 정보가 공유된다. 블록에 기록된 정보가 참여자간에 다르면, 누군가 정보를 위조한 것이다.

6. 잔고 확인
잔고를 확인해 본다.
$ ./bitcoin-cli -regtest getbalance ktw
10.00000000

UI기반 비트코인 도구 사용
UI기반 비트코인을 사용하기 위해 빌드된 /src/qt/bitcoin-qt 를 실행해 보자.
다음과 같이, Bitcoin Core가 실행될 것이다.

아직은 비트코인 지갑에 아무것도 없다. 메뉴에서 Options 를 선택하고, 언어를 다음과 같이 한국어로 설정한다.


프로그램을 종료하고 다시 실행다면, 다음과 같이 한글 인터페이스를 볼 수 있다. 이제 지갑을 만들고, 거래를 하면 된다.

참고로, UI QT메뉴에서 호출되는 기능을 담당하는 모듈은 다음과 같다.

소스코드 분석 과정
이제 제대로 동작되고 있으니, 핵심적인 소스코드를 분석해, 동작 방식을 좀 더 상세히 확인해 본다. 참고로, 다른 괜찬은 코드 분석 사례를 여기에서 참고할 수 있다. 그리고, 비트코인 doxygen 위키에서 관련 클래스의 설명을 확인할 수 있다. 사토시가 쓴 논문(한글버전)을 읽으면 전체 개념을 알기 쉽다. 소스코드와 기본적인 문서를 확인하였으니, 이제 소스 코드의 역공학을 통해 동적 실행 및 정적 구조를 분석해본다. 비트코인 소스코드는 C++로 개발되어 있다. 비트코인 문서를 보면, 비트코인 어플리케이션 클래스 간 참조 그래프를 확인할 수 있다.

정적 모델 구조
정적 모델 구조는 주로 데이터, 구조체, 클래스 구조를 주로 확인한다. 가장 기본적인 몇 가지 구조를 살펴보자. 사토시 나카모토가 비트코인 개발 할 때 가장 핵심이 되는 구조는 primitives, wallet 패키지에 담겨져 있다. 패키지 모듈 간 의존성 그래프를 보면, 다음과 같이 primitives 정보를 wallet이 의존하고 있는 것을 알 수 있다.
그외 중요한 패키지는 다음과 같다.
  • RPC: 블록체인 네트워크 참여자간 명령이나 데이터를 주고 받음
  • consensus:  머클트리(merkle) 트리를 관리하고, 참여자간 컨센서스를 처리함. 머클트리는 트랜잭션을 요약해 암호화한 해쉬값을 관리함

1. primitive 패키지
primitives 패키지는 블록체인의 핵심이 되는 구조인 블록, 트랜잭션 구조가 정의되어 있다. 블록체인과 트랜잭션 정보를 관리한다.

블록들을 연결하는 블록체인 인덱스는 CBlockIndex 클래스에 다음과 같이 정의된다. 


CBlockIndex는 CBlock의 베이스 클래스이고, 블록의 체인을 연결하는 구조는 다음 클래스 다이어그램과 같이 블록 정보를 가지고 있는 해쉬맵과 블록 인덱스를 이용해 관리된다. 실제 블록 체인 데이터는 디스크에 저장되고, 필요할 때 메모리로 serialization된다.

블록 정보의 신뢰성과 추적성을 확보하는 방식은 해쉬와 트랜잭션 이력을 블록 체인이 담아두는 구조에 있다. 해쉬 생성은 다음 호출 그래프와 같이 SHA256함수를 사용한다.

블록마다 트랜잭션 이력 정보가 다음과 같이 리스트 형식으로 관리된다. 트랜젹션은 입금 CTxIn, 출금 CTxOut 클래스를 리스트로 관리하고 있다. 출금은 출금 BTC를 저장하는 nValue를 가지며, 최대 BTC 는 사토시가 정의한 21000000 이다. 입금은 입금 트랜잭션 해쉬를 관리하는 COutPoint를 보관한다. 각 입출금 트랜잭션은 트랜잭션 시나리오가 정의된 CScript를 가지고 있어, 다양한 트랜젹션 시나리오 계산을 지원한다. CScript는 바이트 연산자를 처리하는 가상머신이며, 트랜잭션 계산에 특화되어 있다.

2. wallet 패키지
wallet(지갑. 계정)을 관리한다. 데이터는 CDB클래스를 통해 저장된다. 이를 활용하기 쉽게 CWalletDB를 정의하고 있다. DB를 사용하는 CWallet은 거래를 위한 개인키, 공개키를 지갑에 설정하여, 트랜잭션 시 보안을 지원한다. 지갑은 트랜잭션 정보가 관리되는 블록체인과 연결되며, 거래되는 계정 장부(address book)를 관리한다.
wallet 주요 클래스 구조 

지금까지 분석된 비트코인 정보 모델 구조를 매우 간략하게 요약하면, 다음과 같다.
동적 실행 모델 구조
비트코인 전체 동작을 기술하는 것은 지면한계상 어려우니, 핵심적인 블록체인 처리 부분만 실행 구조를 분석해 보자.

1. 비트코인 서버 실행
비트코인 서버 메인인 bitmaind.cpp를 분석해 본다.

int main(int argc, char* argv[])
{
    SetupEnvironment();   // 비트코인 환경 설정
    noui_connect();           // 비트코인 서버 기능 처리 핸들러 등록


    return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);  // 서버 시작
}


bool AppInit(int argc, char* argv[]) 함수는 bitmaind 서버 옵션에 따라 필요한 함수를 호출한다. 이 함수은 다음과 같은 구조이다.
bool AppInit(int argc, char* argv[])
{
        AppInitBasicSetup();   // 어플리케이션 기본 설정
        fRet = AppInitMain();  // 메인 초기화
}

AppInitMain()이 호출되는 부분을 grep -r "AppInitMain" ./* 으로 확인해 본다.

AppInitMain가 코딩된 init.cpp를 확인한다. 주석에 Satoshi Nakamoto 2009 카피라이트를 발견할 수 있다. 라이센스는 MIT이다.
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.


bool AppInitMain()
{
    RegisterAllCoreRPCCommands(tableRPC);
    RegisterWalletRPC(tableRPC);

    bool fLoaded = false;
    while (!fLoaded && !fRequestShutdown) {

        do {
                LoadBlockIndex(chainparams);       // 블록 인덱스 로딩
                LoadGenesisBlock(chainparams);   // 최초 블록 제너시스 블록 로딩
                pcoinsdbview->Upgrade();              // 비트코인 뷰 업그레이드
                ReplayBlocks(chainparams, pcoinsdbview.get());  
                RPCNotifyBlockChange(true, tip);   // 블록 변경시 변경 공지함
        }
    }

    OpenWallets();   // 지급 열기
}

이 중 관심이 가는 Load다GenesisBlock() 을 확인한다. validation.cpp에 있다.
bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
{
    LOCK(cs_main);   // 쓰레드 동기화를 위한 락 처리

    if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash()))  // 이미 블록 맵에 제네시스 블록이 등록되어 있으면, 굳이 로딩할 필요 없이 리턴함.
        return true;

        CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock());  // 블록 생성
        CDiskBlockPos blockPos = SaveBlockToDisk(block, 0, chainparams, nullptr); // 블록을 저장

        CBlockIndex *pindex = AddToBlockIndex(block); // 블록 인덱스에 블록 추가
        CValidationState state;
        ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus()); // 블록 트랜잭션 처리

    return true;
}

블록은 아래 함수를 통해 기존 블록 맵과 인덱스에 삽입되며, 입력된 해쉬값을 새로 생성된 해쉬값과 쌍으로 만들어, 다시 해쉬값을 생성한다. 각 블록의 해쉬가 일부 변경되면, 블록 체인의 모든 해쉬값은 재계산되어야 하고, 블록체인 참여자의 해쉬값도 모두 변경되어야 하므로, 위변조가 어렵다. 참고로, mapBlockIndex는 해쉬값을 생성하여, 해쉬값으로 객체를 관리하는 컨테이너인 unordered_map의 인스턴스이다.
CBlockIndex* CChainState::AddToBlockIndex(const CBlockHeader& block)
{
    uint256 hash = block.GetHash();   // 입력된 블럭 해쉬값 획득
    CBlockIndex* pindexNew = new CBlockIndex(block);   // 블럭을 생성하고 인덱스를 획득
    pindexNew->nSequenceId = 0;
    BlockMap::iterator mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
    pindexNew->phashBlock = &((*mi).first);    // 새로운 블럭의 해쉬값 생성 후 할당

    BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);  // 이전 블럭 인덱스 획득
    if (miPrev != mapBlockIndex.end())   // 이전 블럭이 있으면
    {
        pindexNew->pprev = (*miPrev).second;   // 새로운 블럭의 이전 블록을 찾은 이전 블록과 체인 연결

        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;  // 깊이 증가
        pindexNew->BuildSkip();
    }
    pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime);   // nTimeMax 타임스탬프 갱신
    pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
    pindexNew->RaiseValidity(BLOCK_VALID_TREE);  // Validity 플래그 마스크 설정
    if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork)
        pindexBestHeader = pindexNew;

    setDirtyBlockIndex.insert(pindexNew);

    return pindexNew;
}


CBlockIndex * CChainState::InsertBlockIndex(const uint256& hash)
{
    BlockMap::iterator mi = mapBlockIndex.find(hash);  // 입력된 해쉬의 블록 획득
    if (mi != mapBlockIndex.end())  // 해쉬가 있으면 해당 블록 인덱스 리턴
        return (*mi).second;

    // Create new
    CBlockIndex* pindexNew = new CBlockIndex();   // 블록 인덱스 생성


    // 주어진 블록 해쉬와 새로 생성된 블록 해쉬를 합친후, 이에 대한 해쉬를 획득함
    mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;  
    pindexNew->phashBlock = &((*mi).first);

    return pindexNew;
}


2. 계좌 트랜잭션 처리
./bitcoin-cli 명령을 이용해 다양한 트랜잭션 처리를 할 수 있다.  명령은 rpcwallet.cpp에 CRPCCommand 구조체 형식의 명령 테이블로 정의되어 있다.

static const CRPCCommand commands[] =
{ //  category  name                    actor (function)        argNames
    //  --------------------- ------------------------          -----------------------         ----------
    { "rawtransactions",    "fundrawtransaction",   &fundrawtransaction,    {"hexstring","options","iswitness"} },
    { "hidden","resendwallettransactions",         &resendwallettransactions,      {} },
    { "wallet","abandontransaction",   &abandontransaction,    {"txid"} },
       ...
    { "wallet","getaddressinfo",        &getaddressinfo,        {"address"} },
    { "wallet","getbalance",             &getbalance,            {"account","minconf","include_watchonly"} },
    { "wallet","getnewaddress",        &getnewaddress,         {"account","address_type"} },
       ...
    { "wallet","gettransaction",        &gettransaction,        {"txid","include_watchonly"} },
       ...
    { "wallet","listlockunspent",      &listlockunspent,       {} },
       ...
    { "wallet","sendtoaddress",        &sendtoaddress,        
       ...
    { "wallet","rescanblockchain",     &rescanblockchain,      {"start_height", "stop_height"} },
    { "generating",         "generate",             &generate,              {"nblocks","maxtries"} },
};

주요 bitcoin-cli 명령 처리 과정을 살펴보자.
generate 명령을 수행하면, 등록된 generate함수가 호출된다.  generate() 함수는 generateBlocks() 함수를 호출하며, 다음과 같은 블록 로직을 수행한다.

UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
{
   int nHeightEnd = 0;
   int nHeight = 0;
   {   
       nHeight = chainActive.Height();        // 체인 높이 획득
       nHeightEnd = nHeight+nGenerate;
   }
   unsigned int nExtraNonce = 0;
   UniValue blockHashes(UniValue::VARR);
   while (nHeight < nHeightEnd)             // 추가할 체인 높이가 될때까지 체인 추가
   {
       CBlock *pblock = &pblocktemplate->block;
       ++nHeight;                                 // 체인 높이 증가
       blockHashes.push_back(pblock->GetHash().GetHex());   // 블록 해쉬를 블록해쉬맵에 추가함
   }
   return blockHashes;
}

sendtoaddress 명령 수행과정을 살펴보자. 이 명령은 다음 같은 옵션을 가진다. 
$ ./bitcoin-cli -regtest sendtoaddress [앞에서 생성한 계좌번호] 10

이를 수행하면, sendtoaddress() 함수가 실행된다. 먼저 request 파라메터에서 계좌번호에 해당하는 CWallet pwallet 객체와 송금할 금액 CAmount nAmount 변수를 얻는다. 송금계좌를 CTXDestination dest 객체에 넣고, 계좌에 대한 트랜잭션 처리를 위해, CWalletTX wtx를 준비한다. 이제 SendMoney() 함수를 호출해 송금한다. 그리고, 송금 트랜잭션에 대한 해쉬값을 얻어 리턴한다. SendMoney() 함수는 트랜잭션(거래) 객체를 생성하여, CommitTransaction() 함수에서 트랜잭션 이력 관리를 위한 링크를 만들고, 거래 사건을 브로드케스팅를 준비한다. 
아래 코드는 이 거래의 핵심적인 코드만 추려 보인 것이다.

UniValue sendtoaddress(const JSONRPCRequest& request)
{
    CWallet * const pwallet = GetWalletForJSONRPCRequest(request);     // 입력 파라메터 정보 획득

    // Make sure the results are valid at least up to the most recent block
    // the user could have gotten from another RPC command prior to now
    pwallet->BlockUntilSyncedToCurrentChain();

    CTxDestination dest = DecodeDestination(request.params[0].get_str());    // 송금 목적지 획득
    CAmount nAmount = AmountFromValue(request.params[1]);                // 송금액 획득
    CWalletTx wtx;
    SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx, coin_control);   // 송금
    return wtx.GetHash().GetHex();       // 트랜잭션 해쉬값 리턴
}


static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)

{

    CScript scriptPubKey = GetScriptForDestination(address);   // 송금 계좌 주소 파싱

    CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};    // 송금 영수증 정보 생성

    vecSend.push_back(recipient);

    pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError, coin_control);     // 트랜잭션 생성

    pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state);   // 트랜잭션 처리

}

bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
{
    AddToWallet(wtxNew);   // wallet에 트랜잭션 객체를 추가해 거래 이력정보를 관리하도록 함
    for (const CTxIn& txin : wtxNew.tx->vin)
    {
         CWalletTx &coin = mapWallet[txin.prevout.hash];   // 이전 트랜잭션 해쉬를 통해, 트랜잭션 객체 획득
         coin.BindWallet(this);                                        // 획득한 트랜잭션 객체와 링크 연결함
         NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
    }
    CWalletTx& wtx = mapWallet[wtxNew.GetHash()];        // 생성된 트랜잭션 객체 획득
    if (fBroadcastTransactions)  // 트랜잭션 브로드캐스트함
         wtx.AcceptToMemoryPool(maxTxFee, state); // 브로드캐스트 메모리풀에 추가. 거래 이력 전파.
    return true;
}


마무리
이 글에서는 비트코인 분석을 위해 소스를 빌드하고, 동작 방식을 확인해 보았다. 코드를 분석해 보면, 복잡하기는 하지만 블록체인 개념에 새로운 기술을 사용한 것은 아니다. 공개키/개인키 암호화, 해쉬함수, 블록과 인덱스 관리 구조, 트랜잭션 이력관리 리스트, 데이터베이스 처리 등은 이미 기존에 많이 활용하던 기술이다. 코드는 깔끔하고, 크게 군더더기가 없어 보이는 데, 트랜잭션 처리에 간단한 가상머신을 만들어, 거래 시나리오를 사용자화할 수 있는 확장성을 지원한 개념이 좋았다.

비트코인에서 사용한 블록체인이 사회적으로 크게 이슈화 된 이유는, 기존 시스템의 신뢰성 확보 방안인 중앙집중식 관리가 네트웍 및 보안 기술의 발달로 분산처리화되면서, 기존 시스템의 기득권과 게임의 법칙이 변화하고 있는 부분에 있다.

컨텐츠의 신뢰성, 무결성, 추적성을 통제하는 모든 시스템에 블록체인 기술을 활용할 수 있다. 스마트 계약(contract)을 구현하기 위해 블록체인을 응용하는 경우가 많아지고 있다. 참고로, 이더리움은 계약과 관련된 정보를 사용자화하여, 블록으로 관리할 수 있는 플랫폼을 제공한다. 이더리움의 많은 개념은 비트코인에서 가져왔다.

블록체인이 만능이 아님은 여러 해킹 뉴스를 통해 접할 수 있다. 이는 기술 활용 전에 사회적, 제도적 준비가 되어 있어야 한다고 생각한다. 아울러, 블록체인을 제대로 활용하기 위해서는 기술에 대한 근본적인 이해가 필요할 것이다.

기타 레퍼런스