기사 메일전송
자바(Java)로 미니 블록체인 개발해봐요(3) - SECTION 02. SHA-256을 이용해 채굴의 원리 이해하기 - 필자 나동빈은 '안경잡이' 개발자로 현재 프리랜서로 활약하고 있다.
  • 기사등록 2018-03-27 10:09:04
기사수정


▲ 출처 : 동아사이언스


  지난 시간에는 미니 블록체인 개발 실습을 위해 자바(Java) 개발환경을 구축해보았다. 이번 시간에는 첫 번째 개발 실습 시간으로 SHA-256 해시 값을 구하는 함수를 작성하여 간단히 채굴(Mining)이 이루어지는 원리를 이해해보는 시간을 가질 것이다. 이클립스(Eclipse) 개발환경을 실행하면 다음과 같이 이전 시간에 작성했던 HelloWorld.java 소스코드가 등장한다.



  HelloWorld 프로그램은 이전 시간에 개발환경이 정상적으로 작동하는지 확인하기 위해 임의로 작성한 프로그램이므로 삭제해준다. 이후에 다음과 같이 새로운 클래스(Class) 파일을 생성한다.



  일반적으로 프로그래밍에서는 단순한 수학적 수식을 계산하거나 인코딩을 수행해주는 등, 프로그램의 전반에서 사용될 수 있는 기능은 유틸리티(Utility)로 분류한다. 따라서 SHA-256 해시 연산을 수행해주는 기능은 유틸(Util) 클래스에 담아주기 위해 Util 클래스를 만들어주도록 하자.


  이 때 패키지의 이름으로 util을 넣어준다. 자바 패키지(Java Package)란 자바 클래스들을 분류에 따라서 저장하고 관리하기 위해 사용하는 단위다. 실제로 자바 프로그램은 프로그램의 세부 동작 단위인 클래스 여러 개가 서로 밀접하게 연관되어 동작하기 때문에 적절히 기능에 따라 분류하여 프로그래밍을 해야 추후에 관리가 편하다.



  클래스 생성 이후에는 바로 SHA-256 연산을 수행하는 메소드(Method)를 구현해보자.


package util;


import java.security.MessageDigest;


public class Util {


  public static String getHash(String input) {

    StringBuffer result = new StringBuffer();

    try {

      MessageDigest md = MessageDigest.getInstance("SHA-256");

      md.update(input.getBytes());

      byte bytes[] = md.digest();

      for(int i = 0; i < bytes.length; i++) {</p>

        result.append(

  Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)

        );

      }

    } catch (Exception e) {

      e.printStackTrace();

    }

    return result.toString();

  }

}


  위 소스코드를 보면 MessageDigest라는 라이브러리를 이용해서 ‘SHA-256’ 해시 알고리즘을 사용하겠다고 명시한 것을 알 수 있다. 이후에 사용자로부터 받은 입력을 SHA-256 해시를 적용하여 그 값을 바이트(Byte) 배열 형태로 반환하도록 함수가 작성되었다.



  위 그림과 같이 네모 박스를 친 세 부분 중에서 ‘getHash’가 함수 이름이고, ‘String input’은 함수의 입력 값이며, 마지막의 ‘result.toString()’는 함수의 반환 값이 된다.



  쉽게 말해 위 그림과 같이 우리가 작성한 getHash() 함수는 단순한 문자열이 들어왔을 때 그것을 SHA-256 해시를 적용한 결과 값으로 바꾸어주는 단순한 함수라고 할 수 있다. 이 때 자바에서는 메소드와 함수는 동일한 의미로 사용된다. 이제 이렇게 만들어 본 메소드를 직접 사용해보는 소스코드를 작성해보자.



  위와 같이 하나의 클래스를 더 추가해준다. 이 때 패키지 명으로는 ‘core’를 넣어주고 클래스 이름으로는 ‘BlockChainStarter’를 넣어주자. 이는 우리가 앞으로 제작할 미니 블록체인 프로그램을 실질적으로 구동시키는 소스코드라는 의미에서 블록체인 구동기(Block Chain Starter)라고 클래스 이름을 지어준 것이다.


  또한 해당 클래스는 실제로 소스코드가 처음 실행되는 진입점 역할을 수행하므로 메인 메소드(Main Method)를 추가해준다. 위와 같이 ‘public static void main(String[] args)’ 부분에 체크해주면 된다. 메인 메소드는 하나의 프로그램 안에 여러 개의 클래스가 공존할 때 가장 첫 번째로 실행되는 부분을 정해주기 위해 사용한다. 이후에 클래스가 생성되면 다음과 같이 코드를 작성한다.


package core;


import util.Util;


public class BlockChainStarter {


  public static void main(String[] args) {

    System.out.println(Util.getHash("0"));

  }

}


  위 소스코드는 방금 우리가 작성해준 SHA-256 해시 값을 구하는 함수 getHash()를 사용해서 결과를 확인하는 간단한 형태의 소스코드다. 구체적으로 문자열 “0”에 대한 SHA-256 해시 결과를 출력하도록 하였다. 이제 실행 버튼(F11)을 눌러 프로그램을 동작시켜보자.



  프로그램 실행 결과는 위와 같다. 총 64글자의 16진수 데이터가 출력된 것을 확인할 수 있다. 그 결과는 ‘5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9’로 이해할 수 없는 무작위의 문자열이다. 이제 한 번 문자열 “0” 대신에 “1”을 넣어서 다시 실행해보자.



  실행 결과로 ‘6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b’가 출력된 것을 확인할 수 있다. 이는 앞서 문자열 “0”을 넣었을 때와 비교하여 완전히 다른 결과 값이 출력되었다. 이와 같이 SHA-256 해시 알고리즘은 눈사태 효과(Avalanche Effect) 기법이 적용되어 입력 값에 따른 결과 값을 유추할 수 없고 천차만별이다. 따라서 결과 값을 보고 입력 값이 무엇이었는지 정확히 알아내기 매우 어렵다. 우연의 일치로 맞출 확률 또한 매우 희박하다.


  블록체인에서 사용되는 채굴의 원리는 이러한 눈사태 효과에서 출발한다. 간단한 작업 증명(Proof of Work) 채굴 방식을 소스코드로 구현해보자. 현재 한 글자는 16진수를 의미하므로 2^4 = 16가지 경우의 수를 표현할 수 있다. 그렇다면 작업 난이도를 2^24라고 가정해보자. 쉽게 말해 2^24번 채굴을 시도했을 때 한 번 정도 채굴이 될 수 있도록 난이도를 설정한다는 것이다.


package core;


import util.Util;


public class BlockChainStarter {


  public static void main(String[] args) {

    int nonce = 0;

    while(true) {

      if(Util.getHash(nonce + "").substring(0, 6).equals("000000")) {

        System.out.println("정답: " + nonce);

        break;

      }

      nonce++;

    }

  }

}


  위 소스코드는 임의의 입력 값에 대해서 SHA-256을 적용한 결과 값이 앞에서부터 6자리만큼 모두 문자 ‘0’으로 구성되어있는지 물어보고, 만약 6자리가 모두 ‘0’으로 구성되어 있다면 정답을 찾았다고 출력하는 소스코드다. 6자리가 모두 0일 확률은 2^4를 6번 곱한 수의 역수이므로 1 / 2^24다. 따라서 확률적으로 대략 천만 번 이상의 연산을 수행했을 때 한 번 채굴에 성공할 수 있는 것이다. 실제로 위 프로그램을 작동시키면 수 초 후에 다음과 같은 결과가 출력된다.



  실제 대부분의 작업 증명 합의 알고리즘을 사용하는 블록체인 시스템은 위와 같이 무작위의 입력 갑을 대입하여 정답(Nonce) 과정으로 채굴(Mining)을 진행하도록 설계되어 있다. 현재 우리는 난이도를 2^24로 설정했으나 실제 블록체인 채굴 난이도는 이것보다 훨씬 어렵다는 점에서 고성능의 컴퓨터 연산이 필요한 것이다. 이번 시간에는 간단히 SHA-256 함수를 직접 구현해봄으로써 채굴이 이루어지는 과정에 대해서 이해하는 시간을 가졌다. 이와 같이 해시 값 생성 함수는 블록체인 소프트웨어에서 가장 핵심이 되면서 중요한 기능이므로 이번 시간에 다룬 내용을 반드시 숙지하도록 하자.


다음 호에 계속...

0
기사수정

다른 곳에 퍼가실 때는 아래 고유 링크 주소를 출처로 사용해주세요.

http://www.bitweb.co.kr/news/view.php?idx=579
기자프로필
프로필이미지
나도 한마디
※ 로그인 후 의견을 등록하시면, 자신의 의견을 관리하실 수 있습니다. 0/1000
실시간 암호화폐 순위 확인하기
코인마켓캡
모바일 버전 바로가기