brunch

You can make anything
by writing

C.S.Lewis

by Nak Sep 20. 2018

[번역] 자바로 블록체인 만드는 법 파트 1


우선 이 글은 Medium 에서 발췌해온 것이며, 모든 글의 저작권은 아래 링크에 포함됨을 밝힙니다.


https://medium.com/programmers-blockchain/create-simple-blockchain-java-tutorial-from-scratch-6eeed3cb03fa


---------------------------------------------------------------------------------------------------------------------------


이 시리즈의 목적은 블록체인 기술을 개발하는 것이 어떻게 돌아가는지에 대한 이해를 돕기 위함입니다.


이 연습에서 하게 될 내용은 다음과 같습니다:


 첫 번째 블록체인의 기본 형태를 만듭니다.

 간단한 마이닝 시스템을 만듭니다.

 결과에 놀라면 됩니다.


( 여기서는 글을 읽는 독자가 Object Oriented Programming에 대한 어느 정도 이해가 있다는 것을 가정하고 있습니다.)


앞서 한 가지 언급해야할 사실은 여기서 구현하게 될 것이 완벽한 형태의 블락체인은 아니며, 블락 체인 생성을 준비하는 과정이라는 것입니다. 대신 여기서 실행하는 것은 Poc(Proof of Concept) 시행과정으로 이후에 나올 블락 체인에 대한 내용을 이해하는데 도움을 주는 내용입니다.


이후 나올 튜토리얼과 지금 내용을 후원 해주시면 감사하겠네요.

btc: 17svYzRv4XJ1Sfi1TSThp3NBFnh7Xsi6fu


또한 개발 서비스쪽에 관심이 있다면 : axiomtech.io 로 방문해주세요.


세팅


이 게시물에서 사용할 언어는 자바입니다. 하지만 다른 OOP(객체 지향 언어)를 사용하여 따라해도 무방합니다. 또한 저는 여기서 Eclipse를 사용할 것이나, 다른 fency한 에디터를 사용해도 괜찮습니다.(비록 유용한 것들을 몇개 놓칠 수도 있기는 하겠지요.)


필요한 준비물:


자바와 JDK가 인스톨 되어있어야 함

Eclipse (혹은 다른 IDE/Text Editor)


추가적으로 이 다운로드 파일을 받아야 합니다.

이 파일을 통해서 하나의 객체를 Json으로 변환할 수가 있습니다. 이것은 굉장히 유용한 라이브러리로 뒤에 나올 peer2peer를 다룰때에도 사용이 됩니다. 다른 방안이 있다면 그걸 사용하셔도 됩니다.


Eclipse에서 (file >  new > ) Java 프로젝트를 만드세요. 저는 제 프로젝트 이름을 "noobcahin이라고 만들 것입니다. 그리고 (NoobChain)이라는 이름의 클래스를 새로 만들도록 하겠습니다.


이제 시작할 준비가 된 것 같군요.


블록체인 만들기


블록체인은 단순히 블락들의 체인/리스트일 뿐입니다. 블락체인의 각 블락은 자신의 디지털 서명(Digital Signature)를 가지고 있으며, 이전 블락의 디지털 서명을 가지고 있을 뿐 아니라 약간의 데이터를 지니고 있습니다.(예를 들자면 이 데이터들이 교환될 수 있습니다.)

나가모토가 이걸 보지 않았다는데 제 손을 겁니다

Hash = Digital Signature


각 블락은 단순히 이전 블락의 해쉬만을 지니고 있는 것은 아닙니다. 그들 자신만의 해쉬 역시 부분적으로 지니게 되는데, 이 해쉬들은 이전 해쉬를 통해서 계산이 되죠. 만약 이전의 블락의 데이터가 변하게 되면 이전 블락의 해쉬 역시 변하게 됩니다(왜냐하면 부분적으로 그 데이터에 의해서 계산이 되었기 때문이죠). 그 결과 모든 블락의 해쉬들에 대하여 영향을 미치는 것입니다. 그 해쉬들을 계산하고 비교함으로써 블락체인이 유효한지 아닌지 여부를 알 수 있습니다.


이게 의미하는 것이 뭐냐고요?... 이 리스트에 있는 데이터를 고치는 것은 Signature를 변하게 할 수도 있고 그 체인을 무너뜨릴수도 있다는 이야기입니다.


첫번째로 블락체인을 구성하는 Block 클래스를 만들어 봅시다.



여기서 볼 수 있는 것과 같이 우리의 기본 블락은 우리의 디지털 서명을 지니고 있는 String hash를 가지고 있다. 변수인 previousHash는 이전 블락의 해쉬값을 지니고 있고 String data는 블락의 데이터를 지니고 있는 중이다.


다음 할 일은 바로 디지털 서명을 만드는 것입니다,


많은 크립토그래픽 알고리즘이 존재하지만, SHA256이 우리가 지금 하고 있는 예제에 가장 알맞는 알고리즘입니다. 이 SHA256 알고리즘에 접근하기 위해 import java.secutiry.MessageDigest; 임포트 시켜줍니다.


SHA256을 나중에 사용해야할테니 StringUtil이란 'utility'클래스를 만들어 유용한 헬퍼 메소드를 만들도록 하자.



만약 위에 있는 헬퍼 메소드의 코드를 모두 이해하지 못했다고 해서 너무 걱정하지는 마세요. 여기서 중요한 것은 바로 하나의 문자열을 사용했다는 것과 SHA256 알고리즘을 거기에 적용시켰다는 것입니다. 그리고 발생된 시그니쳐를 하나의 문자열로 리턴했다는 것입니다.


해쉬값을 계산하기 위해 Block 클래스의 메소드에 우리가 만든 applySha256 헬퍼를 사용해보도록 하죠. 우리는 영향을 받고 싶지 않은 블락의 모든 부분의 해쉬값들을 계산해야 합니다. 그렇기 때문에 우리의 블락은 previousHash, data 그리고 timeStamp 이 3개를 지니게 될 것입니다.



또한 Block 생성자에 이 메소드를 집어넣어 보도록 하죠.


테스팅 시간


우리의 메인 Noobchain 클래스를 통해 블락을 만들고 해쉬값들을 스크린에 출력해보도록 하겠습니다. 그래서 모든 것이 잘 돌아가고 있는지 확인을 해보죠.


첫번째 블락은 genesis 블락이라고 불리는데, 이것은 첫번째 블락이므로 해쉬값을 가지지 않기 때문에 previous hash 값을 "0"이라고 하겠습니다.



이 코드의 아웃풋은 다음과 같은 형태를 띄어야 합니다.

타임 스탬프의 값이 다를 것이기 때문에 value값은 다를 것입니다

이제 각각의 블락은 각자의 전자 시그니쳐를 가지는데 그 블락의 정보와 이전 블락의 시그니쳐에 기반을 둡니다.

현재로써는 블락체인의 형태를 띄고 있지 않기 때문에 이 블락들을 ArrayList에 집어 넣도록 하겠습니다. 그리고 Json 형태로 그것들을 보기 위해 gson을 임포트하도록 하겠습니다.

<a href= https://medium.com/programmers-blockchain/importing-gson-into-eclipse-ec8cf678ad52> 임포트 방법을 보려면 여기를 클릭하십시오. </a>




이제 우리의 출력물이 블락체인의 형태를 조금씩은 띄는 것 같아 보이는군요.


이제는 우리의 블락체인에 대한 무결성을 검사할 방법이 필요합니다.


NoobChain 클래스에서 boolean 타입의 isChainValid()를 생성해보도록 합시다. 이 메소드는 체인 안에 속해있는 모든 블락들을 루프하며 돌 것이며 해쉬값을 비교할 것입니다. 이 메소드를 통해서 할 일은 바로 해쉬 변수가 실제로 계산된 해쉬값과 같은지 그리고 이전 블락의 해쉬값이 이전 해쉬의 변수와 같은지를 확인하는 것입니다.


블락체인의 블락들에 어더한 변화라도 생기게 된다면 리 메소드는 false값을 리턴할 것입니다.


비트코인 네트워크의 노드들은 그들의 블락체인들을 공유합니다. 그리고 가장 긴 유효한 체인이 네트워크에 의해서 받아들여지게 되죠. 누군가가 오래된 블락의 데이터에 영향을 주는 것고 완전히 새롭게 더 긴 블락 체인을 만들고 네트워크에 그것을 소개한다? Proof of work. Hashcash proof of work 시스템이 의미하는 것은 새로운 블락들을 만들기 위해서는 엄청난 시간과 컴퓨팅 파워가 필요하다느 것입니다. 그러힉 때문에 새롭게 만들고자 하는 사람은 나머지 모든 피어들이 합친 것보다 많은 컴퓨팅 파워가 필요하게 됩니다.


마이닝 블락을 시작해보자!!!


이제 채굴할 사람들이 proof-of-work를 수행하도록 해야합니다. 블락안의 변수들 값의 해쉬값들이 특정 자릿수로(the number of 0's) 시작할때까지 시도를 해봐야 합니다.


nonce 라고 불리는 int 타입의 변수를 calculateHash() 메소드 안에 집어 넣도록 합시다. 또한 필요성이 많은mineBlock() 안에도 집어 넣도록 합시다.



mineBlock() 메소드는 int 타입의 difficulty 패러미터를 취하며, 이 멤버가 바로 풀어야할 자릿수의 숫자입니다. 1이나 2와 같이 낮은 자리의 숫자는 대부분의 컴퓨터에서 바로 처리가 될 수 있습니다. 그렇기 때문에 시험을 하기 위해서 4~6자리 정도의 숫자를 쓰기를 권합니다. LiteCoin의 자릿수는 442,592입니다.


NoobChain 클래스에 static 변수로 이 difficulty를 추가해보도록 하죠.


public static int difficulty = 5;


새로운 각 블락의 mineBlock()이 작동하도록 하기 위해서 NoobChain클래스를 업데이트할 필요성이 있습니다. boolean 타입의 isChainValid() 메소드의 경우 각 블락이 마이닝에 의해서 해결된 해쉬값을 지니고 있는지 체크해줍니다.


결과는 다음과 같이 나타날 수 있습니다:


각 블락을 마이닝 하는 것은 시간이 좀 걸립니다 ( 약 3초 정도) 각 블락의 마이닝 시간에 얼마나 영향을 미치는지 알기 위해서 difficulty 값을 조정해 볼 수도 있겠죠 :)


만약 누군가가 당신의 블록체인 시스템의 데이터에 영향을 미치고 싶을 경우


그의 블록체인이 invalid 상태여야 합니다.

더 긴 블락 체인을 만들 수 없어야 합니다.

당신의 네트워크에 의해서 얻어진 블락체인은 가장 긴 체인에 비해서 시간적 우위를 지닙니다.

누군가에 의해서 영향을 블락체인은 더 길고 유효한 체인을 절대 만들 수 없을 것입니다.*


*혹시라도 그 누군가가 훨씬 더 빠른 컴퓨터 스피드가 당신의 네트워크가 지닌 모든 노드를 합친 것보다 빠를 경우라면 모르겠네요. 미래의 퀀텀 컴퓨터나 그와 비슷한 종류가 그 예가 될 수 있겠죠.


 당신의 기본 블락체인이 생성되었습니다!


당신의 블락체인은 :

> 데이터를 저장하는 블락들로 구성되어 있습니다.

> 당신의 블락들을 체인처럼 연결시켜주는 디지털 서명(Digital signature)를 지니고 있습니다.

> 새로운 블락들을 생성하기 위해서 proof of work 마이닝을 필요로 합니다.

> 블락 안의 데이터의 변화 혹은 유효성에 대한 체크가 가능합니다.


---------------------------------------------------------------------------------------------------------------------------


두번째 튜토리얼 번역은 다음주에 연재될 예정입니다.


소스 코드를 현재는 캡쳐한 상태인데, 브런치에서는 스크립트 기능(밑의 예시와 같은)을 호환하지 않는지, 소스 코드가 따로 붙여넣기가 안되는군요ㅜㅜ


<script src="https://gist.github.com/CryptoKass/c1237ef4ae7bbc5a9eaae7ca47b130e8.js"></script>


혹시 어떻게 붙여넣는지  아시는 분은 알려주시면 감사하겠습니다!


작품 선택
키워드 선택 0 / 3 0
댓글여부
afliean
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari