1. 비트코인의 채굴 난이도 구하기
비트코인은 채굴이라는 과정으로 얻을 수 있습니다.
그런데 이 과정은 난이도라는 변수가 존재하는데요
bits 라는 입력값 하나를 이용해 난이도를 구하는 함수 diff()를 구현해 주세요.
아래 링크를 참조하세요.
https://en.bitcoin.it/wiki/Difficulty
https://learnmeabitcoin.com/beginners/difficulty
https://www.quora.com/What-is-the-Bitcoin-mining-difficulty-target-formula
'''
Block #530396
bits = 389315112
difficulty = 5363678461481.357
from reference : 5,363,678,461,481.36
https://www.blockchain.com/btc/block/0000000000000000002a16b0b266d1d568516acb337acdfd6dec1dddce9e07b5
Block #521878
bits = 390462291
difficulty = 4022059196164.954
from reference : 4,022,059,196,164.95
https://www.blockchain.com/en/btc/block/0000000000000000003ab5fdfdce6f17a19a2cefcf3fd21b029a089350d402bc
'''
bits = 389315112
max_target = '0x00000000FFFF0000000000000000000000000000000000000000000000000000'
# MAX_bits = 0x1d00ffff
def dif_cal(a):
tail = str(hex(a))[0:4]
head = "0x" + str(hex(a))[4:]
head_hex = hex(int(head, 16))
zeroer = int(str(hex(a))[0:4], 16)
realzero = int((2 * (zeroer - 3)))
zerostring = ""
for i in range(realzero):
zerostring = zerostring + "0"
diff_c_s = head + zerostring
diff_c_h = hex(int(diff_c_s,16))
diff_c_i = int(diff_c_s,16)
diff_m_h = hex(int(max_target, 16))
diff_m_i = int(max_target, 16)
diff_target = diff_m_i / diff_c_i
print(diff_target)
dif_cal(bits)
2. 비트코인 블럭에 대한 정보인 해시값 구해보기
아래 링크를 참조하세요
https://blockgeeks.com/guides/what-is-hashing/
https://en.bitcoin.it/wiki/Block_hashing_algorithm
'''
https://www.blockchain.com/ko/btc/block/0000000000000000001add5c0da07ac67536318a8e14b23c7e5fe37320a5f73d
Block #530384
bits = 389315112
difficulty = 5,363,678,461,481.36
merckle = 3177fbb8e5a279480c2eaf1da267ec17605366aeb028ace412fc53fc87456b60
nonce = 778197127
이전 블럭의 해시값 : "000000000000000000332f4032babc1a239afd57195320a3d4ee05c794506f91"
현재 블럭의 해시값 : "0000000000000000001add5c0da07ac67536318a8e14b23c7e5fe37320a5f73d
이전 블럭의 해시값과 현재 블럭이 생성된 시간, bits 수(난이도), nonce 값을 이용하여
현재 블럭이 생성될 때 현재 블럭의 해시값을 구하는 문제
다음 블럭이 생성될 때 자동으로 해시값을 생성하기 위한 로직
version, 이전 블럭의 해시값, 블럭 생성시 생성되는 머클값, 블럭 생성시의 시간, 난이도와 넌스값이 input
import hashlib
import binascii
import time
# 1. Getting header values from blockexplorer.com
version = "20000000" # 2
hashPrevBlock = "000000000000000000332f4032babc1a239afd57195320a3d4ee05c794506f91"
hashMerkleRoot = "3177fbb8e5a279480c2eaf1da267ec17605366aeb028ace412fc53fc87456b60"
time = hex(int(time.mktime(time.strptime('2018-07-04 02:19:41', '%Y-%m-%d %H:%M:%S'))) - time.timezone)
bits = 389315112
nonce = 778197127 # in decimal notation
nonce = hex(int(0x100000000)+nonce)[-8:]
bits = hex(bits)
time = time[2:] # 파이썬 계산식에서 16진수의 0x가 없어야 동작해서 문자열 슬라이싱으로 제거합니다.
bits = bits[2:]
print("hex-time = " + time)
print("hex-bits = " + bits)
def un_hex(input):
output = binascii.unhexlify(input)
return output
def re_hex(input):
output = binascii.hexlify(input)
return output
def SHA256_x2(input):
output = hashlib.sha256(hashlib.sha256(input).digest()).digest()
return output
# 2. 리틀-엔디안 헥사코드로 변환합니다.
# 2-1 Un-hex
version = un_hex(version)
hashPrevBlock = un_hex(hashPrevBlock)
hashMerkleRoot = un_hex(hashMerkleRoot)
time = un_hex(time)
bits = un_hex(bits)
nonce = un_hex(nonce)
# 2-2 Reverse(Little Endian)
version = version[::-1]
hashPrevBlock = hashPrevBlock[::-1]
hashMerkleRoot = hashMerkleRoot[::-1]
time = time[::-1]
bits = bits[::-1]
nonce = nonce[::-1]
# 2-1 Hexlify
version = re_hex(version)
hashPrevBlock = re_hex(hashPrevBlock)
hashMerkleRoot = re_hex(hashMerkleRoot)
time = re_hex(time)
bits = re_hex(bits)
nonce = re_hex(nonce)
# 3. 헤더값을 이어붙입니다.(Concatenate)
header = version+hashPrevBlock+hashMerkleRoot+time+bits+nonce
# 4. SHA256 두 번 취해주고
# unhexlify -> sha256 digest x2 -> hexlify
header = un_hex(header)
hash = SHA256_x2(header)
hash = re_hex(hash)
# 5. 이제 다시 빅-엔디안으로 변환합니다.
hash = un_hex(hash)
hash = hash[::-1]
hash = re_hex(hash)
print(hash)
'[중급] 가볍게 이것저것' 카테고리의 다른 글
컴퓨터를 잘 사용하는 EZ한 방법[CPU, 메모리 점유율 100% 달성] (0) | 2022.06.27 |
---|---|
데이터로 알아보는 코로나를 대표하는 키워드! (0) | 2020.04.02 |
월마트 맥주와 기저귀 썰에 대한 부분. (0) | 2020.03.25 |
[R]소득수준 / 소비수준 / 나이 / 성별을 기반으로 고객군 군집화 분석 예제 (0) | 2019.11.11 |
고객 장바구니 분석 level_2 (0) | 2019.11.10 |