ビットコインの仕組みをpythonで実装してみる #1 「ビットコインの仕組みとアドレス」

スポンサーリンク
日常で思うこと

はじめに

ブロックチェーンの必要性について考えていたことがありました。

それはなりすまし対策も含まれている技術で、スマートコントラクトに使われていることもあるので、それは詐欺対策になるのではないかということです。

そこで今回はブロックチェーンというより、ビットコインに焦点を絞って、その技術を調査、検証してみる事にしました。

ブロックチェーンとは

ブロックチェーンは取引記録をまとめた「ブロック」を、鎖のようにつなげた台帳になります。

ブロックチェーンが安全だと言われる理由は、ブロックが繋がっているため、もし誰かが過去を書き換えると、ブロックのハッシュが変わり、それ以降のブロック全部が無効になるため、改ざんがほぼ不可能だからです。

ビットコインの仕組み

ではビットコインはどのようにブロックチェーンを使っているのでしょうか?

ビットコインの中のどこでブロックチェーンが使われているのか

ビットコインは「誰が誰にいくら送ったか」を記録するためにブロックチェーンを使っています。

ビットコインの流れは以下です。

① ユーザーが取引を作る
② 取引はネットワークに広がる
③ マイナーが取引をまとめる
④ ブロックを作る
⑤ ブロックがチェーンに追加される

この流れを図にまとめると以下のようになります。

より詳しく表記すると以下のようになります。

この一連の流れを理解し、でも実装まですることが今回の一連の記事のお題です。

今回はアドレスの作成のところ、つまり以下の部分を見てみる事にします。

アドレス作成

アドレスとは送金先として使う「口座番号」的な存在です。

アドレスは秘密鍵から「秘密鍵 → 公開鍵 → アドレス」のように求められます。

ここで、ウォレットはこの秘密鍵を管理する存在です。

銀行で例えると以下のようなイメージ。

ブロックチェーン銀行
秘密鍵印鑑・署名
アドレス口座番号
ウォレット印鑑ケース

今回はaddressはひとつだけしか使わないため、ウォレットは今回のpython実装には登場しません。

では、早速、pythonでアドレスを作成してみます。

以下のコードになります。

import os
import hashlib
import ecdsa
import base58

def hash256(data: bytes) -> bytes:
    return hashlib.sha256(hashlib.sha256(data).digest()).digest()

def pubkey_to_address(public_key: bytes, version: bytes = b"\x00") -> str:
    sha256_pk = hashlib.sha256(public_key).digest()
    ripemd160 = hashlib.new("ripemd160")
    ripemd160.update(sha256_pk)
    hashed_pk = ripemd160.digest()

    versioned_pk = version + hashed_pk
    checksum = hash256(versioned_pk)[:4]
    return base58.b58encode(versioned_pk + checksum).decode()

def generate_keypair() -> tuple[bytes, bytes, str]:
    private_key = os.urandom(32)
    sk = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1)
    vk = sk.verifying_key
    public_key = b"\x04" + vk.to_string()
    address = pubkey_to_address(public_key)
    return private_key, public_key, address

if __name__ == "__main__":
    private_key, public_key, address = generate_keypair()
    print("Private Key :", private_key.hex())
    print("Public Key  :", public_key.hex())
    print("Bitcoin Address :", address)

実行結果

$ python3 address.py
Private Key : e9dd7b078441359fe42c8feef8395c5f458b38c394eebf3898fd2a4....
Public Key  : 04470ed3e0a6642d075da2dd7ae0c33869130f4f7e5219073815f9738128a3b3189b5fc8f914f7eeb....
Bitcoin Address : 1CsziYx6SpKt5RQhJx3gGCLuwv....

プログラムの中で具体的にやっている事は、

秘密鍵を作成

その秘密鍵から楕円曲線を使って公開鍵を作成

公開鍵が長いので、ハッシュ化して短くする

先頭にネットワーク識別子を付けてチェックサムを加える(ネットワーク演算子を付ける事でメインネットとテストネットを区別できます。チェックサムは入力ミスなどを検出できるので、誤送金を防ぎます)

人間が扱いやすくするためにBase58Checkする

これでアドレスが完成します。

最後に

ブロックチェーンの全体像と、アドレスの作成まで実施してみました。

スタートラインに立ちました。

ビットコインのデモまで実装したいものです。

タイトルとURLをコピーしました