개인 키를 WIF 형식으로 변환하는 프로세스를 Python으로 구현
소개
글꼴로 비트코인이나 블록체인이라는 것이 유행하고 있는 것 같네요. 유행을 늦추지 않게(지금 뭐라든지 말하지 말고 ), 최근비트코인과 블록체인이라는 책을 읽기 시작했습니다.
이 책에서 WIF 형식(Wallet Import Format)이라는 형식이 등장했습니다. 비트코인 지갑은 개인 키를 이 형식으로 처리합니다. 이번에 복습을 겸해 비밀키를 WIF 형식으로 변환하는 처리를 Python으로 구현해 보았습니다.
구현
구체적으로는 Bitcoin Wiki의 Wallet import format 라는 페이지에 쓰여진 내용을 코드에 일으켰습니다.
from base58 import b58encode, b58decode
from binascii import hexlify, unhexlify
from hashlib import sha256
import unittest
def encode_private_key_as_wif(private_key):
"""
秘密鍵 (16 進数文字列) を WIF 形式に変換する。
"""
# 先頭の 0x80 は秘密鍵をエンコードする際の version byte を表す。
key = '80' + private_key
tmp = key
# SHA-256 関数を 2 回適用する。
tmp = sha256(unhexlify(tmp)).hexdigest()
tmp = sha256(unhexlify(tmp)).hexdigest()
# 末尾の 8 バイトをチェックサムとする。
checksum = tmp[0:8]
wif_private_key = b58encode(unhexlify(key + checksum))
return wif_private_key
def decode_wif_private_key(wif_private_key):
"""
秘密鍵 (WIF 形式) を 16 進数文字列に変換する。
"""
tmp = hexlify(b58decode(wif_private_key)).decode('utf-8')
# version byte とチェックサムを取り除く。
private_key = tmp[2:-8]
# b58decode の代わりに b58decode_check を使う場合
# tmp = hexlify(b58decode_check(wif_private_key)).decode('utf-8')
# private_key = tmp[2:]
return private_key
def verify_checksum(wif_private_key):
"""
秘密鍵のチェックサムを検証する。
"""
b58decoded = hexlify(b58decode(wif_private_key)).decode('utf-8')
tmp = b58decoded[:-8]
tmp = sha256(unhexlify(tmp)).hexdigest()
tmp = sha256(unhexlify(tmp)).hexdigest()
return b58decoded[-8:] == tmp[:8]
class WIFTest(unittest.TestCase):
"""
WIF 形式に関する関数の動作を検証するための単体テスト。
検証のための値は https://en.bitcoin.it/wiki/Wallet_import_format から借用している。
"""
def test_encode_private_key_as_wif(self):
private_key = '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d'
wif_private_key = encode_private_key_as_wif(private_key)
self.assertEqual('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ', wif_private_key)
def test_decode_wif_private_key(self):
wif_private_key = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
private_key = decode_wif_private_key(wif_private_key)
self.assertEqual('0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d', private_key)
def test_verify_checksum(self):
valid_wif_private_key = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
invalid_wif_private_key = 'SHueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
self.assertTrue(verify_checksum(valid_wif_private_key))
self.assertFalse(verify_checksum(invalid_wif_private_key))
if __name__ == '__main__':
unittest.main()
이 Python 스크립트를 실행하려면 base58
라는 라이브러리가 필요합니다.
$ pip install base58
스크립트를 실행하면 unittest 단위 테스트가 실행됩니다.
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
참고
구체적으로는 Bitcoin Wiki의 Wallet import format 라는 페이지에 쓰여진 내용을 코드에 일으켰습니다.
from base58 import b58encode, b58decode
from binascii import hexlify, unhexlify
from hashlib import sha256
import unittest
def encode_private_key_as_wif(private_key):
"""
秘密鍵 (16 進数文字列) を WIF 形式に変換する。
"""
# 先頭の 0x80 は秘密鍵をエンコードする際の version byte を表す。
key = '80' + private_key
tmp = key
# SHA-256 関数を 2 回適用する。
tmp = sha256(unhexlify(tmp)).hexdigest()
tmp = sha256(unhexlify(tmp)).hexdigest()
# 末尾の 8 バイトをチェックサムとする。
checksum = tmp[0:8]
wif_private_key = b58encode(unhexlify(key + checksum))
return wif_private_key
def decode_wif_private_key(wif_private_key):
"""
秘密鍵 (WIF 形式) を 16 進数文字列に変換する。
"""
tmp = hexlify(b58decode(wif_private_key)).decode('utf-8')
# version byte とチェックサムを取り除く。
private_key = tmp[2:-8]
# b58decode の代わりに b58decode_check を使う場合
# tmp = hexlify(b58decode_check(wif_private_key)).decode('utf-8')
# private_key = tmp[2:]
return private_key
def verify_checksum(wif_private_key):
"""
秘密鍵のチェックサムを検証する。
"""
b58decoded = hexlify(b58decode(wif_private_key)).decode('utf-8')
tmp = b58decoded[:-8]
tmp = sha256(unhexlify(tmp)).hexdigest()
tmp = sha256(unhexlify(tmp)).hexdigest()
return b58decoded[-8:] == tmp[:8]
class WIFTest(unittest.TestCase):
"""
WIF 形式に関する関数の動作を検証するための単体テスト。
検証のための値は https://en.bitcoin.it/wiki/Wallet_import_format から借用している。
"""
def test_encode_private_key_as_wif(self):
private_key = '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d'
wif_private_key = encode_private_key_as_wif(private_key)
self.assertEqual('5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ', wif_private_key)
def test_decode_wif_private_key(self):
wif_private_key = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
private_key = decode_wif_private_key(wif_private_key)
self.assertEqual('0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d', private_key)
def test_verify_checksum(self):
valid_wif_private_key = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
invalid_wif_private_key = 'SHueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
self.assertTrue(verify_checksum(valid_wif_private_key))
self.assertFalse(verify_checksum(invalid_wif_private_key))
if __name__ == '__main__':
unittest.main()
이 Python 스크립트를 실행하려면
base58
라는 라이브러리가 필요합니다.$ pip install base58
스크립트를 실행하면 unittest 단위 테스트가 실행됩니다.
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
참고
Reference
이 문제에 관하여(개인 키를 WIF 형식으로 변환하는 프로세스를 Python으로 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/QUANON/items/2e280a89f6bbca5dc4a6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)