[멋쟁이사자처럼 블록체인 스쿨 1기] 22.09.16

박기영·2022년 9월 16일
0

멋쟁이사자처럼

목록 보기
4/4

오늘은 난이도에 관한 실습을 진행했다.
지난 강의에서 블록 해시가 타켓값보다 낮으면 채굴이 성공했다는 것을 배웠는데,
그 것과 난이도의 상관관계를 더 자세하게 다뤘다.

😵 난이도와 타겟값의 관계

난이도와 타겟은 어떤 관계가 있을까?
비트코인 위키에 아래와 같은 공식이 있다.(비트코인이 정보가 많기 때문에 자료로 채택)

difficulty = difficulty_1_target / current_target
현재 블록의 난이도 = 제네시스 블록의 타겟값 / 현재 타겟값

비트코인에서 채굴할 블록의 난이도는 위와 같은 방식으로 결정된다.
오늘 해볼 것은 이 공식을 약간 변경해서

current_target = difficulty_1_target / difficulty
현재 타겟값 = 제네시스 블록의 타겟값 / 현재 블록의 난이도

이렇게 만들고나서, 채굴된 블록의 해시가 타겟값보다 낮은지를 확인해 볼 것이다.

🤔 difficulty_1_target

제네시스 블록은 처음으로 채굴된 블록이다.
따라서, 이전 블록이 없고 개발자들이 작성해놓은 로직에 의하여 첫 번째 난이도가 설정된다.
갑자기 난이도 얘기를 왜 하느냐?
난이도로 타겟값을 구할 수 있기 때문이다.
초기 설정된 난이도값은 0x1d00ffff 이다.

결론부터 말하면 난이도로 타겟값을 구하는 공식은

target = B * 2^(8 * (A - 3))

이다.(비트코인에서)
A와 B가 무엇일까?

난이도값이 0x1d00ffff 라고 위에서 언급했다.
16진수의 가장 앞 2개 자리를 B,
나머지 4자리를 A라고 한다.
따라서, 값을 대입하면 아래와 같이 될 것이다.

target = 0x1d * 2^(8 * (0x00ffff - 3))

이걸 어떻게 계산하면 될까?
16진수를 10진수로 변환하면 된다.

그렇게 계산한값은

target = 2.6959535291011309493156476344724e+67

이렇게 긴~ 값이 나오게 된다. 10진수로.
이걸 다시 16진수로 바꿔준다.

target = 0xffff0000000000000000000000000000000000000000000000000000

이게 바로 제네시스 블록의 타겟값이다.
위 공식에서 difficulty_1_target 이 여기에 해당한다.

😵 채굴된 블록의 해시 < 타겟값

오늘 실습의 주된 목적은 채굴된 블록의 해시가 타겟값보다 작다고 배웠던 것을 직접 확인하는 것이다.
어떻게 이걸 확인할 수 있을까?
방법은 아래와 같다.
아, 참고로 비트코인 블록체인에서 753,283번 블록을 예시로 사용할 것이다.(이유는..그냥)
블록의 세부 데이터는 이 사이트에 들어가면 알 수 있다.

  1. 753,283번 블록의 해시를 4자리씩 끊고 앞에 0x를 붙인다.
  2. 753,283번 블록의 난이도로 753,283번의 타겟값을 구한다.
  3. 753,283번 블록의 해시와 3번에서 구한 타겟값을 비교해본다.

큰 순서는 알았으니 차례대로 진행해보자.

1번! 753,283번 블록의 해시를 4자리씩 끊고 앞에 0x를 붙인다.

비트코인 블록체인에서 753,283번 블록의 해시는 다음과 같다.

00000000000000000007fcca7a8c980f84938ca7cc051f7b28312567f96a2aab

64자리의 16진수로 표현된 것을 알 수 있다.
이를 알아보기 편하게 4자리씩 끊어서 표현하자. 16진수니까 0x도 앞에 붙여주자.

0x 0000 0000 0000 0000 0007 fcca 7a8c 980f 8493 8ca7 cc05 1f7b 2831 2567 f96a 2aab

길기도 하다.
마지막에 이 값을 타겟값과 비교할 것이다.

2번! 753,283번 블록의 난이도로 타겟값을 구한다.

753,283번 블록의 난이도는 다음과 같다.

32,045,359,565,303.15

편의상 소수점은 빼고 계산할 것이므로 참고 부탁드립니다.
이 숫자를 16진수로 바꾼다.

32,045,359,565,303 = 0x1d25244609f7

이어서, 이 난이도 값으로 타겟값 구하기를 해보자.
위에서 했던 과정을 그대로 따라서 갈 것이다.

current_target = difficulty_1_target / difficulty

이 공식을 따라서 하겠다는 것이다.
우리가 알고있는 것은 difficulty, 즉, 현재의 난이도이다.
바로 직전에 값을 구했다. 소수점 빼고 사용해보자.

current_target = difficulty_1_target / 0x1d25244609f7

우리가 알고 있는 것이 또 있다.
difficulty_1_target, 즉, 제네시스 블록의 타겟값이다.
🤔 difficulty_1_target 에서 구했었다.
그 값을 넣어보면

current_target = 0xffff0000000000000000000000000000000000000000000000000000 / 0x1d25244609f7

연산은 16진수를 10진수로 바꿔서 하면된다.
그럼 왜 바꿨냐고? 이해하라고 그렇게 한 것이다 ㅋ...
아무튼, 10진수로 바꿔서 계산한 결과는 다음과 같다.

current_target = 8.4129296e+53

10진수를 16진수로 바꿔보자.

current_target = 0x8c894009ca62180000000000000000000000000000000

자, 이렇게 753,283번 블록의 타겟값을 구해냈다!!
여기서 잠깐, 우리가 하려던 것이 뭐였더라?
753,283번 블록의 해시와 지금 구한 타겟값을 비교해보는 것이었다.
이미 채굴된 블록이라서 우리가 확인 가능한거니까
분명히 블록의 해시가 타겟값보다 작아야할 것이다.

앞서, 4자리씩 끊어서 보기 편하게 만든 블록 해시값을 다시 가져와보자.

753,283번 블록의 해시 = 0x 0000 0000 0000 0000 0007 fcca 7a8c 980f 8493 8ca7 cc05 1f7b 2831 2567 f96a 2aab

current_target 값도 마찬가지로 보기편하게 만들어보자.

current_target = 0x 8 c894 009c a621 8000 0000 0000 0000 0000 0000 0000 0000

어? 왜 얘는 자릿수가 부족한가요?
16진수 64자리가 나와야하는거 아닌가요?
맞다. 그래서 자릿수가 맞도록 숫자를 추가할 것이다.
숫자의 앞부분에 0을 넣으면 자릿수는 늘어나지만 실제 값에는 변화가 없으므로,
앞부분에 0을 넣어줘서 자릿수를 맞춰주도록 하자.

current_target = 0x 0000 0000 0000 0000 0008 c894 009c a621 8000 0000 0000 0000 0000 0000 0000 0000

자, 이제 블록의 해시current_target을 비교해보자.

753,283번 블록의 해시 = 0x 0000 0000 0000 0000 0007 fcca 7a8c 980f 8493 8ca7 cc05 1f7b 2831 2567 f96a 2aab

current_target = 0x 0000 0000 0000 0000 0008 c894 009c a621 8000 0000 0000 0000 0000 0000 0000 0000

변수명 때문에 조금 밀려보이지만, 0으로 시작되는 것을 제외하면
같은 자릿수에서 블록의 해시는 7,
타겟값은 8로 시작하는 것을 볼 수 있다!!

블록의 해시 < 타겟값

증명을 해냈다.
다시 한번 복습하자면,
채굴(Mining)이 되기 위해서는 블록의 해시를 target값보다 낮게 만들어야한다.

다른 블록도 해볼까?
하나 더 쌓아진 번호인 753,284번 블록을 살펴보자!
같은 과정을 반복하므로 결과만 말하자면, 블록의 해시가 타겟값보다 낮다.
753,284번 블록의 해시는 2,
target은 753,283번 블록에서 구한 것과 똑같은 값으로, 8로 시작한다.

.....왜 target값이 같죠?
지난 강의에서 비트코인은 2016개가 채굴될 때마다 난이도를 조정한다고 했다.
그리고 우리는 target 값이 난이도를 통해 구해진다는 것을 방금 알게 되었다.
그럼 이렇게 유추할 수 있겠다.
753,283번 블록과 753,284번이 난이도가 같아서 target이 같으므로
아직 2016개가 채굴된 것이 아니구나!

😵 time, hashrate, difficulty, target의 관계

자, 위에서 우리는 타겟값과 블록의 해시, 난이도의 관계에 대해서 알아보았다.
그리고 이어지는 블록에서 같은 타겟값이 나오는 것을 통해 난이도가 변하지않으면 타겟값이 같다는 것도 알게되었다.
비트코인의 난이도 조절 주기가 2016개(대략 14일 걸림)인 것도 알고 있다.

이들을 다 합쳐서 어떤 관계 있는지 알아보자.
time은 2016개가 채굴된 기간,
hashrate는 2016개를 채굴하기 위해 사용된 연산량이라고 이해하자.

우선, 공식으로 살펴보면 아래와 같다.

time = difficulty * 2^32 / hashrate

target이 없는데요?
difficulty와 target은 반비례 관계인 것을 이미 알고 있다.
그래서 difficulty가 높아지면 target은 감소하고,
difficulty가 감소하면 target은 높아진다.
따라서, 공식에는 없더라도 저 3개의 변수와 연관되는 것이다.

각설하고, 4개의 변수 간 관계를 알아보자.
다음의 예시를 살펴보자.

참고 자료

제네시스 블록부터 2015번 블럭까지 2016개의 블록이 채굴되는 시간은 14일로 되어있다.
이 때, 14일간 2016개를 채굴한 hashrate(연산량)는 2였다.
2는 아래와 같은 공식으로 얻게 된 것이다.(표에서는 대충 적은 것이므로 연산과 다르다는 생각은 하지말아주세요 ㅎㅎ)

hashrate = difficulty * 2^32 / time

그런데...다음 2016개가 채굴된 때를 보자.(2016 ~ 4031번 블록 채굴 시기)
시간이 10일 밖에 안 걸렸다!!!
곤란하다. 14일마다 2016개씩 채굴될 것이라고 생각했는데, 사람들의 컴퓨터가 너무 좋아서
hashrate가 2.5가 되었고(연산량이 많고, 빨랐고),
10일만에 2016개가 채굴된 것이다.

비트코인 블록체인의 코드들은 이를 어떻게 해결할까?
맞다. 이전 강의에서도 말했듯 난이도 조절을 시작하게 된다.

difficulty = time * hashrate / 2^32

계속 같은 공식에서 주체만 변하고 있는 것을 알 수 있다.
채굴 속도를 늦추기 위해서는 난이도를 올려야한다.
그래서 블록체인은 난이도가 1.8로 증가시켰다.
난이도를 증가시켰으므로, target값은 4로 낮아졌다.

또 그 다음 2016개 채굴된 때를 보자.(4032 ~ 6047번 블록 채굴 시기)
시간이 15일이 걸렸다!
난이도를 1.8로 올렸기 때문에 2016개를 채굴하는 기간이 더 오래걸린 것이다.
이 때, hashrate는 2.8이었다고 한다.

자, 그럼 이 다음 2016개에 대한 블록체인의 대응은 어떻게 될까?
기준은 14일이기 때문에 난이도를 다시 내릴 것이다.
그래서 난이도를 1.7로 조정하는 것을 확인 할 수 있다.
난이도가 감소했기 때문에, target은 증가한다.

이 다음의 2016개 채굴 기간은 난이도 하락으로 인해 다시 짧아질 것이다.

이렇게 time, hashrate, difficulty, target의 관계에 대해 알아보았다.

😵 이진트리

이진트리 개념은 Merkle Hash와 연관된다.
바디의 정보를 가지고 만든 것이 Merkle Hash인데,
이 때, 이진트리 방식으로 만들어진다.

개념은 다음과 같다.

스크린샷 2022-09-16 오후 8 50 25

바디에 1,2,3,4라는 정보가 들어있다.
1과 2, 3과 4를 묶는다.
그 다음 12와 34를 묶는다.
1234가 최종적으로 나오게 되고 이 것이 Merkle Hash가 되는 것이다.

주의할 게 있다.
이진트리라는 이름에서 알 수 있듯이 데이터의 개수는 2의 제곱 수가 되어야 저런 식으로 작동할 수 있다.
뭔...소리세요...?
다음 예시를 보자.

스크린샷 2022-09-16 오후 8 54 08

바디에 7개의 정보가 들어있다.
그런데, 상위 단계로 묶이게되면 7은 짝이 없게 된다...
만약, 데이터 개수가 8개였다면 어땠을까?

스크린샷 2022-09-16 오후 9 02 10

오, 맞아 떨어지는 것을 확인할 수 있다!
아니, 그러면 7개나 15개나, 30개나...
2의 제곱수만큼 데이터가 없는거면 Merkle Hash는 못 만드는거야??
아니다.

7개일 때의 예시로 돌아가자.
위에서는 안되는 것처럼 말했지만 저 상황에서도 Merkle Hash가 만들어진다.

스크린샷 2022-09-16 오후 9 06 39

바로 이렇게!
부족한 부분은 복제본이 그 자리를 채워준다.
아! 그러면 데이터가 1부터 10까지 10개만 있으면, 10이 계속 복제되서 16개를 채우겠네요?
아니다.
정확히는 다음과 같이 복제된다.

예를들어,

스크린샷 2022-09-16 오후 9 10 31

이렇게 12개의 데이터가 있다고 해보자.
12는 2의 제곱수 8과 16 사이의 숫자다.
16으로는 데이터가 부족해서 잘리지를 않으니,
8을 기준으로 데이터를 자른다.

스크린샷 2022-09-16 오후 9 14 10

짜잔, 이렇게 16개를 채운다.
즉, 2의 제곱수가 되는 곳을 기준으로 데이터를 잘라서 복제한다는 것이다.
맨 마지막에 c 있었으니까 c만 복제해서 16개를 채우는게 아니다.

참고로, 복제된 데이터가 승인되어서 블록이 체인에 올라가면 중복 거래 처리가 되는거냐고 의문이 생길 수 있는데,
다행히 이는 자동적으로 제거된다고 한다. 물론 개발자인 우리가 그 기능을 만드는거지만..

오늘은 여기까지다.
블록체인이 암호화폐와 묶여서 등장했던 개념인만큼 해시같은 암호화 내용이 많았다.
다음 강의에서는 어떤 걸 배우게 될 것인가? 어떻게 그 것을 프론트에 연결 할 수 있을까?
오늘 강의, 초청 강연을 들으면서 느낀 것은, 내가 했던 프론트엔드 공부를 더 열심히 해야겠다는 것이었다.
블록체인을 배우긴하지만 메인은 프론트엔드로 가져가기로 다짐했다.
강연 해주신 분에 의하면 "지갑"과 "메타마스크"의 활용이 블록체인과 프론트엔드 스킬을 둘 다 올릴 수 있는 방법인 것 같다.
언젠가 진행하게 될 해커톤에서 이 개념들을 사용하는 방향으로 아이디어를 생각해봐야겠다.

profile
나를 믿는 사람들을, 실망시키지 않도록

0개의 댓글