// 에드센스

 

므ㅏ

강의출처:


1. 사용할 컨트랙에 대한 정보를 가져온다.

contract("Lottery", ([deployer, user1, user2]) => {
  ...
});

트러플에서는 mocha와 chai를 스마트컨트랙에서 사용할 수 있도록 조절해 놓았다고 한다.

따라서 테스트를 시작할 때 contract 키워드로 시작하면 된다.

 

첫번째 인자로는 컨트랙트 이름이 들어가고,

두번째 인자로는 콜백함수가 들어간다. 이 콜백함수의 파라미터로 ganache-cli에서 생성되는 10개의 account가 들어간다.

즉 최대 10개의 인자를 넣을 수 있다.

 

위 코드처럼 3개를 썼다는 것은 

deployer에 0xd53....

user1에 0xd07....

user2에 0x040....

이렇게 3개의 주소가 파라미터로 들어간 것이다.

 

 

 

 


2. 스마트 컨트랙 배포

테스트를 하려면 스마트컨트랙 코드가 블록에 들어가서 실행되어야 하므로 컨트랙을 배포해주자

contract("Lottery", ([deployer, user1, user2]) => {
  beforeEach(async () => {
    console.log("Before each");
    lottery = await Lottery.new(); //테스트에서 사용할 스마트 컨트랙 배포
  });
});

 

 

 

 


3. 테스트코드 작성

  let betAmount = 5 * 10 ** 15;
  let BET_BLOCK_INTERVAL = 3;
  
  describe("Bet", async () => {
    it("베팅큐에 값이 잘 들어갔는지 확인하기", async () => {
      // 베팅한다
      const receipt = await lottery.bet("0xab", {
        from: user1,
        value: betAmount, // 5 * 10 ** 15 -> 0.005ETH
      });

      // pot머니(상금)은 아직 결과가 들어나지 않았기에 0이어야 한다.
      let pot = await lottery.getPot();
      assert.equal(pot, 0);

      // 컨트랙트 주소로 0.005이더가 들어왔는지 확인한다
      let contractBalance = await web3.eth.getBalance(lottery.address); // web3가 자동으로 주입돼있다
      assert.equal(contractBalance, betAmount);

      // 베팅인포가 제대로 들어갔는지 확인한다
      let currentBlockNumber = await web3.eth.getBlockNumber();
      let bet = await lottery.getBetInfo(0); // 큐 제일 앞의 베팅정보를 가져온다

      // 큐에 넣은 베팅정보가 올바른지 확인
      assert.equal(
        bet.answerBlockNumber,
        currentBlockNumber + BET_BLOCK_INTERVAL
      );
      assert.equal(bet.bettor, user1);
      assert.equal(bet.challenges, "0xab");

      // 로그(BET이라는 이벤트)가 제대로 찍혔는지 확인한다
      await expectEvent.inLogs(receipt.logs, "BET");
    });

    it("0.005이더가 안들어왔을때는 실패해야한다", async () => {
      // 트랜잭션 실패
      await assertRevert(
        // 두번째 인자는 트랜잭션 오브젝트, transaction object란
        // (chainId, value, to, from, gas(limit), gasPrice)
        lottery.bet("0xab", { from: user1, value: 4000000000000000 }) // bet함수 실행 -> 0.004ETH가 들어갔기에 트잭이 실패나야한다
      );
    });
  });

 

 

event, emit을 테스트하기

const assert = require("chai").assert;

// 직접 발생시킨 event의 로그가 있는지 확인한다.
const inLogs = async (logs, eventName) => {
  const event = logs.find((e) => e.event === eventName);
  assert.exists(event);
};

module.exports = {
  inLogs,
};

[Lottery Dapp 개발하기] 2.4까지의 분량이다. 

밀린 블로그 글써내기중이라 그간 했던 분량을 한번에 쑤셔넣는중.

이 글을 읽는 여러분들에게 도움이 되면 좋겠지만 딱히 그럴려고 쓰는 글은 아니고 혼자서 끄적이는 글.

따라서 생략된 설명이나 이걸 왜 설명? 하는 부분이 있을것이다.

 

 

가보자~

강의 출처:


1. 코딩할 것들

  • 스마트 컨트랙
    • 베팅정보를 담는 구조체
    • 베팅정보를 저장할 큐 자료구조
    • 쌓인상금_가져오기()
    • 베팅큐에서_베팅정보_가져오기()
    • 베팅하기()
      • 베팅을_베팅큐로_밀어넣기()
      • 베팅을_베팅큐에서_빼기()
  • 테스트코드 (다음글에서)
    • beforeEach
    • 베팅큐에 베팅정보가 잘 들어간경우 테스트
    • 베팅큐에 베팅정보가 못들어간경우 테스트

 

 

 


2. Lottery.sol에 코딩한 것들

베팅 정보를 담는 구조체

  struct BetInfo {
    uint256 answerBlockNumber; // 맞출 블록의 넘버
    address payable bettor; // 돈을 건 사람 주소, 특정주소에 돈을 보내려면 payable을 써줘야함
    bytes challenges; // 문제. ex) 0xab
  }

 

 

 

BetInfo 구조체를 넣어줄 큐를 구현

  // 매핑으로 큐를 구현하기 위한 변수
  uint256 private _tail;
  uint256 private _head;

  // 키는 uint, 값은 BerInfo인 매핑
  mapping(uint256 => BetInfo) private _bets;

index - value의 쌍을 mapping을 통해 구현한다.

 

 

 

상금 액수 조회하기

  uint256 private _pot;
  
  // 스마트 컨트랙의 변수를 가져와서 쓰려면 view 키워드를 쓴다
  // 더 자세히는, Storage 자료를 읽어서 보여줄때 사용. 수정할때는 사용x
  // Storage 자료는 블록에 영구적으로 기록된 값(하드디스크)
  // 반대인 Memory 자료는 임시로 저장되는 값(RAM)
  function getPot() public view returns (uint256 value) {
    return _pot;
  }

 

 

 

베팅하기

  // 이벤트 객체
  event BET(uint256 index, address bettor, uint256 amount, bytes1 challenges, uint256 answerBlockNumber);

  function bet(bytes challenges) public payable returns (bool result) {
    // 베팅할 금액(0.005ETH)이 제대로 왔는지 확인
    // require는 if역할, msg.value는 컨트랙트가 받은금액, 'Not Enough ETH'은 조건이 false때 출력할 문구
    require(msg.value == BET_AMOUNT, 'Not Enough ETH');

    // 큐에 베팅정보를 넣기
    require(pushBet(challenges), 'Fail to add a new Bew Info');

    // 이벤트 객체를 체인에 기록한다
    // (몇번째 배팅인지, 누가 배팅했는지, 얼마 배팅했는지, 어떤글자로 베팅했는지, 어떤 블록에 정답이 있는지)
    emit BET(_tail - 1, msg.sender, msg.value, challenges, block.number + BET_BLOCK_INTERVAL);
    return true;
  }

event와 emit

트랜잭션이 완료되면 트랜잭션 영수증을 발행한다.

영수증에는 트랜잭션 실행 동안 발생했던 모든 행동로그가 기록되어 있다.

event는 이런 로그를 만들기 위한 객체

emit은 만들어진 event 객체를 체인에 올리기.

더보기

 

 

 

 

베팅정보들을 담은 큐에서 베팅정보 1개 꺼내오기

  function getBetInfo(uint256 index)
    public
    view
    returns (
      uint256 answerBlockNumber, // 반환값1
      address bettor, // 반환값2
      bytes challenges // 반환값3
    )
  {
    BetInfo memory b = _bets[index]; // memory형 변수는 함수가 끝나면 지워짐, storage형 변수는 블록에 영영 기록됨
    answerBlockNumber = b.answerBlockNumber; // 반환값1
    bettor = b.bettor; // 반환값2
    challenges = b.challenges; // 반환값3
  }

 

 

 

베팅큐에 베팅정보 push

  function pushBet(bytes challenges) internal returns (bool) {
    BetInfo memory b; // 베팅정보를 하나 생성하고 세팅한다
    b.bettor = msg.sender; // 함수 호출한 사람
    b.answerBlockNumber = block.number + BET_BLOCK_INTERVAL; // block.number는 현재 이 트랜잭션이 들어가게되는 블록넘버를 가져온다
    b.challenges = challenges; // 내가 베팅한 값

    _bets[_tail] = b; // 큐에 넣고
    _tail++; // 테일 포인터 조정

    return true;
  }

 

 

 

베팅큐에서 베팅정보 1개 pop

  function popBet(uint256 index) internal returns (bool) {
    // 스마트컨트랙에서 덧셈이든, 뺄셈이든 하면 가스를 소모한다.
    // delete를 하면 가스를 돌려받는다. 왜? 이더리움 블록체인에 저장하고 있는 데이터를 더 이상 저장하지 않겠다는 것이기에
    // 즉, 상태 데이터베이스에 있는 값을 그냥 가져오겠다는 것이기에
    // 그러니 필요하지 않은 값이 있다면 delete를 해주자
    delete _bets[index];
    return true;
  }

 

 

 

 


3. 전체 코드

pragma solidity >=0.4.21 <0.6.0;

contract Lottery {
  struct BetInfo {
    uint256 answerBlockNumber; // 맞출 블록의 넘버
    address payable bettor; // 돈을 건 사람 주소, 특정주소에 돈을 보내려면 payable을 써줘야함
    bytes challenges; // 문제. ex) 0xab
  }

  // 매핑으로 큐를 구현하기 위한 변수
  uint256 private _tail;
  uint256 private _head;

  // 키는 uint, 값은 BerInfo인 매핑
  mapping(uint256 => BetInfo) private _bets;

  address public owner;

  uint256 internal constant BLOCK_LIMIT = 256; // 블록해시를 확인할 수 있는 제한
  uint256 internal constant BET_BLOCK_INTERVAL = 3; // 2번 블록에서 베팅을 하면 5번 블록에서 결과가 나온다
  uint256 internal constant BET_AMOUNT = 5 * 10**15; // 0.005ETH

  uint256 private _pot;

  // 이벤트 로그들을 한번에 모을 수 있다, BET이라는 로그들을 찍어줘
  // (몇번째 배팅인지, 누가 배팅했는지, 얼마 배팅했는지, 어떤글자로 베팅했는지, 어떤 블록에 정답이 있는지)
  event BET(uint256 index, address bettor, uint256 amount, bytes1 challenges, uint256 answerBlockNumber);

  constructor() public {
    owner = msg.sender; // msg.sender는 전역변수
  }

  function getPot() public view returns (uint256 value) {
    // 스마트 컨트랙의 변수를 가져와서 쓰려면 view 키ㅕ드를 쓴다
    return _pot;
  }

  // Bet (베팅하기)
  /*
    @dev 베팅을 한다. 유저는 0.005ETH를 보내야하고 베팅용 1byte 글자를 보낸다, 큐에 저장된 베팅 정보는 이후 distribute 함수에서 해결한다
    @param challenges 유저가 베팅하는 글자
    @return 함수가 잘 수행되었는지 확인하는 bool 값
    */
  function bet(bytes challenges) public payable returns (bool result) {
    // 돈이 제대로 왔는지 확인
    // require는 if역할, msg.value는 컨트랙트가 받은금액, 문자열은 조건이 false때 출력할 문구
    require(msg.value == BET_AMOUNT, 'Not Enough ETH');

    // 큐에 베팅정보를 넣기
    require(pushBet(challenges), 'Fail to add a new Bew Info');

    // 이벤트 로그를 찍는다
    // (몇번째 배팅인지, 누가 배팅했는지, 얼마 배팅했는지, 어떤글자로 베팅했는지, 어떤 블록에 정답이 있는지)
    emit BET(_tail - 1, msg.sender, msg.value, challenges, block.number + BET_BLOCK_INTERVAL);
    return true;
  }

  // 베팅한 값을 큐에 저장함

  // Distribute (검증하기)
  // 베팅한 값을 토대로 결과값을 검증
  // 검증결과가 틀리면 팟머니에 돈을 넣고, 맞으면 돈을 유저에게 준다

  // 베팅정보들을 담고있는 큐에서 베팅정보 가져오기
  function getBetInfo(uint256 index)
    public
    view
    returns (
      uint256 answerBlockNumber,
      address bettor,
      bytes challenges
    )
  {
    BetInfo memory b = _bets[index]; // memory형 변수는 함수가 끝나면 지워짐, storage형 변수는 블록에 영영 기록됨
    answerBlockNumber = b.answerBlockNumber; // 반환값1
    bettor = b.bettor; // 반환값2
    challenges = b.challenges; // 반환값3
  }

  // 큐 push
  function pushBet(bytes challenges) internal returns (bool) {
    BetInfo memory b; // 베팅정보를 하나 생성하고 세팅한다
    b.bettor = msg.sender; // 함수 호출한 사람
    b.answerBlockNumber = block.number + BET_BLOCK_INTERVAL; // block.number는 현재 이 트랜잭션이 들어가게되는 블록넘버를 가져온다
    b.challenges = challenges; // 내가 베팅한 값

    _bets[_tail] = b; // 큐에 넣고
    _tail++; // 테일 포인터 조정

    return true;
  }

  // 큐 pop
  function popBet(uint256 index) internal returns (bool) {
    // delete를 하면 가스를 돌려받는다. 왜? 상태데이터베이스에 저장된 값을 그냥 뽑아오겠다는 것이기에
    // 그러니 필요하지 않은 값이 있다면 delete를 해주자
    delete _bets[index];
    return true;
  }
}

정말 오~랜만에 글을 쓴다.

써야지 써야지 하면서 너무 미뤘다.

 

 

 

더 이상 글을 안쓰면 블로그를 영영 잊게될까봐 다시 자리에 앉았다.

그래도 그간 쪼잡쪼잡 이거저거 맛보기는 하고있었는데 그 중 하나인 이더리움 dapp 개발 과정을 써볼까 한다.

유튜브 강좌를 보며 따라하는 것이고.. 그저 따라할 뿐...! 아직 어렵다

 

코딩하는 나의 모습

 

내가 보며 따라하는 강좌는 요거다.

https://youtu.be/Ud3_OrxNPDg

 

 


0. What we gonna do?

스마트컨트랙트를 기반으로하는 디앱을 만들어보는 프로젝트.

디앱이란?

대충 블록체인을 활용한 애플리케이션.

Decentralized App

 

 

 


1. Lottery Dapp preview

로또게임(?)을 만들건데 스마트컨트랙을 활용하여 만들 것이다.

 

이 프로젝트에서 우리는

  • 솔리디티를 사용한 스마트컨트랙 만들기
  • 배포스크립트 만들기
  • 테스트코드 만들기
  • 프론트에 연동하기

를 하게된다.

 

 

스마트컨트랙을 작성하여 블록체인에 올린다는 것은,

자바로 백엔드 코드를 작성하여 EC2에 올린다는 것과 같다.

 

블록체인도 결국 분산된 무수히 많은 컴퓨터들이니 블록이 곧 서버역할을 하는 셈이다. 스마트컨트랙은 코드역할이고.

따라서 기존 애플리케이션의 흔한 구조인

[프론트엔드]-[백엔드]가

[프론트엔드]-[블록체인]이 되는 것이다.

 

 

단, 경우에 따라서 디앱이라도 [프론트엔드]-[백엔드]-[블록체인]처럼 백엔드를 추가하는 구조도 많은데 아무래도 블록체인상에서 코드를 실행시키기 위해서는 가스비라는 비용이 발생하기에 이런 비용적인 측면을 개선하고자 백엔드단을 추가하기도 한다고 한다.

(블록체인을 구성하는 노드(컴퓨터)들을 제공하는 사람들은 땅파서 장사하는게 아니기에.. 이들에게 가스비라는 대가를 지불하고 우리의 코드를 실행시켜달라고 하는 것)

 

 

 

 

아무튼, 서론이 길었다.

 

우리가 만들 로터리 디앱은 어떤 프로젝트냐면,

https://youtu.be/div91ADl_7k

시연영상

 

 

블록해시 맞추기 게임이다.

 

내가 만든 트랜잭션이 들어가게 되는 블록보다 3개 뒤 블록의 블록해쉬를 때려맞추는 게임(재미는 없을듯)

 

 

예를들자면

  1. 내가 0xab라고 베팅을 한다.
  2. 이 베팅은 하나의 트랜잭션으로서 블록에 포함된다.
  3. 만약 이 트랜잭션이 3번 블록에 포함됐다고 하자.
  4. 3번 블록의 3개 뒷 블록인 6번 블록의 블록해쉬값이 0xab라면 내가 이긴 것이다.
  5. 즉 6번 블록이 생성완료되고 7번블록의 생성이 시작된 시점부터 게임결과를 알 수 있다.

 

pot머니라고 부르는 베팅금액을 가져가는 규칙은 이러하다.(전부 0.005ETH씩 베팅한다)

  1. 6번 블록이 완성되었을때 유저들이 베팅한 돈을 팟머니에 쌓는다.
  2. 맞춘사람이 여러명일 경우 첫번째로 맞춘 사람이 가져간다.
  3. 두글자중(ab중에서) 하나만 맞추었다면 돈을 돌려준다.
  4. 결과값을 검증할 수 없는 경우가 발생하는 경우 돈을 돌려준다.

 

 

동작으로만 보면 그닥 복잡하진 않아보인다.

이 프로젝트의 핵심은 스마트컨트랙을 작성하고 이를 배포하여 체인과 상호작용하는 것에 있다.

 

 

 

 


2. 개발 환경

  • NodeJS : 배포와 테스트 코드를 작성하기 위해
  • VSCode : ide 이거씀
  • Truffle : 솔리디티를 컴파일하고 스마트컨트랙을 테스트, 배포할 수 있는 블록체인 개발 프레임워크이다. Truffle 설치시 solc-js가 설치된다(JS기반의 솔리디티 컴파일러)
  • ganache-cli : 간이 블록체인. 근데 이제 내 PC 메모리로 실행되는. 블록체인을 쉽게 mock을 해놓은 툴(테스트 용도), 즉 테스트와 개발에 사용하는 이더리움 RPC 클라이언트.(테스트용 노드(서버)의 느낌으로 이해하면 되려나..?)

 

ganache-cli(편의상 가나슈라고 하겠다)를 실행하면 로컬에서 블록체인 환경이 실행되고 여기서 사용할 수 있는 계정 10개가 제공된다. 

 

이 간이 블록체인을 켜기 위해서는 콘솔창에서

ganache-cli -d -m tutorial

를 실행해준다

 

-d 옵션을 주면 생성되는 니모니깅 동일하고 주소와 키값이 동일하다

-m 옵션은 지정된 HD 지갑 니모닉 값으로 초기 주소를 생성하기 위해 사용한다.

우리는 니모닉으로 tutorial을 사용했다.

보통 니모닉은 12개 단어를 사용하지만 1개만 써도 된다(?)

 

즉 -d, -m 옵션을 사용하고 니모닉 단어(tutorial)를 사용하면 항상 같은 지갑주소가 생성된다.

블록체인에 대해 전반적인 그림을 그리기 위해 조사하며 얻은 얕은 지식입니다.


0. 코인말고 블록체인

암호화폐에 대한 글은 아니고 카카오의 블록체인 프로젝트 클레이튼으로써 클레이튼 네트워크 전반에 대해 얕게 조사해 본것을 정리하고자 한다.

이번 포스팅은 클레이튼 공식 문서에 있는 소개 동영상을 보고 정리한 내용이다.

https://ko.docs.klaytn.com/bapp/tutorials/bapp-on-baobab-video-lecture/1.-introduction

 

1. 소개 - Klaytn Docs KO

Baobab에서 BApp 개발하기(동영상 강의)

ko.docs.klaytn.com

 

 

 

 


1. 다른 블록체인 플랫폼들의 약점

  • Scalability(확장성)
  • Finality(확정성)
  • Fork(분기발생)

 

 

 

1. Scalability(확장성)

"얼마나 많은 일을 신속하게 처리할 수 있는지"

 

를 의미한다.

이때 TPS와 Block Interval의 개념이 나온다.

TPS란 Transaction Per Second로, 초당 몇개의 트랜잭션(거래)인지를 의미하고.

Block Interval은 블록 생성 주기를 의미한다.

 

  • 비트코인은 보통 7 TPS
  • 이더리움은 보통 15~20 TPS

반면,

  • VISA카드는 1700 TPS를 가진다.

 

또 Block Interval을 보면

  • 비트코인은 10분
  • 이더리움은 15~20초다.

 

다시말해

이더리움이 20 TPS에 15초의 인터벌을 가진다면 20 * 15 = 300 transactions라는 것을 알 수 있다.

이더리움으로 우리가 송금을 한다면, 이더리움 블록이 생성이 되어야 거래가 성사되기에 15초의 대기시간이 필요하다. 물론 비트코인의 10분에 비해서 이더리움의 15초는 많이 개선된 것이긴 하지만 여전히 너무 느리다.

 

왜 이렇게 느리지?

기존 평범한 중앙 서버 방식에서는 큰 request가 들어올 경우 많은 서버들이 request를 나누어 병렬적으로 처리를 하기에 서버의 개수를 증가시키면 처리 속도를 늘릴 수 있었다.

하지만 블록체인 네트워크에서는 노드의 수가 아무리 많다해도 일을 분산해서 처리하는 것이 아닌 모든 노드가 모든 일을 한다. 즉, 전체 네트워크에서 가장 낮은 퍼포먼스의 노드를 기준으로 전체 네트워크의 속도가 낮아지는 하향평준화가 발생한다.

 

하지만,

킹레이튼은 3000 TPS와 Block Interval 1초를 가진다.

 

 

 

2. Finality(확정성)

FInal이란 트랜잭션이 블록에 기록되고 그 블록을 더 이상 수정할 수 없는 상태를 의미한다.

Finality는 블록이 더 이상 변경될 수 없는 상태까지 소요되는 시간을 의미한다고 할 수 있다.

 

이전 포스팅에서 51%공격과 컨펌의 개념에 대해 살짝 다뤘는데 그 내용인 듯 하다.

  • 비트코인은 블록생성(채굴)까지 10분이 걸리고, 60분의 Finality 시간이 걸린다.(10분씩 6번의 검증)
  • 이더리움은 블록생성(채굴)까지 15초갸 걸리고, 6분의 Finality 시간이 걸린다.(15초씩 25번의 검증)

 

즉, 내가 만약 비트코인으로 송금을 했고, 10분이 지나서 나의 거래기록이 저장된 블록이 생성되어 체인에 붙었다고 해도,

그 거래를 확정하려면 그 뒤로 5개의 블록이 더 붙어야 한다는 것이다. 그 정도로 많은 블록이 추가로 붙은 체인이어야만 메인 체인으로 인정을 해 줄수 있기 때문이다.

거꾸로 말하면 비트코인은 60분동안은 내 거래내역이 무효화 될 수 있다는 뜻.

 

하지만,

갓레이튼은 Finality까지 1초면 충분하다.

 

 

 

3. fork(분기발생)

비트코인과 이더리움은 PoW 알고리즘으로 블록 생성 노드를 결정한다.

매우 복잡한 연산을 노드들끼리 경쟁적으로 하며 먼저 문제를 푼 노드가 블록을 생성하고, 주위 노드들로 자신이 문제를 풀었다고 전파를하는 원리인데,

 

만약 두개의 노드가 기가막힌 타이밍으로 동시에 문제를 푼다면?

그러면 블록체인에 분기가 발생한다.

 

하나의 예시 상황을 보자

  1. 내가 비트코인을 친구에게 전송했다.
  2. 내가 전송한 거래 기록은 트랜잭션 풀에 저장된다.
  3. 채굴 노드들은 트랜잭션 풀에서 거래 기록을 모으고 문제를 풀며 블록을 생성하기 위해 애쓴다.
  4. 이때 기막힌 타이밍에 A노드와 B노드가 동시에 문제를 풀어냈다.
  5. 따라서 A노드와 B노드는 동시에 자신이 문제를 풀었다는 사실을 주위 노드들에게 전파한다.
  6. 주위 노드들은 A노드에게 전파받은 노드는 A노드가 생성한 블록을 체인에 추가하고 다시 문제를 푼다.(B노드의 경우도 마찬가지) 이때 A노드와 B노드가 동시에 생성한 블록의 내용은 동일하다. 동일한 트랜잭션을 모았으니까.
  7. 그러면 현재 A노드가 생성한 #6-1블록이 체인 마지막에 붙은 줄 알고있는 노드가 있을 것이고, B노드가 생성한 #7블록이 체인 마지막에 붙은 줄 알고있는 노드가 있을 것이다.
  8. 이 상태로 노드들은 다시 열심히 채굴을 하고 이번에는 어떤 C노드가 문제를 풀어내어 블록 생성 권한을 가졌다고 해보자.
  9.  C노드는 B노드가 생성했던 #7블록을 마지막으로 하는 체인을 알고있는 노드라면 #7블록 뒤에 자신이 생성한 #8 블록을 붙인다. 그리고 이 사실은 모든 노드들에게 전파된다.
  10. #6-1 블록을 갖고있던 노드들은 #7블록이 없기에 자신들의 체인을 포기하고 #6 - #7 - #8 체인의 형태로 다시 채굴을 시작한다.

 

이런 흐름으로 PoW가 작동하는데 여기서 51%공격이 발생할 수 있다.

 

황레이튼은 이런 위험이 있는 PoW 방식 대신 IBFT 알고리즘을 사용하여 문제를 해결했다.

 

https://steemit.com/kr/@kanghamin/istanbul-byzantine-fault-tolerance

 

Istanbul Byzantine Fault Tolerance/이스탄불 비잔티움 장애 허용 — Steemit

Istanbul Byzantine Fault Tolerance(=IBFT)에서는 3단계로 합의과정이 이루어져있다. Pre-Prepare Prepare Commit 시스템은 잘못된 노드(나쁜 노드)가 F라고 가정했을때 총 노드수가 3F+1이상이면 돌아갈 수 있다. N =

steemit.com

 

 

 

 


2. 클레이튼의 합의 과정

참여 노드 수를 제한하여 성능을 높힌 BFT 알고리즘은 덜 분산적이고 투명성이 저하된다는 단점이 있다.

이 단점을 개선한 방식이 IBFT다. 이거에 대해선 따로 다시 공부를 해야한다...

 

IBFT의 경우 1명의 제안자(Proposal)다수의 위원회(Commit/Validator)로 구성된다.

제안자는 거버넌스 카운실(Governance Council) 노드들 중 랜덤으로 선정된 하나의 노드이며 이번 라운드는 자신이 선정다는 사실을 자신의 공개키를 통해 암호화하여 위원회 노드들에게 알린(전파한)다. (클레이튼의 블록 생성 주기를 라운드라고 한다.)

위원회 노드들의 경우도 자신이 합의 노드라는 것을 합의 노드들에게 공개키를 통해 암호화하여 알린다.

제안자는 합의 노드의 2/3의 서명을 받을 경우 블록을 생성하고 다른 위원회 노드들에게 전파한다.

 

 

 

 


3. 클레이튼 네트워크의 구조

CNN : consensus node network = 합의 노드 / 제한 노드

PNN : proxy node network = 블록을 앤드포인트 노드에게 전달하는 노드

ENN : Endpoint node network = 기타 노드 / 누구나 참여가능 노드

CN/PN/ENBootnode : 새로운 참가자의 노드를 등록하게 도와주는 노드

CNN + PNN : Core cell

출처: https://jeongbincom.tistory.com/88 [하나셋 - 프로그래머로써 살아남기]

CN노드들간의 합의 끝에 블록이 생성되고 CNN에서 PNN으로, PNN에서 EN들에게 전파된다.

 

 

왜 CN -> EN의 다이렉트 통신을 안하고 CN -> PN -> EN처럼 중간에 PN을 둘까?

위에 언급하였듯 블록체인 네트워크에서 커다란 request가 들어온다면 이 request를 여러 노드들이 분산하여 처리하는 것이 아닌 각각의 노드들이 모든 request를 처리해야한다. 따라서 네트워크의 성능은 그 네트워크에서 가장 낮은 성능의 노드에 맞춰진다.

 

즉, CN 노드들의 성능이 매우 중요한데, CN 노드들은 합의하는 것에만 최선을 다해도 모자란 판인데 EN들과 통신하는 것에 자원을 낭비해선 안된다. 따라서 CN 하나에 여러개의 EN을 연결하는 구조 대신, CN 하나와 여러개의 EN 사이에 PN을 두어 EN과 통신하는 측면에서 성능을 높힌것이다.

 

참고로 CN 노드가 되려면 

  • Physical core가 40개 이상
  • 256GB RAM
  • 14TB 이상 저장공간
  • 10G 네트워크

의 조건이 필요하다고 한다.

 

 

 

 


4. 서비스 체인

메인넷과 연결돼있고, 독립적으로 운영되는 체인이다.

  • Bapp이 특별한 노드 환경에서 수행되어야 할 때
  • 프라이빗 블록체인과 같이 보안 수준 맞춤형으로 설정해야 할 때
  • 많은 처리량을 요구하는 서비스라서 메인넷에서 사용하기엔 비용 부담이 될 때

서비스 체인을 사용한다.

 

메인체인과 서비스체인간 통신은 되지만 제한된 조건 하에서 통신한다.

요약하면 서비스 체인은 독립된 서비스 공간을 구축해서 필요할때 메인넷의 신뢰를 고정 시키는 것

참고로 클레이튼의 서비스 체인에서는 트랜잭션 가스비를 안받도록 설정할 수 있다.

 

 

 

 


5. 이더리움 VS 클레이튼

이더리움

  • 단일 네트워크
  • PoW방식이고, 어떤 노드가 블록을 생성하게 될지 모름
  • 따라서 최신 블록을 전파받기 위해서 노드는 다른 모든 노드들고 최대한 연결돼 있어야한다.

 

클레이튼

  • 2개의 레이어를 가지는 네트워크
  • 매 라운드마다 합의 노드들 중  하나가 뽑혀서 블록을 생성한다.
  • 이더리움과 달리 합의 노드들 중에서 블록이 생성되기에 어떤 노드에서 생성될지 거의 알 수 있다.
  • 따라서 최신 블록을 전파받기 위해서는 합의 노드들에게만 연결해 있으면 된다.
  • 개발자가 Bapp을 만들고 엔드포인트 노드에 접속한다. EN -> PN -> CN
  • 혹은 개발자의 Bapp 자체를 엔드포인트로 활용하여 네트워크에 접근할 수도 있다.
  • 메인넷과 부분적으로 소통하며 독립된 서비스 공간을 구축할 수 있는 서비스 체인이 있다.

 

 

 

 

 

참고:

더보기

https://media.fastcampus.co.kr/insight/why-blockchain-is-hard/

블록체인에 대해 전반적인 그림을 그리기 위해 조사하며 얻은 얕은 지식입니다.


1. 채굴이란?

채굴은 새로운 블록을 생성하는 것을 의미한다.

블록은 채굴 노드가 생성한다.

저번 포스팅에서 말했 듯, 트랜잭션들은 검증노드로부터 네트워크 여러곳으로 전파된다.

채굴노드는 네트워크에 공유되고 있는 트랜잭션들을 모아서 블록 만들기를 시도한다.

 

 

비트코인은 블록 한개당 1MB의 크기이다. 물론 모든 코인이 동일하지는 않고 어떤 블록체인을 사용하느냐에 따라 다르다.

 

 

비트코인은 블록 한개가 생성되는데 10분이 걸린다. 즉, 나의 거래내역이 블록에 포함되어 체인에 붙기까지 10분이 걸린다는 것이다. 또 컨펌의 과정을 위해서 추가로 6개의 블록이 이어져야한다.(비트코인의 경우)

컨펌이란 나의 트랜잭션이 포함된 블록이 블록체인의 메인 체인에 들어있다고 확정하는 것이다.

 

 

 

 


2. 어떤 채굴노드가 블록을 생성하는가?

채굴 노드들은 블록을 생성하기 위한 경쟁을 서로 한다.

모든 노드들이 블록을 생성하면 체인은 너무 많은 분기(갈래)가 발생할 것이다.

이 경쟁은 수학문제를 푸는 것이며, 정확히는 특정 해쉬값이 나오게 하는 임의의 논스(nonce)값을 먼저 찾는 경쟁이다.

이 경쟁에서 승리하면 블록을 생성할 수 있고 이 노드에게는 보상이 주어진다.

논스값을 찾는 것은 CPU보다는 GPU를 사용하는 것이 훨씬 빠르기에 그래픽카드를 사용한 채굴이 많은 것이다.

아무튼 이런 고생을 PoW 알고리즘이라고 하며 모든 블록체인이 이 방법을 사용하는 것은 아니다.

여러가지 채굴 알고리즘이 존재하는데, 다음 포스팅에서 공부해보겠다.

 

 

 

 


3. 동시에 블록이 만들어진다면?

경쟁을 하였음에도 동시에 블록을 생성하여 분기가 발생한다면?

 

6번 블록 이후 두개의 갈래로 나눠졌다.

이때 6-1블록과 7블록 중 어떤 블록쪽으로 계속 이어나가야 할까? 

이때 위에 언급한 확정(컨펌)의 개념이 나온다.

 

PoW알고리즘은 

 

"네트워크에 더 많은 기여를 한 사용자는 신뢰할 수 있는 사용자다"

 

라는 전제를 하고있다.

따라서 최초로 분기가 발생하고 그 뒤로 더 많은 블록들이 붙은 쪽이 더 많은 기여를 받은 분기이고 이 쪽을 메인 체인으로 인정한다. 블록들을 더 붙혀보고 많이 붙은 분기를 선택하는 이 과정이 위에서 언급한 컨펌(확정)의 과정이다.

인정받지 못한 분기의 블록들은 고아블록(스테일블록)이 된다.

 

 

 

 


4. 51%공격

블록을 수정하거나 조작하는 것은 불가능할까?

채굴하는 과정에서 GPU는 많은 전력을 소모한다. 논스값을 찾는 경쟁을 하기 때문인데,

왜 채굴하는데 이렇게 많은 전력을 쓰도록 설계한 것일까?

그냥 다음 블록을 생성할 노드를 랜덤으로 정하면 안되는 것일까?

 

이유는 블록체인 네트워크를 해킹으로부터 보호하기 위함이다.

블록 1개를 만드는데 많은 고생(채굴)을 했으니 이것을 수정하기 위해서는 그 이상의 고생(컴퓨팅 파워)를 하도록 만든 것이다. 또 블록 하나를 조작하면 그 블록의 해시값이 바뀌고 이로인해 연결된 블록들의 해시값도 바뀌기 때문에 사실상 블록체인 네트워크 전체 노드들의 고생보다 더 큰 고생이 필요하다.

 

하지만 그렇다해도 방법은 존재한다.

51% 공격이라고 불리는 수단인데, 과정은 다음과 같다.

 

 

 

1. A가 B에게 30코인을 줬다는 거래 내역이 101번 블록에 기록됐다.

 

 

2. A는 전체 네트워크의 51%이상의 컴퓨팅 파워를 지니고 있다고 가정한다.

3. A는 자기의 거래내역을 없애버린 새로운 블록을 만들고 그 뒤로 컨펌을 위한 블록들을 더 빠르게 생성한다.(자신이 가진 51% 이상의 압도적인 컴퓨팅 파워를 사용해서)

 

 

4. 이렇게 되면 A가 조작한 블록이 속한 분기가 메인 체인으로 인정된다. 

고로 A가 B에게 코인을 보낸 사실은 사라진다.

 

 

 

 


5. 51% 공격 대응

사실 이 공격은 공격자가 손해를 보는 모순을 가지고있다.

 

첫째로,

공격자가 이득을 취하기 위해서는 해당 암호화폐의 가치가 올라야한다.

하지만 이런 공격으로인해 해당 암호화폐에 대한 신뢰가 떨어지게 되고, 가치도 떨어진다.

그렇다면 51% 소유자가 가장 큰 손해를 보는 상황이 돼 버린다.

실제로 2014년 특정 마이닝풀이 일시적으로 코인의 해시파워가 51%를 초과하는 일이 발생했을 때, 가격이 폭락했다. 즉, 이론적으로 가능하나 경제적인 이유로 불가능한 공격이라는 것이다.

 

둘째로,

블록체인 네트워크의 참여자가 많을수록 51%의 해시파워를 확보하는 것은 매우 높은 비용이 필요하다.

따라서 해킹을 통해 얻는 수익보다 적자가 난다는 것이다.

하지만 참여자가 적은 네트워크는 51%의 파워를 확보하고 유지할 수도 있기 때문에 이 부분에서는 대안이 필요하다.

이것도 다음 포스팅에서 공부해보겠다.

 

 

 

 

 

참고:

더보기

https://media.fastcampus.co.kr/insight/why-blockchain-is-hard/

블록체인에 대해 전반적인 그림을 그리기 위해 조사하며 얻은 얕은 지식입니다.


1. 왜 검증이 필요한가?

블록체인에서 블록은 곧 데이터베이스다.

근데 이 데이터베이스는 모든 사람이 접근하여 작성할 수 있다.

이 데이터베이스를 거래장부라고 할 수 있다.

거래장부에 모든 사람들이 접근하여 거래를 기록할 수 있다면 어떻게 될까?

 

만약

"A가 B에게 100만원을 줬다."

라는 진실된 거래가 있다.

하지만 B가 돈을 갚기 싫어서 다음과 같은 가짜 거래 내역을 썼다.

"B가 A에게 100만원을 줬다"

그러면 실제로 B가 돈을 갚지 않았지만 A와 B사이에는 더 이상 빚진 돈이 없게된다.

 

이런 일을 방지하기 위해 거래내역을 위조할 수 없도록 검증이 필요하다.

 

 

 

 


2. 검증 방법

현실세계에서는 자필 서명이나 도장을 찍는다.

사람이라면 타인의 자필 서명을 완벽하게 흉내낼 수 없다는 전제,

도장은 자신이 소중하게 관리를 한다는 전제,

가 있기 때문이고 이는 잘 작동된다.

 

하지만 모든것이 ctrl+c / ctrl+v로 복제가 되는 인터넷에서는 어떻게 할까?

 

 

 

1. 트랜잭션이란?

데이터베이스에서 상호작용 및 수행의 논리적 단위를 뜻하는 단어이다.

블록이 곧 데이터베이스이니 이렇게 표현한다.

 

 

 

2. 비대칭 암호화 방식

비트코인을 포함한 많은 암호화폐들이 이 방식을 사용한다.

혹은 공개키 알고리즘이라고도 부른다.

 

클라이언트에서 거래를 하면 거래내역이 생성된다.

클라이언트는 이 거래내역을 노드에게 전송하여 검증을 맡긴다.

노드가 이제 검증을 수행하게되는데,

이를 위해서는 거래내역에 노드에게 전송될 때 "전자서명"이 포함되어야 한다.

비대칭 암호화 방식을 통해 전자서명을 생성한다.

우선 다음의 배경지식이 필요하다.

  • 모든 클라이언트들은 자신의 [공개키]와 [개인키]가 있다.
  • [공개키]는 모두에게 노출되어도 괜찮은 키이다.
  • [개인키]는 오직 자신만 알고있어야 하는 키이다.
  • [개인키]로 암호화한 데이터(거래내역)은 [공개키]로만 해독할 수 있다.

[개인키]를 [비밀키], [비공개키]라고도 하는데 나는 그냥 [개인키]라고 하겠다.

 

[개인키], [비밀키], [주소]는 다음과 같은 관계를 가진다.

https://www.google.co.kr/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0ahUKEwi567Lu-ojVAhXDHJQKHZWcC-cQFggmMAA&amp;amp;url=https%3A%2F%2Fdocs.google.com%2Fa%2Fieee.org%2Fuc%3Fid%3D0Byw4AEomZK2edlQwel95S1J0VTg%26export%3Ddownload&amp;amp;usg=AFQjCNHfjSAx7d59S3UDVHjxBQcl3OmkWw

[개인키]를 타원곡선 곱셈함수로 돌리면 [공개키]가 나오고,

[공개키]를 해시함수로 돌리면 [주소]가 나온다.

이 흐름은 그림에서처럼 일방향으로만 진행할 수 있다.

[개인키]로 [공개키]를 알 수는 있지만,

[공개키]로 [개인키]를 알아낼 수는 없다는 것이다.

 

 

 

3. 검증 과정

다른 블로그의 글에는 막 그림도 있고 그러던데, 우리는 그냥 눈을 감고 생각해 보자. 오히려 이해가 잘 될지도?

 

  1. 클라이언트 A는 자신의 거래 내역이 있다.
  2. A는 자신의 거래 내역을 자신의 [개인키]로 암호화한다.
  3. 그 후 A는 노드에게 [개인키로 암호화한 거래내역] + [원본 거래내역] + [A의 공개키]를 세트로 보낸다.
  4. 노드는 저거 3종 세트를 받아서 검증을 수행한다.
  5. 우선, [A의 공개키]로 [개인키로 암호화한 거래내역]을 해독하고 그걸 [원본 거래내역]과 비교한다.
  6. 비교 결과 동일하면 이 거래내역은 A가 생성한 올바른 거래임을 인정한다.
  7. 이후 검증된 거래내역은 해당 노드 근처의 다른 노드들로 전파된다.

5번 과정이 핵심이다.

 

참고로 거래내역을 바로 [개인키]로 암호화하는 것이 아니라

[개인키]를 해시함수로 돌려서 해시값을 뽑아내고 그 해시값을 [개인키로] 암호화하는 것이다.

이렇게 하면 거래내역이 아무리 길어도 고정된 길이의 해시값이 나오기에 송수신시 유리하다.

 

 

 

 


3. 검증자가 조작하면?

A와 검증노드가 합심해서 조작하면 어떻게 될까?

A가 가짜 거래내역을 노드에게 검증신청을 하고,

이 노드가 가짜 거래내역임에도 불구하고 검증완료 처리를 한다면?

 

이를 막기위해 신뢰할 수 있는 노드(검증자)만 검증을 진행할 수 있도록 제한한다.

신뢰할 수 있는 노드를 가리기 위해

 

  1. 검증에 참여하기 위해서는 비용이 발생하도록 만든다.
  2. 검증이 완료되면 네트워크에서 보상을 지급한다.

이런 안전장치를 마련해 두었다.

일종의 입장료를 내야만 검증에 참여할 수 있기에 나쁜 의도를 가진 검증 참여자를 걸러낼 수 있다.

또 보상으로 암호화폐를 받기에 이 화폐의 가치가 올라가기 위해서는 정직한 검증이 이어져야 한다. 

즉, 검증을 정직하게 해야만 하는 이유가 생기는 것이다.

 

 

 

 


4. 헷갈렸던 부분

공개키와 개인키 중에 어떤 것으로 암호화를 하고 복호화를 하는지 헷갈렸다.

내가 지금까지 알아온 방식은

 

  1. A와 B가 있고, A -> B로 데이터를 보낸다면
  2. A는 [B의 공개키]로 보낼 데이터를 암호화해서 보내면
  3. B는 자신만 가지고있는 [B의 개인키]로 복호화해서 보는 것

(이 비유에서 A는 트랜잭션의 생성자가 되겠고, B는 검증노드가 되겠다.)

 

 

 

이런 흐름이었는데 블록체인의 전자서명도 같겠거니 했지만,

[개인키]로 암호화해서 [공개키]로 복호화한다는 점이 반대였다.

누구나 가질 수 있는 [공개키]로 복호화하게 되면 데이터를 누구나 들여다 볼 수 있지 않은가?

라는 생각에 빠져 혼란이 왔었는데,

 

 

생각해보니 데이터를 비밀스럽게 보내기 위한 비대칭키 암호화 방식이 아니라,

데이터를 생성(전송)한 사람의 본인확인을 위한 절차였기에 개인키, 공개키를 반대로 쓰는 것 이었다.

 

 

굳이 검증노드가 생성된 트랜잭션을 비밀스럽게 확인 할 필요는 없고,

오히려 모든 검증노드가 이런 트랜잭션을 까봐서 올바른 트랜잭션인지 확인하기 위해서는 공개키로 복호화를 해야만 하는 것이었다.

 

A의 공개키로 복호화가 된다면?

그 암호는 A의 비밀키로 암호화 했다는 의미 

왜?

비밀키 -[해싱]-> 공개키 -[해싱]-> 지갑주소

이기에 공개키로 해독이 되는 암호는 그 공개키에 해당하는 비밀키로 암호화음이 분명하다.

 

 

[개인키] <-> [공개키] 양쪽으로 암/복호화가 된다는 성질을 이렇게도 활용하는구나 싶어서 소소한 깨달음이었다.

뭔가 적어놓고 보니 당연한 사실이긴한데,

처음 전자서명 암호화를 접할 당시에는 헷갈렸다ㅠㅠ

 

 

 

 


아무튼,

장황하게 썼지만 생각보다 간단하다.

이렇게 많은 노드들로 전파된 거래내역을 채굴노드가 모아서 블록을 생성한다.

이 과정은 다음 글에서 알아보겠다.

 

 

 

 

 

참고:

더보기

 

 

https://media.fastcampus.co.kr/insight/why-blockchain-is-hard/

블록체인에 대해 전반적인 그림을 그리기 위해 조사하며 얻은 얕은 지식입니다.


 

1. 어디에 저장?

노드에 저장된다

블록체인을 설명할때 주로 블록은 데이터베이스, 체인은 체인 이라는 표현을 한다. 

블록에 정보를 저장하고 체인형태로 쭉 이은 구조이기 때문인데,

이러한 탈중앙화 구조로 인해 해킹에 안전하다고 한다.

 

그런데 문뜩 궁금해졌다. 거래내역과 같은 정보들은 블록에 저장된다고 하는데,

그럼 이 블록은 실제로 어디에 존재하는 것일까?

무엇이 됐든 물리적인 저장 공간은 있어야 기록이 계속 유지되지 않는가?

어딘가의 서버에 존재하면 그것은 중앙화된 구조기에 말이 안되지 않는가?

 

 

 

 


2. 블록체인 노드

블록들은 노드에 저장된다.

노드라는 단어를 많이 들었지만 정확히는 잘 몰랐다. 

우선 암호화폐 시장은 3종류의 사람들로 구성된다.

  1. 채굴자 (컴퓨터로 암호를 풀고 블록을 생성할 권한을 얻음)
  2. 소비자 (생성된 코인을 가지고 거래를 함)
  3. 네트워크 참여자 (거래가 안전한지 검토하고 승인하는 관리자)

이때 네트워크 참여자들이 사용하는 기계를 노드라고 한다.

노드는 새로운 블록이 생성되면 그 블록이 안전한 거래인지 검토하고 승인하는 역할이다.

데이터를 다운로드할 수 있는 모든 종류의 전자기기는 노드가 될 수 있다.

즉, 모든 스마트폰이나 데스크탑 PC가 노드가 될 수 있다. 

 

노드가 되려면 블록체인 네트워크에 접속하면 된다.

블록체인 네트워크에 접속하려면 데이터(블록)를 다운받거나 지갑을 생성하는 등의 행위를 의미한다.

이런 노드는 전 세계에 무수히 많이 있기에 탈중앙화었다고 말할 수 있고, 이를 해킹하기 위해선 전세계의 스마트폰과 데스크탑을 해킹해야 한다는 말이 된다.

 

검증의 원리와 과정은 다음 포스팅으로 알아보도록 하자.

 

 

 

 


3. 노드의 종류

노드는 풀노드라이트노드로 구분할 수 있다.

더 많은 종류의 노드가 있긴하지만 일단 대표적인 종류부터 알아보자.

 

 

1. 풀노드

풀노드는 모든 기능을 다 가지고 있는 노드이다.

이때 모든 기능이란

  • 지갑
  • 채굴
  • 데이터베이스
  • 라우팅

을 의미한다.

풀노드는 최초의 블록부터 최신의 블록까지 모든 블록을 가지고있다.

따라서 독자적으로 어떤 거래에 대한 검증을 할 수 있다.

모든 블록을 저장하고 있어야하기에 저장공간이 많이 필요하다.

 

비트코인의 경우 최초블록(제네시스블록)부터 현재의 블록까지 모든 정보를 저장하기 위해서는 200GB 이상의 용량이 필요하다고 한다. 

 

이곳에서 소프트웨어를 다운로드받으면 풀노드가 될 수 있다.

https://bitcoin.org/ko/download

 

다운로드 - Bitcoin

Bitcoin.org is a community funded project, donations are appreciated and used to improve the website. Make a donation

bitcoin.org

 

2. 라이트노드

라이트노드는 블록체인의 모든 블록을 가지고있지는 않다.

따라서 풀노드보다 요구되는 저장용량이 적다.

헤더정보만 가지고있는 일종의 요약본이다.

라이트노드도 거래는 가능하다. 다만 거래에 대한 검증은 불가능하다.

검증을 하기위해 풀노드에 검증된 거래인지 머클트리를 통해 확인하는 요청이 필요하다.

이를 SPV(Simple Payment Verification)라고 한다.

 

 

 

 

참고:

더보기

 

https://media.fastcampus.co.kr/insight/why-blockchain-is-hard/

이 카테고리는 Ground X에서 진행한 한양대학교 일반대학원 블록체인 융합학과 강의와 그 외의 참고자료를 보고 정리하는 곳입니다. 강의 동영상은 여기서 볼 수 있습니다.

 

너무 빈약한 지식이기에 이 글을 신뢰하지는 마세요.. 혹시 지나가시다가 잘못된 점 발견하시면 피드백 부탁드립니다.


1. 블록체인이란?

  • 블록은 정보다.
  • 정보를 블록이라고 하는 단위로 저장하고 이 블록들을 이어붙혀서 체인 형태로 저장하는 기술.
  • 블록은 더하기만 가능하고 수정과 삭제가 힘들다.
  • 블록은 [내 블록의 해시값], [이전 블록의 해시값], [내 데이터]로 구성된다.
  • 조금더 자세히 말해보면, 블록체인은 데이터 분산 처리 기술이다.
  • 블록은 개인과 개인의 거래 장부의 역할을 하고, 이를 조작하려면 모든 사람의 장부를 조작해야한다.

 

출처 : 한국전자통신연구원

 

기존 거래 방식

은행이 모든 거래 내역을 가지고있다. A가 B에게 10만원을 송금한다고 하면 은행이 중간역할을 한다.

A가 B에게 10만원을 보냈다는 사실을 증명해줘야 하기 때문이다.

 

우리는 오직 은행만을 신뢰하게 된다. 증명해 줄 곳이 은행뿐이니까. 그렇기에 이 은행에 문제가 생기면 A는 돈을 보냈다는 사실을 증명할 수 없고 결국 돈을 잃는다.

 

 

 

블록체인 방식

블록체인도 거래 내역을 저장하고 증명한다. 단, 은행처럼 한 곳이 전담하는게 아닌 여러명이 나눠서 맡는다.

한 네트워크에 10명의 참여자가 있다면 A가 B에게 10만원을 보낸 내역을 10개의 블록으로 생성해 10명 모두에게 전송, 저장한다. 나중에 거래내역을 확인할 때는 블록으로 저장한 데이터들을 연결해 확인한다. 

 

보안이 탄탄한 한 명이 모든 장부를 관리하는 것이 아닌 모두가 장부를 관리한다. 그렇기에 장부를 조작하려면 한 개만 조작해선 될게 아니다.

 

 

 

 


2. 블록체인의 활용

비트코인의 구조 출처: http://www.smallake.kr/

화폐(Currencies)

  • 이체와 화폐의 기능을 수행하는 전자 화폐.
  • 규제, 감독, 법제화 등 관련된 공인성은 없음
  • 예) 비트코인, 라이트코인, 다크코인, 피어코인, 도기코인 등

자산 등록(Asset Registry)

  • 자산 등록을 블록체인에 기록 하고, 개인키로 자산의 소유권을 주장하는 장부 기능.
  • 블록의 크기가 화폐용 블록보다 상대적으로 크며, 네트워크 성능 저하와 고비용 수반함.
  • 예) 컬러드코인, 옴니, 카운터파티 등

응용 플랫폼(Application Platform)

  • 네트웍상에 존재하는 블록체인에 응용프로그램을 개발하고 작동시키는 플랫폼 역할
  • 아직까지 서비스 초기이기 때문에 취약점이 다수 존재
  • 예) 이더리움, 에리스, NXT 등

자산 중심(Assent Centric)

  • 화폐, 자원. 주식, 채권의 거래를 일부 사용자만 볼 수 있는 공유장부에 기술함. (비트코인은 공개된 장부)
  • 외환 거래, 송금, 결제, 이체를 목적으로 두고 있음.
  • 예)리플, 스텔라

 

 

 

 


3. 해시함수

해시는 전에도 정리했던 적이 있다.

https://llshl.tistory.com/17?category=942551 

 

[Java] 해시/해시테이블이란?

사실 자료구조 카테고리에 맞는 게시글이지만 아직 자료구조 카테고리가 없고 앞으로 딱히 만들 계획이 없기에, 그리고 구현을 자바로 했기에 자바 카테고리에 넣었다! 그냥 그런걸로 하자 ㅎ

llshl.tistory.com

 

  • 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수,
  • 한 개의 인풋은 한 개의 아웃풋만을 가진다.
  • 조금만 인풋이 달라도 아웃풋은 크게 바뀐다.
  • 블록체인에는 Keccak256을 많이 쓴다 카더라(아직 잘 모름)
  • [이전 블록의 해시값]을 통해서 이전 블록을 포인팅하기에 블록의 순서를 알 수 있다.

 

 

 

 


4. 블록 생성 과정

블록 생성 시간 == 거래 소요 시간

  • 블록체인상에서의 장부 작성은 블록체인 네트워크에 참여하고 있는 사람들(이를 노드라고 한다)이 그 기록이 참인지 거짓인지 과반수의 동의를 얻어야 장부에 기록이 된다.
  • 이 노드들은 전 세계적으로 분산되어있고 전세계를 아우르는 하나의 거대한 장부를 형성한다. 따라서 신뢰가 필요가 없이 합의를 통해서 기록이 작성된다. 
  • 가장 많고 가장 빨리 작업을 한 사람이 블록에 기록하고 블록을 생성할 수 있는 투표권을 더 많이 갖는다고 할 수 있다. (작업증명)
  • 합의 알고리즘은 여러 방법이 있고 3개만 알아보자.

 

 

 


5. 합의 알고리즘

합의 알고리즘이란,

  • P2P 네트워크에서 정보의 지연과 미 도달을 통해 잘못된 정보 or 정보의 중복이 발생할 수 있다.
  • 이때 어떤 블록이 정당한지 검토하고 체인에 연결하기 위해 참가자들의 함의를 얻기 위한 알고리즘이다.

 

 

PoW

  • Proof Of Work, 비트코인, 비트코인 캐시, 라이트코인 등이 있다.
  • 누구나 참여 가능.
  • 풀기 어려운 문제를 빨리 해결한 사람에게 블록을 생성할 수 있는 권한을 주고 그 보상으로 코인을 제공하는 알고리즘
  • [앞 블록의 해시] + [Nonce] = [어떤 해시 값]을 만족하는 Nonce를 찾는 문제이다.
  • 난이도라는게 존재하는데 난이도가 4라면 어떤 해시 값은 4개의 0으로 시작하는 값이어야 한다.
  • 즉, Nonce를 빠르게 돌리면서 4개의 0으로 시작하는 해시값이 나오면 Nonce를 찾았다고 할 수 있다.
  • 연산량의 51퍼센트를 한 명의 참여자가 소유하면 블록을 조작할 수 있다. 
  • Nonce를 찾기 위해 전기를 너무 많이 써야한다.

 

 

PoS

  • Proof Of Stake, 대시, 네오 등이 있다.
  • 자신이 네트워크에 얼마만큼의 지분을 가지고 있는지로 판단. 즉 가지고있는 재산에 비례
  • 지분을 많이 가지고 있으면 높은 확률로 다음 블록을 제안할 수 있다.
  • 중앙 집중화를 예방하고 PoW보다 에너지를 절약한다.
  • 코인을 독식한 사람이 너무 강한 권력을 지니게 된다.
  • 그렇기에 PoW와 연계하여 사용한다고 한다.

 

 

BFT

  • PoW와 PoS의 단점인 *파이널리티의 불확실성을 해결한 것
  • 정해진 순번에 따라서 다음 블록을 누가 제안할지 정함
  • 네트워크가 동기화 되어있다. 즉 네트워크 참여자가 누구인지 다 알고있기에 새로운 참여자가 들어가면 작업을 멈추고 동기화를 진행해야한다.
  • 좀 느림

 

* 블록체인이 분기하게 되는 경우 긴 체인이 올바른 것으로 판단한다. 짧은 체인이 버려지는 경우 트랜잭션이 없었던 일이 될 수 있다.

 

 

 

 


6. Public vs Private

  • 누구든지 기록된 정보를 자유롭게 읽을 수 있는가?
  • 명시적인 등록 또는 자격 취득 없이도 블록체인 네트워크에 기록할 수 있는가?

라는 질문에 예라고 답하면 Public/공개형 블록체인이라고 한다.

반대로 정보가 공개돼 있지 않고 미리 자격을 얻은 사람만이 정보를 기록할 수 있다면 Private/비공개형 블록체인이라고 한다.

 

퍼블릭 블록체인은 누구나 접근 가능하고 익명이다.

프라이빗 블록체인은 정보를 비밀로 공유하고 아무나 못들어온다. 또 익명이 아니다.(기업 특화)

 

 

 

 

 

 

참고:

더보기

https://medium.com/@kimjunyong/5-%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%ED%95%A9%EC%9D%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-1%ED%8E%B8-pow-pos-dpos-21f8e3b2c22a

 

블록체인 합의 알고리즘 알아보기 1편(PoW, PoS, DPoS)

안녕하십니까 블록체인 알려주는 남자 Ryan KIM 입니다.

medium.com

https://medium.com/b-ock-chain/pow-%EC%99%80-pos-%EC%9D%98-%EC%A0%95%EC%9D%98-962a36d0979

 

PoW 와 PoS 의 정의

안녕하세요 이번에 PoW 와 PoS에 대한 포스팅을 맡게된 Seonmi입니다 :)  앞으로 잘부탁드릴게요!

medium.com

https://www.markany.com/kr/portfolio-posts/%EC%9D%80%EA%B7%BC-%EC%9E%98-%EB%AA%A8%EB%A5%B4%EB%8A%94-%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EA%B0%9C%EB%85%90/

 

다 아는 것 같은데 은근 잘 모르는 블록체인의 개념 - 마크애니

다 아는 것 같은데 은근 잘 모르는 블록체인의 개념 ‘블록체인’하면 어떤 게 떠오르세요? 많은 분들이 ‘코인’, 가상화폐를 제일먼저 떠올리실 것 같습니다. 재작년 소위 비트코인광풍으로

www.markany.com

https://wooaoe.tistory.com/19

 

[신기술]블록체인 이란? - 블록체인 개념 이해하기(퍼블릭,프라이빗,컨소시엄,하이브리드)

블록체인은 무엇일까요? 블록체인 이란? 블록체인은 데이터 분산 처리 기술이다. 즉, 네트워크에 참여하는 모든 사용자가 모든 거래 내역 등의 데이터를 분산, 저장하는 기술을 지칭하는 말이다

wooaoe.tistory.com

https://www.youtube.com/playlist?list=PLKqrwxupttYEcJhWAw0E_5RVpDD9LD6Q- 

 

Klaytn 클레이튼 스마트계약과 탈중앙앱 강의

이 수업은 한양대학교 일반대학원(석사과정) 블록체인 융합학과에서 한 학기동안 진행하게 된 블록체인 플랫폼 클레이튼을 활용한 스마트계약과 탈중앙앱 개발에 대한 수업입니다. 이 강의를

www.youtube.com

 

 

+ Recent posts