ウマたん
ウマたん
当サイト【スタビジ】の本記事では、Pythonで簡易ブロックチェーンを実装しながら、ブロックチェーン・ビットコインの仕組みを解説していきます。なぜ改ざんが難しいのか肌で感じていきましょう!

こんにちは!スタビジ編集部です!

近年、暗号通貨が普及して「ブロックチェーン」や「ビットコイン」といった言葉を耳にしたする機会は多いです。

言葉は聞いたことあるけど、どんな仕組みかよくわからない。。。
暗号通貨ってどうして安全って言われているの?

上記の悩みを持つ人は多いのではないでしょうか。

そこで本記事では、Pythonで簡易ブロックチェーンを実装しながら、ブロックチェーンとビットコインの仕組みを解説します。

ウマたん
ウマたん
実際に実装をしてみてブロックチェーンや暗号技術へのモヤモヤを解消していこう!

・ブロックチェーンの仕組み
・Pythonでブロックを実装
・Pythonでビットコインのような仕組みを実装

ブロックチェーンやビットコインの仕組みについてより詳しく勉強したい方は以下のUdemy講座で解説していますのでチェックしてみてください!

【初心者向け】Pythonで分かるブロックチェーン・ビットコインの仕組み!手を動かして学ぼう!

【時間】2.5時間
【レベル】初級

ブロックチェーン・ビットコインの仕組みをPythonで学ぶならこのコース!

今なら購入時に「J56MYR9S」という講師クーポンコードを入れると90%オフ以上の割引価格になりますのでぜひご受講ください!

\30日以内なら返金無料/このコースを見てみる

ブロックチェーンとは?

ブロックチェーン」とは、データを「ブロック」という単位にまとめて、順番に鎖(チェーン)のようにつなげてデータを記録する仕組みです。

データの記録というとイマイチイメージできないと思いますので、例えば注文を例に考えてみましょう。

注文ではどこに何を注文したかの情報や注文日時の情報がブロックに記載されます。

次の注文が入った場合、前回の注文がどれかどのように判断すればよいでしょうか。

注文ごとに注文IDを払い出す方法はありますが、その場合、注文IDが正しくても注文の中身が誤っていたら判別できません。

そこで考えられたのが注文情報を元にスタンプを作成し、そのスタンプを引き継いでいく方法です。

blockchain

このようにブロックの情報を元に計算される値を”ハッシュ“と呼びます。

各ブロックが前のブロックのハッシュ情報を持ち、それらの情報を元に新たなハッシュを作成して繋いでいくのがブロックチェーンのイメージです。

ウマたん
ウマたん
データを元にハッシュを作成してその情報を繋いでいく。。。実際に実装したらもう少しわかるかも!

仮想通貨の仕組み

仮想通貨(ビットコインなど)」は、このブロックチェーン技術を土台として作られた仕組みです。

仮想通貨では「取引情報」をブロックとしてつなぎ合わせていきます。

現実の通貨では銀行が「誰にいくら送ったか」や「その人の残高情報」といった情報を管理する中央集権型の仕組みになります。

一方で仮想通貨ではそのような中央管理者はおらず、世界中の参加者が仮想通貨の取引履歴(台帳)を共有・保証しており、これを「分散型台帳技術」と呼ばれます。

このように仮想通貨は以下の性質があります。

  • 銀行や国といった管理者を持たない
  • 世界中の参加者が同じ取引履歴を共有する
  • 取引の正しさを自動で検証する

また、仮想通貨ではあくまで取引情報のみを記録するため、いくら持っているかという残高情報は記録されないという特徴があります。

仮想通貨のブロックチェーンに書き込まれた取引履歴を元に、自分が今「〇〇BTC」あると計算して算出されるのが感覚としてい面白いですね。

ウマたん
ウマたん
現物でいくら持っているではなく、取引情報を元に〇〇BTC分の権利を持っているイメージかな!

インターネット上のやり取りで完結する価値ということで”仮想通貨”と名前がぴったりだね!

仮想通貨をもっと勉強したい方は以下の記事で勉強方法について詳しく解説しているので。参考にしてみて下さい。

virtualcoin_study
【初心者向け】仮想通貨を始めるための勉強方法と注意点!当サイト【スタビジ】の本記事では、仮想通貨を始めてみたい初心者に向けた、仮想通貨の勉強方法と注意点をまとめています!仮想通貨をやってみたいけど、躊躇している人もこの記事でチャレンジしていきましょう![...

マイニングについて

仮想通貨は取引情報をブロックとしてつないでいます。

ただし、この場合新たな取引があった場合、「誰が新しいブロックを追加するのか」という問題が発生します。

そこで考えられた方法が「マイニング」です。

マイニング」とは、新しいブロックをブロックチェーンに追加するために、大量の計算を行い、その正当性を証明する仕組みです。

マイニングでは改ざんを防止するために大量の計算を行わせ、ブロックを追加する順番を決めていきます。

具体的な流れは以下の通りです。

  1. 世界中の取引がネットワークに集まる
  2. マイナー(マイニングをする人)が取引を選ぶ
  3. マイナーは条件を満たすハッシュ値が出るまで計算を繰り返す
  4. 最初に計算できたマイナーがブロックをネットワークに公開
  5. 検証が入り問題なければブロック追加、マイナーに報酬(新規発行された仮想通貨)が与えられる

この条件を満たすハッシュ値の計算を競わせる方法は「Proof of Work」と呼ばれます。

Pythonでブロックを作ってみよう

ここからは、実際にPythonで「ブロック」を作りながら、ブロックチェーンの基本を理解していきます。

ブロックチェーンの最小単位は “ブロック” なので、まずは「ブロックって何を持ってるの?」をコードで確認しましょう。

今回はPythonの実行環境にGoogle Colaboratoryを使います。

Google Colaboratoryの使い方は以下の記事で詳しく解説しているので、参考にしてみて下さい。

Google Colaboratory
Google Colaboratoryのメリットと使い方!GPU環境でPython回すならこれだ!当サイト【スタビジ】の本記事では、Googleが無償で提供する機械学習のプラットフォーム「Google Colaboratory」をメリット・デメリット・使い方について見ていきます!実際にPythonを実行していきGPUの威力を見ていきます。...

ブロッククラスの実装

ブロックをPythonのクラスとして実装します。

import hashlib
import time
from dataclasses import dataclass

@dataclass
class Block:
    index: int
    timestamp: float
    data: str
    previous_hash: str
    hash: str = ""

    def __post_init__(self):
        self.hash = self.calculate_hash()

    def calculate_hash(self) -> str:
        # ブロックの中身を数値にまとめる(値が変わるとハッシュが変わる)
        block_bytes = (
            self.index.to_bytes(4, byteorder="big") +
            int(self.timestamp).to_bytes(8, byteorder="big") +
            self.data.encode("utf-8") +
            bytes.fromhex(self.previous_hash)
        )

        return hashlib.sha256(block_bytes).hexdigest()

ブロックチェーンのブロックには、ざっくり次の情報が入ります。

  • index:何番目のブロックか
  • timestamp:いつ作られたか
  • data:記録したいデータ(取引など)
  • previous_hash:前のブロックのハッシュ(つなぎ目)
  • hash:このブロック自身のハッシュ(指紋みたいなもの)

上記のコードでは各情報をパラメータとして定義してすべてを数値に変換してから、ハッシュ化を行います。

ブロックを作ってみる

定義したクラスを使ってブロックを作ってみます。

genesis_block = Block(
    index=0,
    timestamp=time.time(),
    data="Genesis Block",
    previous_hash="0" * 64  # SHA-256 は 64文字
)

print(genesis_block)

実際にプログラムを実行すると各パラメータの情報と、それらを組み合わせたデータがハッシュ値として出力されます。

Block(index=0, timestamp=1770551434.196756, data='Genesis Block', previous_hash='0000000000000000000000000000000000000000000000000000000000000000', hash='cffea251d1d614adf2362e57d55c0ef1f178aa83bd9d2d855e8a4bd196ebcc97')

ブロックを追加してみる

次にブロックを追加して、ブロックを繋げていきましょう。

block1 = Block(
    index=1,
    timestamp=time.time(),
    data="Aさん → Bさんへ 10BTC",
    previous_hash=genesis_block.hash
)

print(block1)

処理自体はブロック作成時と同じですが、「previous_hash」が大きく異なります。

ブロック作成時は前のブロックがないため「0」を選択していましたが、ブロック追加時では前のブロックのハッシュ値をデータとして取り込みます。

Block(index=1, timestamp=1770551783.5191286, data='Aさん → Bさんへ 10BTC', previous_hash='cffea251d1d614adf2362e57d55c0ef1f178aa83bd9d2d855e8a4bd196ebcc97', hash='c2de0733107738fb466f39c36d9cdc5f6381d2b6a71b2d7cf69319f83ef17d15')

このようにブロックをどんどんとつないでいったものがブロックチェーンになります。

class Blockchain:
    def __init__(self):
        self.chain = [self.create_genesis_block()]

    def create_genesis_block(self) -> Block:
        return Block(
            index=0,
            timestamp=time.time(),
            data="Genesis Block",
            previous_hash="0" * 64
        )

    def add_block(self, data: dict):
        previous_block = self.chain[-1]

        new_block = Block(
            index=len(self.chain),
            timestamp=time.time(),
            data=data,
            previous_hash=previous_block.hash
        )

        self.chain.append(new_block)

上記が先ほどの処理をブロックチェーンのクラスとして定義したものになります。

ウマたん
ウマたん
前のブロックからハッシュ値を引き継いで新たなハッシュ値を作成することで、ブロック間の関係性を繋いでいくんだね!

前の情報を元にブロックを追加を繰り返してチェーンになっていくんだ!

データ改ざんのチェック

ブロックチェーンの特徴といわれるデータの改ざんの難しさを確認してみましょう。

取引データの中身を改ざんしてみます。

original_hash = block1.hash

# データを改ざん
block1.data = "Aさん → Bさんへ 100BTC"
tampered_hash = block1.calculate_hash()

print("元のhash:", original_hash)
print("改ざん後hash:", tampered_hash)

データを改ざんする前と後でハッシュ値を確認します。

元のhash: c2de0733107738fb466f39c36d9cdc5f6381d2b6a71b2d7cf69319f83ef17d15
改ざん後hash: dd78e469f722cdf48ce96925441c2475deae7f5acf3f129558d1eca4107d3c8e

ブロック内の情報を用いてハッシュ値を計算しているので当然とは言えますが、ハッシュ値が変わります。

出力されるハッシュ値を元に後続にブロックでは計算を行っているため、ブロック間のつながりで不整合が生じます。

仮にインデックスの番号のみでデータの順番を管理していた場合は、インデックスの情報が変わっていなければ、他のデータの情報が変わったことは気づきませんでした。

ブロックチェーンでは、ブロック内の情報を元に計算したハッシュ値を使ってブロック間で連携しているため、一つでも情報が変わればハッシュ値が変わって、データに改ざんがあったことが検知できます。

ウマたん
ウマたん
ハッシュ値も改ざんするとなると後続のブロックすべてのハッシュ値の情報を更新しないといけないから、改ざんが難しいんだね!

ビットコインのような仕組みを作ってみよう

ブロックチェーンの技術を使ってビットコインのような仮想通貨の仕組みを作っていきましょう。

ビットコインでは、「誰が誰にいくら送ったか」の履歴がブロックとして追加されていきます。

この取引履歴を参照して現在自分の残高がいくらかを計算する仕組みです。

取引履歴から残高を計算してみる

取引内容は「誰が」・「誰に」・「いくら」を送ったかが必要なので、下記のように定義します。

# 取引は「誰から・誰へ・いくら」
transaction = {
    "from": "A",
    "to": "B",
    "amount": 10
}

データを辞書型で受け取るように作成したブロッククラスも変更します。

import hashlib
import time
from dataclasses import dataclass

@dataclass
class Block:
    index: int
    timestamp: float
    data: dict | str
    previous_hash: str
    hash: str = ""

    def __post_init__(self):
        self.hash = self.calculate_hash()

    def calculate_hash(self) -> str:
        """
        ブロックの内容をすべてバイト列に変換してハッシュ化
        """
        block_bytes = (
            self.index.to_bytes(4, "big") +
            int(self.timestamp).to_bytes(8, "big") +
            str(self.data).encode("utf-8") +
            bytes.fromhex(self.previous_hash)
        )
        return hashlib.sha256(block_bytes).hexdigest()

class Blockchain:
    def __init__(self):
        self.chain = [self.create_genesis_block()]

    def create_genesis_block(self) -> Block:
        return Block(
            index=0,
            timestamp=time.time(),
            data="Genesis Block",
            previous_hash="0" * 64
        )

    def add_block(self, data: dict):
        previous_block = self.chain[-1]

        new_block = Block(
            index=len(self.chain),
            timestamp=time.time(),
            data=data,
            previous_hash=previous_block.hash
        )

        self.chain.append(new_block)

では、実際に取引データをブロックとして追加していきます。

transaction_1 = {"from": "A", "to": "B", "amount": 10}
transaction_2 = {"from": "B", "to": "C", "amount": 5}
transaction_3 = {"from": "C", "to": "A", "amount": 2}

bc = Blockchain()

bc.add_block(transaction_1)
bc.add_block(transaction_2)
bc.add_block(transaction_3)

ここでは以下がポイントになります。

  • 各ブロックは1つの取引しか知らない
  • あくまでブロックのデータは取引情報だけ、残高はどこにも書かれていない

実際にブロックの情報を見てみます。

from datetime import datetime

for block in bc.chain:
    print("======== Block ========")
    print("index        :", block.index)
    print(
        "timestamp    :",
        datetime.fromtimestamp(int(block.timestamp))
    )
    print("data         :", block.data)
    print("previous_hash:", block.previous_hash)
    print("hash         :", block.hash)
    print()

---
======== Block ========
index        : 0
timestamp    : 2026-02-08 14:50:42
data         : Genesis Block
previous_hash: 0000000000000000000000000000000000000000000000000000000000000000
hash         : a5a13787732e222c9aeb5fd8646d595c7e6cab2a2a29ad87a908d6a95cd58293

======== Block ========
index        : 1
timestamp    : 2026-02-08 14:50:42
data         : {'from': 'A', 'to': 'B', 'amount': 10}
previous_hash: a5a13787732e222c9aeb5fd8646d595c7e6cab2a2a29ad87a908d6a95cd58293
hash         : ba24d0e57b157635c22032e03987f4d67904711db6dc84ff5b98e8e5c8c034d4

======== Block ========
index        : 2
timestamp    : 2026-02-08 14:50:42
data         : {'from': 'B', 'to': 'C', 'amount': 5}
previous_hash: ba24d0e57b157635c22032e03987f4d67904711db6dc84ff5b98e8e5c8c034d4
hash         : 7ac04de133258e82e23c67448889cf95dbe2d0405cf5abaf1ee17579abdd2e7e

======== Block ========
index        : 3
timestamp    : 2026-02-08 14:50:42
data         : {'from': 'C', 'to': 'A', 'amount': 2}
previous_hash: 7ac04de133258e82e23c67448889cf95dbe2d0405cf5abaf1ee17579abdd2e7e
hash         : 9596ad57ab86cf56bce04542f270371930b345ccecd42e5acd37c164bc964fb6

dataに取引情報が入り、それらを元にハッシュ値が作成されて、ブロックがつながっています。

では、この情報を元に各ユーザーの持ち額を計算する関数を作成します。

def calculate_balances(blockchain: Blockchain):
    balances = {}

    for block in blockchain.chain:
        if not isinstance(block.data, dict):
            continue

        sender = block.data["from"]
        receiver = block.data["to"]
        amount = block.data["amount"]

        balances[sender] = balances.get(sender, 0) - amount
        balances[receiver] = balances.get(receiver, 0) + amount

    return balances

ブロックから「誰が」・「誰に」・「いくら」の情報を抜き取り、ブロックの最初から計算する流れですね。

balances = calculate_balances(bc)
print(balances)

---
{'A': -8, 'B': 5, 'C': 3}

実際に計算すると上記になります。現金で考えた場合と同じ結果になりますね。

ただし、現金の場合は実物をやり取りした後の残高が情報になるのに対し、仮想通貨では取引の履歴をデータとして保存し、そこから残高を計算する点が違いになります。

ウマたん
ウマたん
仮想通貨では取引情報がすべて!だから改ざんされない信頼性が大事なんだね!

Proof of Workを体験してみる

仮想通貨の特徴の一つである「Proof of Work」を体験してみましょう、

Proof of Workはざっくり以下の流れで行われます。

  1. ブロックに「nonce(ナンス:適当な数)」を足す
  2. ブロックのハッシュ値がある条件を満たすまで計算する

仕組み自体はシンプルですね。

まずはブロックに「nonce」を付けるように関数を修正します。

import hashlib
import time
from dataclasses import dataclass

@dataclass
class Block:
    index: int
    timestamp: float
    data: dict | str
    previous_hash: str
    nonce: int = 0            # ★追加:PoWのための数
    hash: str = ""            # 既存

    def __post_init__(self):
        # Block作成時点で現在のnonceでhashを計算
        self.hash = self.calculate_hash()

    def calculate_hash(self) -> str:
        """
        ブロックの内容をすべてバイト列に変換してハッシュ化(nonceも含める)
        """
        block_bytes = (
            self.index.to_bytes(4, "big") +
            int(self.timestamp).to_bytes(8, "big") +
            str(self.data).encode("utf-8") +
            bytes.fromhex(self.previous_hash) +
            self.nonce.to_bytes(8, "big")         # ★追加:nonceをバイト列で付与
        )
        return hashlib.sha256(block_bytes).hexdigest()

続いて、ブロックチェーンのクラスに条件に合うハッシュ値を計算をする処理を追加します。

class Blockchain:
    def __init__(self, difficulty: int = 4):
        """
        difficulty: 先頭に必要な'0'の数
        """
        self.difficulty = difficulty
        self.chain = [self.create_genesis_block()]

        # Genesis blockもPoW条件を満たすようにする
        self._mine_block(self.chain[0])

    def create_genesis_block(self) -> Block:
        return Block(
            index=0,
            timestamp=time.time(),
            data="Genesis Block",
            previous_hash="0" * 64
        )

    def add_block(self, data: dict):
        previous_block = self.chain[-1]

        new_block = Block(
            index=len(self.chain),
            timestamp=time.time(),
            data=data,
            previous_hash=previous_block.hash
        )

        # ★追加:PoW(マイニング)
        self._mine_block(new_block)

        self.chain.append(new_block)

    def _mine_block(self, block: Block):
        """
        Proof of Work:
        ハッシュの先頭が '0'*difficultyになるまでnonceを増やし続ける
        """
        prefix = "0" * self.difficulty
        nonce = 0

        start = time.time()
        while True:
            block.nonce = nonce
            h = block.calculate_hash()

            if h.startswith(prefix):
                block.hash = h
                elapsed = time.time() - start
                print(
                    f"[Mined] index={block.index} nonce={block.nonce} "
                    f"hash={block.hash[:16]}... time={elapsed:.3f}s"
                )
                return

            nonce += 1

「difficulty」が4の場合、ハッシュ値の先頭が”0000″となるようにひたすらnonceの値を変更して計算し続けます。

実際に計算した結果が以下になります。

transaction_1 = {"from": "A", "to": "B", "amount": 10}
transaction_2 = {"from": "B", "to": "C", "amount": 5}
transaction_3 = {"from": "C", "to": "A", "amount": 2}

bc = Blockchain(difficulty=4)

bc.add_block(transaction_1)
bc.add_block(transaction_2)
bc.add_block(transaction_3)

---
[Mined] index=0 nonce=148697 hash=00008abbd6810523... time=0.353s
[Mined] index=1 nonce=150078 hash=0000c81c0aae3e1f... time=0.453s
[Mined] index=2 nonce=54621 hash=000006ab2e2dc983... time=0.156s
[Mined] index=3 nonce=34961 hash=00007fba9bf39678... time=0.106s

条件を満たすハッシュ値が出力されているのがわかります。

仮想通貨では各取引に対してProof of Workが行われ、条件を満たしたブロックが追加されていきます。

ただし実際は、世界中のノードとの通信や高度なセキュリティ対策がされているのでより仕組みは複雑になります。

ウマたん
ウマたん
計算しまくって条件をみたすブロックを見つける姿勢はまさに”発掘”って感じだね!

Pythonでブロックチェーン・ビットコインの仕組みを学ぶ まとめ

PythonでブロックチェーンやビットコインのしくみをPythonで実装しながら見ていきました。

この記事ではざっくりとした説明なので、もしもっと詳しく知りたい場合は、以下のUdemy講座をぜひ受講してください。

【初心者向け】Pythonで分かるブロックチェーン・ビットコインの仕組み!手を動かして学ぼう!

【時間】2.5時間
【レベル】初級

ブロックチェーン・ビットコインの仕組みをPythonで学ぶならこのコース!

今なら購入時に「J56MYR9S」という講師クーポンコードを入れると90%オフ以上の割引価格になりますのでぜひご受講ください!

\30日以内なら返金無料/このコースを見てみる

さらに詳しくAIやデータサイエンスの勉強がしたい!という方は当サイト「スタビジ」が提供するスタビジアカデミーというサービスで体系的に学ぶことが可能ですので是非参考にしてみてください!

AIデータサイエンス特化スクール「スタアカ」

スタアカトップ
【価格】ライトプラン:1280円/月
プレミアムプラン:149,800円
【オススメ度】
【サポート体制】
【受講形式】オンライン形式
【学習範囲】データサイエンスを網羅的に学ぶ
実践的なビジネスフレームワークを学ぶ
SQLとPythonを組み合わせて実データを使った様々なワークを行う
マーケティングの実行プラン策定
マーケティングとデータ分析の掛け合わせで集客マネタイズ

データサイエンティストとしての自分の経験をふまえてエッセンスを詰め込んだのがこちらのスタビジアカデミー、略して「スタアカ」!!

当メディアが運営するスクールです。

24時間以内の質問対応と現役データサイエンティストによる複数回のメンタリングを実施します!

カリキュラム自体は、他のスクールと比較して圧倒的に良い自信があるのでぜひ受講してみてください!

他のスクールのカリキュラムはPythonでの機械学習実装だけに焦点が当たっているものが多く、実務に即した内容になっていないものが多いです。

そんな課題感に対して、実務で使うことの多いSQLや機械学習のビジネス導入プロセスの理解なども合わせて学べるボリューム満点のコースになっています!

Pythonが初めての人でも学べるようなカリキュラムにしておりますので是非チェックしてみてください!

ウォルマートのデータを使って商品の予測分析をしたり、実務で使うことの多いGoogleプロダクトのBigQueryを使って投球分析をしたり、データサイエンティストに必要なビジネス・マーケティングの基礎を学んでマーケティングプランを作ってもらったり・Webサイト構築してデータ基盤構築してWebマーケ×データ分析実践してもらったりする盛りだくさんの内容になってます!

・BigQuery上でSQL、Google Colab上でPythonを使い野球の投球分析
・世界最大手小売企業のウォルマートの実データを用いた需要予測
・ビジネス・マーケティングの基礎を学んで実際の企業を題材にしたマーケティングプランの策定
・Webサイト構築してデータ基盤構築してWebマーケ×データ分析実践して稼ぐ

スタビジアカデミーでデータサイエンスをさらに深く学ぼう!

スタアカサービスバナースタビジのコンテンツをさらに深堀りしたコンテンツが動画と一緒に学べるスクールです。

プレミアムプランでは私がマンツーマンで伴走させていただきます!ご受講お待ちしております!

スタビジアカデミーはこちら