// 에드센스

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&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwi567Lu-ojVAhXDHJQKHZWcC-cQFggmMAA&url=https%3A%2F%2Fdocs.google.com%2Fa%2Fieee.org%2Fuc%3Fid%3D0Byw4AEomZK2edlQwel95S1J0VTg%26export%3Ddownload&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)라고 한다.

 

 

 

 

참고:

더보기

 

노드자스를 통해 개발하면서 무지성 install들을 해온것 같다. 그래서 정리해보는 시간.


1. npm options

기본적으로 npm install은 ./node_modules 폴더에 패키지를 다운받는 명령어이다.

나는 주로 npm 쓸때 접미사로 -D, -S, -g 옵션을 썼다. 왜냐? 블로그에서 이렇게 하라고 해서..

무슨 차이인지 모르고 써왔고 이거 때문에 문제 생긴적은 없었지만 찾아보니 나름의 의미가 있더라.

 

package.json을 보면 dependencies와 devDependencies가 있는데 얘네 중 어느쪽에 속하게 하도록 구분짓는 용도였다.

  • dependencies: 프로덕션 환경에서 응용 프로그램에 필요한 패키지.
  • devDependencies: 로컬 개발 및 테스트에만 필요한 패키지.

어떤 라이브러리가 빌드타임에 필요하면 devDependencies에 넣고, 런타임에도 필요하면 dependencies에도 넣어준다.

즉, 배포용 패키지와 개발용 패키지의 차이

 

--save는 package.json에 의존성 항목에 추가하도록 해주는 옵션인데 npm5부터는 굳이 --save 쓰지 않아도 된다고 한다.

 

 

 

-P/--save-dev (default)

암튼 그래서 

npm install [패키지명] -P
npm install [패키지명] --save-prod

이렇게 옵션을 주면 패키지를 설치하고 dependencies 목록에 추가한다.

사실 디폴트 옵션이라 아무 옵션도 안써주는 경우가 이 경우였다.

npm install [패키지명]

 

-D/--save-dev

그렇다면 얘는 devDependencies에 속하도록 하는 옵션이다.

npm install [패키지명] -D
npm install [패키지명] --save-dev

 

 

-g/--global

전역모드로 설치하면 시스템 폴더에 패키지를 설치하게 된다. -g를 통해서 설치하면 package.json의 의존성 목록에 기록되지 않는다.

-P나 -D는 지역설치옵션으로 루트 디렉토리의 node_modules에 설치된다. 이렇게 설치된 패키지는 해당 프로젝트 내에서만 사용 가능하다.

-g를 통한 전역설치를 하면 모든 프로젝트에서 사용 가능하다.

npm install [패키지명] -g
npm install [패키지명] -global

 

 

 

이 내용들을 어떤 분이 친절하게 정리해 두셨다.

npm install
// package.json의 dependencies에 있는 모든 패키지를 설치한다.
// 처음 프로젝트를 세팅했다면 이 명령어로 패키지를 설치하고 개발을 시작하면 된다.

npm i
// npm install 의 줄인 명령어. 

npm install [package]
// 현재 작업중인 디렉토리 내에 있는 ./node_modules에 [package]를 설치한다. 
// (예: npm install moment) -> ./node_modules에 moment 패키지를 설치 함

npm install [package] --save
// [package]를 설치 하면서 package.json파일에 있는 dependencies 객체에 지금 설치한 패키지 정보를 추가한다.

npm install [package] --save -dev
// --save옵션과 같이 package.json파일에 의존성 내용을 추가하지만
// dependencies가 아닌 devDepenencies 객체에 추가한다.
–save와 –save-dev의 차이는 의존성을 기본으로 추가할지, 개발용으로 추가할지의 차이이다.
--production로 빌드할 경우 devDepenencies에 있는 패키지들은 설치되지 않는다

npm install [package] --no-save
// dependencies에 패키지 정보를 추가하지 않는다.

npm install [package] --save-exact
// 정확히 일치하는 버전의 패키지를 추가한다.

npm install [package] --save-bundle
// 해당 패키지를 bundleDependencies에 추가한다.

npm install [package] --force
// 해당 패키지가 존재하더라도 원격 저장소에 있는 패키지를 가져온다.

 

 

 

 

 

참고:

 

+ Recent posts