티스토리 뷰

IT

블록체인 C#으로 만들어보기

현정경 2021. 5. 29. 22:27

여기에서의 예제는 HOSANG JEON님 블로그 글  [JAVA 코드로 이해하는 블록체인(BLOCKCHAIN)]에 나온 JAVA 코드의 예제를 C#으로 컨버팅(converting)한 것임을 밝힌다.

해당 글의 예제를 이용하게 된 이유는 네트워크 노드를 실제로 구현하지 않고 하나의 스레드 안에서 동작하도록 되어 있으나 블록체인의 기본개념을 이해하기에 매우 적절한 구조를 갖고 있었기 때문이다. 입문 차원에서 적절한 예제로 판단된다.(작업증명이 없는 게 아쉬운 점이긴 하다)

다만 먼저 본 글의 예제는 JAVA로 되어 있었기에 내게 익숙한 C# 코드로 칸버팅하는 작업을 해보았다. 칸버팅은 창조적인 작업보다는 거의 베끼기이니 뭐 거의 어렵지 않았다ㅎㅎ (콘솔용 C#이다)

물론 JAVA가 더 익숙한 분이라면 링크한 예제를 참고하길 바라며 자세한 설명의 경우는 해당 글을 참고할 것. 여기서는 설명을 배제한다. GitHub에 소스를 올려두었으므로 참고할 것.


(18/2/21일 추가)

현재 작업 증명(proof of work)에 대한 기능을 추가했고 GitHub에 올려두었다. 현재까지 작업한 것을 대강 설명하자면 아래와 같다.

  • 간단한 작업증명 기능 추가
  • 출력용 해시를 ByteArray에서 Hash 문자열로 출력하도록 변경
  • 주석의 보완

작업증명의 경우 JAVA로 짠 원작자 분의 코드에는 빠져있으므로 따로 설명을 해야 할 것 같다.

작업증명 기능은 원리를 이해하고나서 바로 코드를 짠 거라 실제랑은 차이가 있을 수 있다. 원론적으로는 일단 일치하니까 교육상으로도 좋다고 봄. 내가 참고한 작업증명 원리는 HomoEfficio님 블로그 글 「Blockchain의 기초 개념」을 참고할 것.

나는 BlockHeader 클래스에 다음과 같은 메소드를 추가했다.

        /// <summary>
        ///  채굴과정에서 필요한 작업 증명(Proof of Work) 알고리즘의 난이도 목표
        /// </summary>
        private static uint difficultyTarget = 10;
        /// <summary>
        ///  채굴과정의 작업 증명에서 사용되는 카운터
        /// </summary>
        private static int nonce = 0;

        /// 작업증명
        /// </summary>
        public int ProofOfWorkCount()
        {
            using (SHA256Managed hashstring = new SHA256Managed())
            {
                byte[] bt;
                string sHash = string.Empty;
                while (sHash == string.Empty || sHash.Substring(0, (int)difficultyTarget) != ("").PadLeft((int)difficultyTarget, '0'))
                {
                    bt = Encoding.UTF8.GetBytes(merkleRootHash + nonce.ToString());
                    sHash = Block.ByteArrayToString(hashstring.ComputeHash(bt));
                    nonce++;
                }
                return nonce;
            }
        }

difficultyTarget은 작업 증명의 난이도를 말한다. 실제 블록체인은 참여하는 노드들의 수를 이용하여 SHA-256의 경우의 수를 가지고 확률을 얻고 그로부터 10분 동안 노드들이 작업 증명을 끝낼 수 있도록 난이도를 조정한다. 여기에서는 임의로 카운트를 정하도록 하였다.

nonce는 거래내역에 붙는 수학적 변수의 성격을 갖는다.  중학교 수학에서 연립방정식을 풀기 위해 대입법을 쓰는데 그것과 같다. 블록에서는 컴퓨터가 이를 증가시켜서 대입해보고, 그 난이도가 설정한 자릿수만큼 해시코드 문자열의 앞에 '0'이 나오면 작업 증명이 끝나고 아니면 또 증가시켜서 대입하는 식이다.

작업 증명의 기능은 ProofOfWorkCount 메소드에서 적용되어 있다. while 문을 이용하여 거래내역 해시에 nonce를 붙이고 해시화된 문자열의 앞에 난이도(자릿수)만큼의 '0'이 나오면 성공한 nonce를 리턴하는 것이다.

블록체인의 개념을 이해하기 위한 예제로써 이정도면 충분하지 않을까 싶다;; 다만 블록의 유효성 검증이 빠진 점을 보강할 필요가 있겠는데.. 이건 언젠가는 할 수 있겠지? 다른 분들에게도 도움이 되었다면 매우 기쁘겠다.

[이관 글. 2018-01-29 작성]