در حال بارگذاری 0%
// منو.exe
خانه رزومه بلاگ تماس سفارش
English فارسی
~/blog / cryptocurrency / how-bitcoin-works

بیت‌کوین چگونه کار می‌کند؟ بیایید خودمان یک نمونه بسازیم

فرض کنید بخواهیم بدون استفاده از بانک، یک سیستم پول دیجیتال بسازیم. علی می‌خواهد ۳۰ واحد پول برای رضا بفرستد. رضا باید بتواند مطمئن شود این پول واقعاً از علی آمده است — و علی نباید بتواند همان ۳۰ واحد را همزمان برای شخص دیگری هم خرج کند. بیت‌کوین از ابتدا برای حل دقیقاً همین مسئله طراحی شد. در این مقاله آن را تکه‌تکه می‌کنیم و نسخه‌ای کوچک اما واقعاً کارکردنی از آن را با Python می‌سازیم.

# اول از همه؛ بیت‌کوین دقیقاً چه مشکلی را حل می‌کند؟

مسئله اصلی پول دیجیتال فقط «انتقال پول» نیست. فرض کنید من ۱۰۰ سکه دیجیتال دارم. اگر بتوانم یک نسخه از این ۱۰۰ سکه را برای علی بفرستم و بعد همان نسخه را برای رضا هم بفرستم، در واقع یک فایل را Copy کرده‌ام. این همان مشکل معروف Double Spending است.
یک فایل

ده بار کپی کنید — کاملاً مشکلی ندارد

file.txt → file2.txt ✓
پول

ده بار کپی کنید — دیگر پول نیست

100 → 100 → 100 → ∞ ✗
راه‌حل سنتی این بود که یک نگه‌دارنده مرکزی دفتر حساب‌ها داشته باشد — بانک:
1
کاربر — می‌خواهد پول بفرستد
2
بانک — دفتر مرکزی را بررسی می‌کند
3
بررسی موجودی — آیا فرستنده پول را دارد؟
4
ثبت — بانک تراکنش را می‌نویسد
اما بیت‌کوین از ابتدا با ایده‌ای متفاوت ساخته شد؛ به‌جای اینکه یک مرکز اصلی بگوید چه تراکنشی معتبر است، مجموعه‌ای از کامپیوترها یا Nodeها یک دفتر عمومی مشترک را نگهداری و قوانین آن را مستقل از یکدیگر بررسی می‌کنند. بلاک‌چین بیت‌کوین در واقع یک دفتر ثبت عمومی و مرتب‌شده از تراکنش‌هاست و هر نود می‌تواند نسخه‌ای از آن را نگهداری و اعتبارسنجی کند.
نکته کلیدی: بیت‌کوین در نگاه اول شاید یک پروژه بسیار پیچیده به نظر برسد؛ اما وقتی آن را به اجزای کوچک‌تر تقسیم کنیم، ایده اصلی بسیار قابل‌فهم‌تر می‌شود. دقیقاً همین کار را در این مقاله انجام می‌دهیم.

# بلاک‌چین در ساده‌ترین شکل چیست؟

بلاک‌چین، در ساده‌ترین شکل، چیزی بیشتر از یک زنجیره از بلاک‌ها نیست. هر بلاک علاوه بر داده‌های خودش، یک مقدار به نام Hash از بلاک قبلی دارد:
B3
Block 3
Previous Hash = hash(Block 2)
B2
Block 2
Previous Hash = hash(Block 1)
B1
Block 1
Previous Hash = hash(Block 0)
B0
بلاک پیدایش (Genesis)
Previous Hash = 000...0
اگر کسی محتوای Block 1 را تغییر دهد، Hash آن تغییر می‌کند. Block 2 دیگر به Hash صحیح Block 1 اشاره نمی‌کند؛ اتصال زنجیره می‌شکند و اعتبار همه‌چیز بعد از آن فرو می‌ریزد. در بیت‌کوین واقعی، هر بلاک به Hash بلاک قبلی در Header خودش اشاره می‌کند و همین زنجیره‌سازی باعث می‌شود تغییر یک بلاک، روی همه بلاک‌های بعدی هم اثر بگذارد.

# Hash چیست و چرا این‌قدر مهم است؟

Hash را می‌توانیم به یک اثر انگشت دیجیتال برای داده تشبیه کنیم. یک متن را به SHA-256 بدهید، یک خروجی با طول ثابت می‌گیرید. فقط یک کاراکتر عوض کنید، خروجی کاملاً متفاوت می‌شود:
sha256("Hello")
185f8db32271fe25f5...
sha256("hello")
2cf24dba5fb0a30e26e...
ایده مهم اینجاست: تغییر بسیار کوچک در ورودی → تغییر بسیار بزرگ در خروجی. در نمونه ما از SHA-256 استفاده خواهیم کرد:
hash_demo.py
import hashlib

text = "Hello"

hash_value = hashlib.sha256(
    text.encode()
).hexdigest()

print(hash_value)
# 185f8db32271fe25f5... (طول ثابت، ظاهراً تصادفی)
در بیت‌کوین، Hash نقش‌های مختلفی دارد؛ از شناسه تراکنش‌ها گرفته تا ساختار بلاک و خودِ Proof of Work.

# اما فقط Hash کافی نیست؛ ورود Proof of Work

فرض کنید من یک بلاک ساخته‌ام. اگر تولید Hash معتبر رایگان باشد، یک مهاجم هم به همان راحتی می‌تواند بلاک را تغییر دهد و Hash جدیدی محاسبه کند. پس بیت‌کوین فقط نمی‌گوید «Hash درست داشته باش»؛ بلکه می‌گوید:
قانون: برای ساختن یک بلاک معتبر، باید مقدار مشخصی کار محاسباتی انجام داده باشی. Hash هدر بلاک باید شرایط سختی (Difficulty) را برآورده کند — مثلاً با تعداد مشخصی صفر شروع شود.
چون نمی‌توان Hash را مستقیماً انتخاب کرد — خروجی ظاهراً تصادفی است — یک عدد به نام Nonce را تغییر می‌دهیم و هر بار دوباره Hash می‌گیریم:
145
83af... — رد شد
146
c921... — رد شد
147
0000b71...قبول شد!
این همان ایده اصلی Proof of Work است: پیدا کردن مقداری که باعث شود Hash هدر بلاک شرایط سختی مشخصی را برآورده کند. در بیت‌کوین این کار به‌عنوان اثبات صرف شدن توان محاسباتی استفاده می‌شود. و چرا فقط Nonce را تغییر می‌دهیم؟ چون تغییر داده‌های بلاک، معنای آن را عوض می‌کند — Nonce همان فیلدی است که از ابتدا برای بارها تغییر داده شدن ساخته شده.
تراکنش‌ها
+
Previous Hash
+
Timestamp
+
Nonce
SHA-256
هدف: hash = 0000................

# Transaction چیست؟ آشنایی با مدل UTXO

حالا به مهم‌ترین بخش می‌رسیم: تراکنش. یک سیستم ساده‌لوح می‌گفت Alice = 100 و از یک موجودی کم می‌کرد. اما بیت‌کوین واقعی از مدل ساده «موجودی حساب» استفاده نمی‌کند. مدل اصلی آن UTXO — Unspent Transaction Output است: خروجی یک تراکنش که هنوز خرج نشده است.
به‌جای اینکه بگوییم Alice = 100 BTC، تصور کنید Alice چند خروجی خرج‌نشده دارد:
60
UTXO #1 → Alice
40
UTXO #2 → Alice
100
جمع = «موجودی» Alice
اگر Alice بخواهد ۳۰ واحد بفرستد، یک یا چند UTXO را مصرف می‌کند و خروجی‌های جدیدی می‌سازد. یک اسکناس ۱۰۰ واحدی را تصور کنید که به دو اسکناس تبدیل شده:
UTXO = 100 — به‌طور کامل مصرف می‌شود
30
→ Bob — پرداخت
70
→ Aliceباقی‌پول (Change)
و دقیقاً به همین دلیل جلوی Double Spending گرفته می‌شود: اگر Alice UTXO-A را برای Bob خرج کند و بعد بخواهد همان UTXO-A را برای Reza هم خرج کند، شبکه تراکنش دوم را رد می‌کند — چون آن خروجی دیگر Unspent نیست. یک خروجی مشخص حداکثر یک‌بار قابل خرج شدن است. مستندات توسعه‌دهندگان بیت‌کوین نیز همین مدل را توضیح می‌دهد: ورودی یک تراکنش به خروجی تراکنش قبلی اشاره می‌کند و هر خروجی فقط یک‌بار می‌تواند خرج شود.

# تراکنش‌ها داخل بلاک کجا می‌روند؟ Merkle Tree

یک بلاک می‌تواند چند تراکنش داشته باشد. اما چگونه بفهمیم مجموعه تراکنش‌ها دستکاری نشده است، بدون اینکه همه‌چیز را دوباره بخوانیم؟ اینجاست که Merkle Tree وارد می‌شود. تراکنش‌ها را دوتا‌دوتا هش می‌کنیم، سطح به سطح، تا یک Hash واحد باقی بماند — Merkle Root:
Merkle Root
hash(H12 + H34) — می‌رود داخل Block Header
H2
سطح ۲
H12 = hash(H1+H2)  •  H34 = hash(H3+H4)
H1
سطح ۱
H1..H4 = هش هر تراکنش (txid)
TX
تراکنش‌ها
TX1 • TX2 • TX3 • TX4
در بیت‌کوین، Hash تراکنش‌ها درخت Merkle را تشکیل می‌دهند و Root در Block Header قرار می‌گیرد. این موضوع حتی اجازه می‌دهد وجود یک تراکنش در یک بلاک بدون نگهداری کل بلاک‌چین اثبات شود؛ همان ایده‌ای که در مقاله اصلی بیت‌کوین با عنوان Simplified Payment Verification توضیح داده شده است.

# حالا بیایید خودمان یک بیت‌کوین کوچک بسازیم

قرار نیست Bitcoin Core را از صفر بازنویسی کنیم. می‌خواهیم نسخه‌ای کوچک بسازیم که چند ایده اصلی را واقعاً اجرا کند:
1
Transaction — ورودی‌ها و خروجی‌ها
2
UTXO — ردیابی پول خرج‌نشده
3
Merkle Root — خلاصه‌سازی بلاک
4
Proof of Work — استخراج بلاک
5
Blockchain — اتصال و اعتبارسنجی
هشدار ساده‌سازی: در بیت‌کوین واقعی، مالکیت UTXO با کلیدهای خصوصی و امضاهای دیجیتال اثبات می‌شود. در نمونه ما، برای قابل‌فهم ماندن کد، مالکیت فقط یک address رشته‌ای است. این برنامه برای یادگیری است، نه برای ساخت پول واقعی.

مرحله اول — توابع کمکی Hash

mini_bitcoin.py — بخش ۱
import hashlib
import json
import time


def sha256_hex(data: str) -> str:
    return hashlib.sha256(data.encode()).hexdigest()


def canonical(obj) -> str:
    return json.dumps(
        obj,
        sort_keys=True,
        separators=(",", ":")
    )
تابع canonical مهم است: داده‌ای که Hash می‌شود باید همیشه با یک ترتیب ثابت Serialize شود تا همان داده، همیشه همان Hash را بدهد.

مرحله دوم — ساخت Transaction

هر تراکنش دو قسمت اصلی دارد: Inputs (کدام UTXOهای قبلی خرج می‌شوند) و Outputs (پول جدید مال کیست و چقدر):
mini_bitcoin.py — بخش ۲
from dataclasses import dataclass


@dataclass(frozen=True)
class TxInput:
    txid: str
    output_index: int


@dataclass(frozen=True)
class TxOutput:
    address: str
    amount: int


class Transaction:

    def __init__(self, inputs, outputs):
        self.inputs = inputs
        self.outputs = outputs

    def to_dict(self):
        return {
            "inputs": [
                {"txid": i.txid,
                 "output_index": i.output_index}
                for i in self.inputs
            ],
            "outputs": [
                {"address": o.address,
                 "amount": o.amount}
                for o in self.outputs
            ]
        }

    @property
    def txid(self) -> str:
        return sha256_hex(
            canonical(self.to_dict())
        )

مرحله سوم — ساخت Merkle Root

mini_bitcoin.py — بخش ۳
class Block:

    @staticmethod
    def calculate_merkle_root_from_txids(txids):
        if not txids:
            return sha256_hex("")

        level = txids[:]

        while len(level) > 1:

            if len(level) % 2 == 1:
                level.append(level[-1])  # اگر فرد بود، آخری تکرار می‌شود

            level = [
                sha256_hex(
                    level[i] + level[i + 1]
                )
                for i in range(0, len(level), 2)
            ]

        return level[0]

مرحله چهارم — ساخت Block و Header آن

هدر بلاک ما این اطلاعات را دارد: Index، Timestamp، Merkle Root، Previous Hash، Nonce — و Hash بلاک از همین هدر ساخته می‌شود:
mini_bitcoin.py — بخش ۴
class Block:

    def __init__(self, index, transactions,
                 previous_hash, timestamp=None):
        self.index = index
        self.timestamp = (
            time.time()
            if timestamp is None
            else timestamp
        )
        self.transactions = transactions
        self.previous_hash = previous_hash
        self.nonce = 0
        self.merkle_root = (
            self.calculate_merkle_root()
        )
        self.hash = ""

    def header_dict(self):
        return {
            "index": self.index,
            "timestamp": self.timestamp,
            "merkle_root": self.merkle_root,
            "previous_hash": self.previous_hash,
            "nonce": self.nonce
        }

    def calculate_hash(self):
        return sha256_hex(
            canonical(self.header_dict())
        )

مرحله پنجم — Mining

حالا قسمت جذاب ماجرا. با difficulty = 3، Hash باید با 000 شروع شود:
mini_bitcoin.py — بخش ۵
def mine(self, difficulty):
    target = "0" * difficulty

    while True:
        self.hash = self.calculate_hash()

        if self.hash.startswith(target):
            return  # بلاک معتبر پیدا شد!

        self.nonce += 1
این حلقه دقیقاً همان ایده‌ای است که توضیح دادیم: nonce را 0 و 1 و 2 و ... امتحان کن تا Hash شرایط هدف را برآورده کند. در شبکه واقعی بیت‌کوین، سختی استخراج بسیار فراتر از چند صفر آموزشی است و با هدف نگه‌داشتن نرخ تولید بلاک‌ها تنظیم می‌شود.

مرحله ششم — استفاده واقعی از UTXO Set

برای فهمیدن اینکه چه پولی هنوز خرج نشده، یک دیکشنری به شکل (txid, output_index) → output نگه می‌داریم. وقتی Alice یک خروجی را خرج می‌کند، از مجموعه حذف و خروجی‌های جدید اضافه می‌شوند:
قبل
("abc123...", 0) → Alice : 100
بعد
("def456...", 0) → Bob : 30
("def456...", 1) → Alice : 70

# موتور اصلی: کیف پول، استخراج و اعتبارسنجی کامل

حالا قطعات را در کلاس MiniBitcoin کنار هم می‌گذاریم. این کلاس مجموعه UTXO را از روی زنجیره بازسازی می‌کند، پرداخت می‌سازد (با باقی‌پول خودکار)، تراکنش‌های در انتظار را با پاداش Coinbase استخراج می‌کند و کل زنجیره را به‌طور کامل اعتبارسنجی می‌کند — شامل تشخیص Double Spend:
mini_bitcoin.py — بخش ۶ (کیف پول و استخراج)
class MiniBitcoin:

    def __init__(self, difficulty=3, reward=50,
                 genesis_address="Alice",
                 genesis_amount=100):
        self.difficulty = difficulty
        self.reward = reward

        genesis_tx = Transaction(
            [],
            [TxOutput(genesis_address, genesis_amount)]
        )

        self.genesis = Block(
            0, [genesis_tx], "0" * 64,
            timestamp=0
        )
        self.genesis.hash = (
            self.genesis.calculate_hash()
        )

        self.chain = [self.genesis]
        self.pending = []

    def _utxos(self):
        # کل زنجیره را دوباره پخش می‌کنیم و
        # مجموعه خروجی‌های خرج‌نشده را می‌سازیم.
        utxos = {}

        for block in self.chain:
            for tx in block.transactions:

                for tx_input in tx.inputs:
                    key = (tx_input.txid,
                           tx_input.output_index)
                    utxos.pop(key, None)  # خرج شد

                for index, output in enumerate(tx.outputs):
                    utxos[(tx.txid, index)] = output

        return utxos

    def balance(self, address):
        return sum(
            output.amount
            for output in self._utxos().values()
            if output.address == address
        )

    def create_payment(self, sender, recipient, amount):
        if amount <= 0:
            raise ValueError("amount must be positive")

        utxos = [(key, output)
                 for key, output
                 in self._utxos().items()
                 if output.address == sender]

        total = 0
        inputs = []

        for (txid, index), output in utxos:
            inputs.append(TxInput(txid, index))
            total += output.amount
            if total >= amount:
                break

        if total < amount:
            raise ValueError("insufficient funds")

        outputs = [TxOutput(recipient, amount)]

        change = total - amount
        if change:
            outputs.append(TxOutput(sender, change))

        tx = Transaction(inputs, outputs)
        self.pending.append(tx)
        return tx

    def mine_pending(self, miner_address):
        # Coinbase: تراکنش پاداش ماینر
        reward_tx = Transaction(
            [], [TxOutput(miner_address, self.reward)]
        )

        block = Block(
            len(self.chain),
            [reward_tx] + self.pending,
            self.chain[-1].hash
        )

        self._validate_candidate_block(block)
        block.mine(self.difficulty)

        self.chain.append(block)
        self.pending = []
        return block
و قوانین اعتبارسنجی — نزدیک‌ترین چیز در برنامه کوچک ما به قوانین اجماع:
mini_bitcoin.py — بخش ۷ (اعتبارسنجی)
    def _validate_candidate_block(self, block):
        if block.index != len(self.chain):
            raise ValueError("invalid block index")

        if block.previous_hash != self.chain[-1].hash:
            raise ValueError("invalid previous hash")

        if block.merkle_root != block.calculate_merkle_root():
            raise ValueError("invalid merkle root")

        # اولین تراکنش باید Coinbase باشد (بدون ورودی)
        if block.transactions[0].inputs:
            raise ValueError(
                "first transaction must be coinbase"
            )

        utxos = self._utxos()
        spent_in_block = set()

        for tx in block.transactions[1:]:
            input_total = 0

            for tx_input in tx.inputs:
                key = (tx_input.txid, tx_input.output_index)

                if key in spent_in_block:
                    raise ValueError("double spend detected")

                if key not in utxos:
                    raise ValueError("missing UTXO")

                spent_in_block.add(key)
                input_total += utxos[key].amount

            output_total = sum(
                o.amount for o in tx.outputs
            )

            if output_total > input_total:
                raise ValueError("outputs exceed inputs")

        return True
متد is_valid() کل زنجیره را با همین قوانین پیمایش می‌کند — بررسی Genesis، هش هدرها، Proof of Work، Coinbase و پخش مجدد همه UTXOها — و یک بولین برمی‌گرداند. از آن برای آزمایش دستکاری استفاده خواهیم کرد.

# حالا واقعاً از آن استفاده کنیم

run.py
coin = MiniBitcoin(difficulty=3, reward=50)

print(coin.balance("Alice"))
# 100  (بلاک پیدایش به Alice صد واحد داد)

coin.create_payment("Alice", "Bob", 30)
# تراکنش وارد pending می‌شود — هنوز داخل زنجیره نیست

block = coin.mine_pending("Miner")
# ماینر بلاک می‌سازد، Proof of Work انجام می‌دهد، بلاک را اضافه می‌کند

print(coin.balance("Alice"))  # 70
print(coin.balance("Bob"))    # 30
print(coin.balance("Miner"))  # 50
ماینر دقیقاً چه کار کرد؟ تقریباً این اتفاق افتاد:
1
تراکنش‌های در انتظار — Alice → Bob : 30
2
+ Coinbase — Miner : 50
3
Merkle Root — خلاصه‌سازی تراکنش‌ها
4
Proof of Work — پیدا کردن Nonce
5
افزودن — بلاک به زنجیره می‌پیوندد
چرا ماینر پول می‌گیرد؟ اگر قرار باشد افراد برای ساخت بلاک‌ها هزینه محاسباتی واقعی صرف کنند، باید انگیزه‌ای هم وجود داشته باشد. در بیت‌کوین، اولین تراکنش هر بلاک یک Coinbase Transaction است که پاداش بلاک (به‌علاوه کارمزدها) را به ماینر تعلق می‌دهد. در بیت‌کوین واقعی قواعد بسیار دقیق‌ترند — مثلاً Coinbase واقعی حداقل ۱۰۰ بلاک قابل خرج شدن نیست.

# قسمت جالب: اگر بلاک را دستکاری کنیم چه می‌شود؟

فرض کنید کسی پرداخت Alice → Bob : 30 را تبدیل کند به Alice → Bob : 999. داده تراکنش تغییر کرد → txid تغییر می‌کند → Merkle Root تغییر می‌کند → Hash بلاک تغییر می‌کند → بلاک دیگر معتبر نیست:
tamper_test.py
print("Valid:", coin.is_valid())
# Valid: True

# کسی بی‌سروصدا تاریخچه را بازنویسی می‌کند:
coin.chain[1].transactions[1].outputs[0] = (
    TxOutput("Bob", 999)
)

print("Valid:", coin.is_valid())
# Valid: False
و دستکاری یک بلاک به‌تنهایی هم کافی نیست. بلاک ۲ هنوز Previous Hash = هش قدیمی بلاک ۱ را نگه داشته است. مهاجم باید بلاک ۱ را دوباره استخراج کند، بعد بلاک ۲، بعد همه بلاک‌های بعدی — یعنی همه Proof of Workها را دوباره انجام دهد. زنجیره‌کردن Hashها همراه با Proof of Work دقیقاً چیزی است که هزینه تغییر تاریخچه را بالا می‌برد.
یک سوءتفاهم معروف: بلاک‌چین جادو نیست. این‌طور نیست که «چون اطلاعات روی بلاک‌چین است، دیگر مطلقاً غیرقابل تغییر است» — ساختار آن به شکلی طراحی شده که تغییر تاریخچه هزینه محاسباتی داشته باشد و نودها هم بلاک‌های نامعتبر را نمی‌پذیرند. در بیت‌کوین، نودها بلاک را با قوانین اجماع خودشان اعتبارسنجی می‌کنند و زنجیره دارای بیشترین میزان Proof of Work انباشته را دنبال می‌کنند.

# هنوز یک چیز خیلی مهم کم داریم: رمزنگاری و شبکه

در کد ما، مالکیت چیزی بیشتر از رشته address = "Alice" نیست. اگر کسی ادعا کند Alice است، برنامه ما حرفش را قبول می‌کند. در دنیای واقعی این کافی نیست — و اینجاست که کلید خصوصی، کلید عمومی و امضای دیجیتال وارد می‌شوند:
کلید خصوصی
امضای دیجیتال
تراکنش
شبکه بررسی می‌کند
نوشتن اسم «Alice» کافی نیست
تفاوت بزرگ دیگر این است که برنامه ما روی یک کامپیوتر اجرا می‌شود. اما بیت‌کوین فقط یک برنامه نیست — یک شبکه از Nodeها است. تراکنش‌ها منتشر می‌شوند، نودها بررسیشان می‌کنند، ماینرها بلاک می‌سازند و بلاک پیدا‌شده دوباره منتشر می‌شود. هر نود مستقلاً چک می‌کند: Hash درست است؟ Proof of Work درست است؟ تراکنش‌ها معتبرند؟ Double Spend وجود دارد؟ Previous Hash درست است؟ فقط بعد از آن: قبول.
بررسی Hash
  • هش بلاک با هدر می‌خواند
بررسی PoW
  • هش به هدف سختی رسیده
بررسی اتصال
  • Previous Hash درست است
خرج دوباره
  • هیچ خروجی‌ای دوبار خرج نشده

# بیت‌کوین یک پشته از ایده‌هاست، نه یک اختراع واحد

اگر کل سیستم را باز کنیم، دیگر با یک «بلاک‌چین» ساده طرف نیستیم — چند قطعه روی هم قرار گرفته‌اند:
شبکه P2P
هزاران نود، بدون مرکز
C
قوانین اجماع
اعتبارسنجی مستقل توسط هر نود
W
Proof of Work
هزینه محاسباتی برای تولید بلاک
M
Merkle Tree
خلاصه فشرده تراکنش‌های بلاک
B
بلاک‌ها
ظرف‌های زنجیرشده تراکنش‌ها
U
تراکنش و UTXO
مالکیت به شکل خروجی‌های خرج‌نشده
T
کیف پول
کلیدها و امضاها — اثبات مالکیت
پس چیزی که ما ساختیم کجای بیت‌کوین قرار می‌گیرد؟ این هم مقایسه صادقانه:
قابلیت نمونه ما Bitcoin واقعی
Block
Previous Hash
SHA-256
Merkle Root
Proof of Work
پاداش استخراج
UTXO
بررسی Double Spend
امضای دیجیتال
کلید خصوصی/عمومی
شبکه P2P
اجماع کاملساده‌شده
Bitcoin Script
تنظیم سختی واقعی
کارمزد تراکنش
چیزی که ساختیم هسته آموزشی ایده است، نه پیاده‌سازی کامل پروتکل بیت‌کوین. و این تفاوت بسیار مهم است.

# چرا ساختن یک نمونه کوچک ارزش دارد؟

چون وقتی فقط بگوییم «بیت‌کوین یک ارز دیجیتال مبتنی بر بلاک‌چین است»، تقریباً هیچ چیز یاد نگرفته‌ایم. اما وقتی با چشم خودمان ببینیم که یک تراکنش UTXO جدید می‌سازد، وارد Merkle Root می‌شود، در یک بلاک استخراج می‌شود و لحظه‌ای که کسی دستکاری‌اش کند کل زنجیره می‌شکند — مفهوم ناگهان کاملاً روشن می‌شود.
SHA-256 به‌تنهایی چیز خارق‌العاده‌ای نیست. Hash Chain به‌تنهایی چیز جدیدی نیست. امضای دیجیتال به‌تنهایی پول دیجیتال نیست. شبکه P2P به‌تنهایی بلاک‌چین نیست. Proof of Work به‌تنهایی بیت‌کوین نیست. اما وقتی این قطعات با قوانین دقیق کنار هم قرار می‌گیرند، سیستمی شکل می‌گیرد که می‌تواند بدون بانک مرکزی، یک دفتر تراکنش عمومی و قابل‌اعتبارسنجی نگه دارد. این همان بخش جذاب مهندسی بیت‌کوین است:
گاهی یک فناوری انقلابی از اختراع یک قطعه عجیب ساخته نمی‌شود؛ از کنار هم گذاشتن قطعاتی ساخته می‌شود که قبلاً وجود داشته‌اند، اما کسی آن‌ها را به این شکل کنار هم قرار نداده بود.
takeaway.txt
قدرت بیت‌کوین در قطعاتش نیست؛
در کنار هم قرار گرفتن آن‌هاست.
اجزای ساده + قوانین دقیق = سیستمِ پیچیده