どうも、月見(@Suzuka14144156)です。
私は、ブロックチェーンに関する研究をしており、本ブログでは仮想通貨/暗号資産の情報を整理して発信しています。
今回は、Pythonでブロックチェーンを実際に実装していきたいと思います。
参考にした講座は以下のUdemyの講座です。
こちらの講座は、Pythonでスクラッチでブロックチェーンを実装するというものです。
Pythonの中級者以上の向けの講座となっています。
ブロックチェーンだけでなく、クラスを使ったコーディングを覚えたい方にもオススメの講座だと思います。
前回までの私の記事は、こちらです。
今回は、前回からの続きですので、お読みでない方は、ぜひ参考にしてみてください。
【Python】ブロックチェーンの実装_1 クラスの定義
【Python】ブロックチェーンの実装方法_2 hashの定義
【Python】ブロックチェーンの実装方法_3 トランザクションの定義
【Python】ブロックチェーンの実装方法_4 Proof of Workの定義

【Python】ブロックチェーンの実装方法_5 マイニングの実装
【Python】ブロックチェーンの実装方法_6 秘密鍵と公開鍵とウォレットの実装
今回は、ブロックチェーンアドレスの生成です。
ブロックチェーンアドレスの生成
今回は、パブリックキー(公開鍵)からブロックチェーンアドレスを生成していきます。
システム上、パブリックキーをトランザクションの中に格納することは、可能です。
しかし、メモリの容量は、少しでも節約したいです。
そのため、なるべく短い情報量でユニークな情報を生成するために、ブロックチェーンアドレスがあります。
- ECDSAでパブリックキーを生成
- SHA-256の適用
- Ripemd 160 をSHA-256に適用
- ネットワークバイトの付与
- Double SHA-256
- チェックサムの生成
- パブリックキーとチェックサムの連結
- Base58 でエンコード
ECDSAでパブリックキーを生成
- ECDSA(Elliptic Curve Digital Signature Algorithm)とは、楕円曲線DSA
- ビットコインの送金のための暗号化技術
SHA-256の適用
- SHA-256【Secure Hash Algorithm 256-bit】は、任意の長さの原文から固定長の特徴的な値を算出するハッシュ関数(要約関数)の一つです。
Ripemd 160 をSHA-256に適用
- RIPEMD-160は、オリジナルのRIPEMDでは128ビットであるハッシュ長を160ビットにしたうえで改良を加えたもの
- RIPEMDは、暗号学的ハッシュ関数
- SHA-256より、短いハッシュを生成することが可能
ネットワークバイトの付与
- メインネットとテストネットを分けるのに当たり、メインネットには、00を先頭に足す
Double SHA-256
- ダブルハッシュを使う
- SHA-256でハッシュを作成し、digest()に変換
- それを再度SHA-256でハッシュ化する
チェックサムの生成
- データの信頼性を確かめるためにチェックサムを用いる
- 今回チェックサムは、上位8桁とする

- データの信頼性を高速かつそれなりの信頼性でチェックするのに総和をとった計算を用いる方法はよく使われます
Base58 でエンコード
- Base58は、データを58種類の英数字のみを用いたエンコード方式
詳細は、こちらのページを参照ください。
コード
wallet.py
class Wallet(object):
def __init__(self):
self._private_key = SigningKey.generate(curve=NIST256p)
self._public_key = self._private_key.get_verifying_key()
self._blockchain_address = self.generate_blockchain_address()
@property
def private_key(self):
return self._private_key.to_string().hex()
@property
def public_key(self):
return self._public_key.to_string().hex()
@property
def blockchain_address(self):
return self._blockchain_address
def generate_blockchain_address(self):
# SHA-256の適用
public_key_bytes = self._public_key.to_string()
sha256_bpk = hashlib.sha256(public_key_bytes)
sha256_bpk_digest = sha256_bpk.digest()
# Ripemd 160 をSHA-256に適用
ripemed160_bpk = hashlib.new('ripemd160')
ripemed160_bpk.update(sha256_bpk_digest)
ripemed160_bpk_digest = ripemed160_bpk.digest()
ripemed160_bpk_hex = codecs.encode(ripemed160_bpk_digest, 'hex')
#ネットワークバイトの付与
network_byte = b'00'
network_bitcoin_public_key = network_byte + ripemed160_bpk_hex
network_bitcoin_public_key_bytes = codecs.decode(
network_bitcoin_public_key, 'hex')
#Double SHA-256
sha256_bpk = hashlib.sha256(network_bitcoin_public_key_bytes)
sha256_bpk_digest = sha256_bpk.digest()
sha256_2_nbpk = hashlib.sha256(sha256_bpk_digest)
sha256_2_nbpk_digest = sha256_2_nbpk.digest()
sha256_hex = codecs.encode(sha256_2_nbpk_digest, 'hex')
#チェックサムの生成
checksum = sha256_hex[:8]
#パブリックキーとチェックサムの連結
address_hex = (network_bitcoin_public_key + checksum).decode('utf-8')
#Base58 でエンコード
blockchain_address = base58.b58encode(address_hex).decode('utf-8')
return blockchain_address
if __name__ == '__main__':
wallet = Wallet()
print(wallet.private_key)
print(wallet.public_key)
print(wallet.blockchain_address)
実行結果
973201db32d0cbd10cbf2fdb2ce280ed5db7ccfb4cd31c510049b288d7c5a9f1
fb54eb350e5d640e18f7fb1b5507ee882c871880543c53ab95edfff45a5f88f8ec1b2220b1ceb9ef750289fa38cba44be371630911e23da9a684dfb62a86271b
bSLh4YvRiyfcQTv7wSJFVe5HgyFrCBmboAGpzcSrff9hYzZj8T9AEMsTgLjhuGoYPUaH
1

プライベートキーとパブリックキーとブロックチェーンアドレスを出力した結果となります








コメント