공개키 비트코인 주소 형식에 대해 알아본다. 이는 곧 "주소"이다.
BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def encode_base58(s):
count = 0
for c in s: # 전처리이다. 0바이트의 개수를 정한다.
if c == 0:
count += 1
else:
break
num = int.from_bytes(s, 'big') # 바이너리 데이터를 숫자로 디코딩한다.
prefix = '1' * count # 0에 대응되는 값인 "1"을 0바이트 개수만큼 prefix로 달아둔다. 이 부분은 p2pkh에서 필요하다.
result = ''
while num > 0:
num, mod = divmod(num, 58)
result = BASE58_ALPHABET[mod] + result # 58로 나눈 나머지를 바탕으로 문자를 결정한다.
return prefix + result # 결과를 더한다.
def decode_base58(s):
num = 0
for c in s:
num *= 58
num += BASE58_ALPHABET.index(c)
combined = num.to_bytes(25, byteorder='big')
checksum = combined[-4:]
if hash256(combined[:-4])[:4] != checksum:
raise ValueError('bad address: {} {}'.format(checksum, hash256(combined[:-4])[:4]))
return combined[1:-4]
class S256Point(Point):
...
def address(self, compressed=True, testnet=False):
'''Returns the address string'''
h160 = self.hash160(compressed)
if testnet:
prefix = b'\x6f'
else:
prefix = b'\x00'
return encode_base58_checksum(prefix + h160)
def hash160(self, compressed=True):
return hash160(self.sec(compressed))
def hash160(s):
'''sha256 followed by ripemd160'''
return hashlib.new('ripemd160', hashlib.sha256(s).digest()).digest()
def encode_base58_checksum(b):
return encode_base58(b + hash256(b)[:4])
def hash256(s):
'''two rounds of sha256'''
return hashlib.sha256(hashlib.sha256(s).digest()).digest()
def encode_base58(s):
count = 0
for c in s: # <1>
if c == 0:
count += 1
else:
break
num = int.from_bytes(s, 'big')
prefix = '1' * count
result = ''
while num > 0: # <2>
num, mod = divmod(num, 58)
result = BASE58_ALPHABET[mod] + result
return prefix + result # <3>