> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# كيف تتفق شبكة البلوكتشين؟ إثبات العمل وإثبات الحصة
- URL: https://arabroot.io/articles/الاجماع-في-البلوكتشين-اثبات-العمل-واثبات-الحصة/
- Published: 2026-10-09T13:30:00.000Z
- Updated: 2026-10-14T07:41:32.000Z
- Description: كيف تتفق آلاف العقد التي لا يثق بعضها ببعض على سجل واحد، ولماذا يكلف الغش كهرباء في شبكة ومالاً محجوزاً في أخرى.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, مجالات متخصصة, الاستضافة الذاتية

في [مقال البلوكتشين للمبتدئين](https://arabroot.io/articles/%D8%A7%D9%84%D8%A8%D9%84%D9%88%D9%83%D8%AA%D8%B4%D9%8A%D9%86-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84-%D9%88%D9%85%D8%AA%D9%89-%D9%84%D8%A7-%D8%AA%D8%AD%D8%AA%D8%A7%D8%AC%D9%87/#consensus) مررنا على الإجماع Consensus مروراً سريعاً: لغز حسابي في Bitcoin، ومال محجوز في Ethereum، وتصويت بين أعضاء معروفين في الشبكات الخاصة، ونفذنا هناك تعدين كتلة بعدد أصفار متزايد. ولكن بقيت أسئلة مهمة دون إجابة كاملة: من يحدد صعوبة اللغز ولماذا لا يصبح أسهل كلما زادت الأجهزة؟ وكم كتلة يجب أن تنتظر حتى تطمئن أن الدفعة لن تختفي؟ وماذا يحدث فعلاً عندما يملك طرف واحد أغلب قوة التعدين؟ وما معنى أن الكتلة أصبحت «نهائية» في Ethereum؟ وهذا المقال هو الثاني في [مرحلة البلوكتشين](https://arabroot.io/start/#stage-blockchain) من خريطة الطريق، ويجيب عن هذه الأسئلة بالأوراق الأصلية وبكود صغير تشغله على جهازك.

وهذا المقال تعليمي تقني فقط، ولا يتضمن أي نصيحة استثمارية أو مالية، ولا يروج لأي عملة أو رمز Token، وكل الأمثلة فيه تعمل على جهازك دون أي مال حقيقي.

وسوف نناقش في هذا المقال ما يلي:

- لماذا يختلف الإجماع بين سيرفرات تثق ببعضها عن الإجماع بين غرباء، ومشكلة الجنرالات البيزنطيين Byzantine Generals Problem.
- إثبات العمل Proof of Work من الداخل: الهدف Target والصعوبة Difficulty، والتحقق من رأس كتلة حقيقية من شبكة Bitcoin بأنفسنا.
- تعديل الصعوبة Difficulty Adjustment بتجربة حقيقية، ولماذا يستهلك إثبات العمل كل هذه الكهرباء.
- هجوم 51% 51% Attack بالأرقام من ورقة Bitcoin، وحادثة موثقة.
- إثبات الحصة Proof of Stake في Ethereum: الخانات والحقب والنهائية Finality والمصادرة Slashing.
- خوارزميات BFT في الشبكات الخاصة، ومتى يكفيك Raft.

## المشكلة: الاتفاق عندما يكذب بعض الأطراف

في [مقال الأنظمة الموزعة](https://arabroot.io/articles/%D8%A7%D9%84%D8%A7%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D9%88%D8%B2%D8%B9%D8%A9-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-cap-%D9%88%D8%A7%D9%84%D8%A7%D8%AA%D8%B3%D8%A7%D9%82-%D9%88%D8%A7%D9%84%D8%A7%D8%AC%D9%85%D8%A7%D8%B9/#consensus) شرحنا كيف تتفق ثلاثة سيرفرات etcd على قيمة واحدة بخوارزمية Raft، وهناك افتراض مهم كان مخفياً في كل الأمثلة: أن السيرفر قد يتوقف أو ينقطع عن الشبكة، ولكنه لا يكذب، وهذا ما يسمى عطل التوقف Crash Fault. وهذا افتراض معقول عندما تملك أنت السيرفرات الثلاثة، فالسيرفر المعطل لا يرسل شيئاً، وأي رسالة تصلك منه صحيحة.

ولكن في شبكة عامة يشارك فيها من لا تعرفه، قد يرسل أحد الأطراف لسيرفر رسالة «نفذ المعاملة» ولسيرفر آخر «ألغها»، وهذا ما يسمى العطل البيزنطي Byzantine Fault، وقد سماه بهذا الاسم Leslie Lamport وRobert Shostak وMarshall Pease في ورقة [The Byzantine Generals Problem](https://lamport.azurewebsites.net/pubs/byz.pdf?ref=arabroot.io) سنة 1982\. وصورة الورقة جنرالات يحاصرون مدينة ويتواصلون بالرسل، وبعضهم خونة، والمطلوب أن يتفق المخلصون على خطة واحدة. وأثبتت الورقة أنه مع الرسائل الشفهية، أي الرسائل التي يستطيع الخائن تزويرها، لا يوجد حل مع ثلاثة جنرالات أحدهم خائن، وأن الحل ممكن فقط إذا كان أكثر من ثلثي الجنرالات مخلصين، أي تحتاج 3f + 1 عضواً لتتحمل f كاذبين. والصورة التالية تضع النوعين جنباً إلى جنب:

![مخطط من جزأين: على اليمين عطل التوقف في Raft وetcd حيث سيرفران يوافقان والثالث صامت فيكفي اثنان من ثلاثة، ويتحمل النظام f أعطال بـ 2f+1 سيرفرات، وعلى اليسار العطل البيزنطي من ورقة Lamport سنة 1982 حيث خائن يرسل لأحد الجنرالين هجوم وللآخر انسحاب، فمع ثلاثة جنرالات لا يمكن الاتفاق، ومع أربعة يقارن المخلصون ما سمعوه فتغلب الأغلبية، ويتحمل النظام f كاذبين بـ 3f+1 أعضاء](https://arabroot.io/content/images/2026/10/consensus-01-faults.webp)

عطل التوقف يكفيه 2f + 1، والعطل البيزنطي يحتاج 3f + 1

والبلوكتشين العام يواجه مشكلة أصعب من ذلك، فهو لا يعرف أصلاً كم عضواً في الشبكة، وأي شخص يستطيع أن يشغل ألف عقدة بأسماء مختلفة ليكسب التصويت، وهذا ما يسمى هجوم Sybil كما ذكرنا في المقال الأول. ولذلك لا يصلح أن يكون الصوت لكل عقدة، والحل أن يكون الصوت لشيء مكلف لا يمكن نسخه مجاناً: الكهرباء في إثبات العمل، أو المال المحجوز في إثبات الحصة.

## إثبات العمل Proof of Work من الداخل

الفكرة كما في [ورقة Bitcoin](https://bitcoin.org/bitcoin.pdf?ref=arabroot.io) أن حق إضافة الكتلة التالية لمن يجد أولاً رقماً اسمه Nonce يجعل هاش رأس الكتلة Block Header أصغر من هدف Target محدد، ولا توجد طريقة لإيجاده إلا التجربة رقماً بعد رقم، أما التحقق من الحل فهو حساب هاش واحد. وفي المقال الأول عبرنا عن الهدف بعدد الأصفار في بداية الهاش لأنه أسهل للفهم، ولكن Bitcoin لا يعد الأصفار، وإنما يقارن الهاش كرقم من 256 بت بالهدف كرقم.

### الهدف Target والصعوبة Difficulty في كتلة حقيقية

رأس الكتلة في Bitcoin 80 بايت بالضبط: رقم الإصدار، وهاش الكتلة السابقة، وهاش شجرة Merkle للمعاملات Merkle Root، والوقت، والحقل `bits` الذي يحمل الهدف بصيغة مضغوطة، ثم الـ Nonce. والهاش المستخدم هو SHA-256 مرتين. ولكي لا نصدق ذلك بالكلام فقط، سوف نتحقق بأنفسنا من كتلتين حقيقيتين: الكتلة الأولى Genesis Block التي نأخذ قيمها من الملف [chainparams.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/kernel/chainparams.cpp?ref=arabroot.io) في Bitcoin Core، والكتلة رقم 840,000 من أبريل 2024 التي نأخذ رأسها الخام من [mempool.space](https://mempool.space/block/0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5?ref=arabroot.io) بالأمر `curl https://mempool.space/api/block/<hash>/header`. احفظ الكود التالي باسم `verify_header.py`:

```python
import hashlib, struct

def dsha(b): return hashlib.sha256(hashlib.sha256(b).digest()).digest()
def bits_to_target(bits):
    exp, mant = bits >> 24, bits & 0xFFFFFF
    return mant * (1 << (8 * (exp - 3)))

MAX = bits_to_target(0x1d00ffff)       # difficulty 1, the genesis target

def check(name, header, expected):
    assert len(header) == 80
    version, prev, merkle, ts, bits, nonce = struct.unpack("<I32s32sIII", header)
    h = dsha(header)[::-1].hex()        # shown in reverse byte order
    target = bits_to_target(bits)
    print(f"{name}: time={ts} bits={bits:#010x} nonce={nonce}")
    print(f"  hash     {h}")
    print(f"  matches  {h == expected}")
    print(f"  target   {target:064x}")
    print(f"  hash <= target: {int(h, 16) <= target}   difficulty={MAX / target:,.0f}")
    return target

# Genesis block: values from Bitcoin Core src/kernel/chainparams.cpp
genesis = struct.pack("<I32s32sIII", 1, bytes(32),
    bytes.fromhex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")[::-1],
    1231006505, 0x1d00ffff, 2083236893)
check("genesis", genesis, "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")

# Block 840,000 (April 2024): the raw 80-byte header from mempool.space/api/block/<hash>/header
raw = bytes.fromhex("00e05f2aab948491071265ad552351d0ad625745668da54b0172010000000000000000004f89a5d73bd4d4887f25981fe81892ccafda10c27f52d6f3dd28183a7c411b03b7072366194203177d9863ea")
t = check("block 840000", raw, "0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5")

# Change one bit of the nonce: the work no longer counts
bad = raw[:-1] + bytes([raw[-1] ^ 1])
hb = dsha(bad)[::-1].hex()
print(f"tampered nonce -> {hb}  valid: {int(hb, 16) <= t}")

expected_hashes = 2**256 / (t + 1)
print(f"expected hashes per block at 840000: {expected_hashes:.3e}")
print(f"implied network rate (/600 s): {expected_hashes / 600 / 1e18:,.0f} EH/s")
```

ثم شغله داخل Container مؤقت حتى لا تحتاج تثبيت Python على جهازك:

```bash
docker run --rm --name lab-consensus-py -v "$PWD:/lab" -w /lab python:3.13.16-slim python verify_header.py
```

والمخرج سوف يكون كما يلي:

```text
genesis: time=1231006505 bits=0x1d00ffff nonce=2083236893
  hash     000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
  matches  True
  target   00000000ffff0000000000000000000000000000000000000000000000000000
  hash <= target: True   difficulty=1
block 840000: time=1713571767 bits=0x17034219 nonce=3932395645
  hash     0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5
  matches  True
  target   0000000000000000000342190000000000000000000000000000000000000000
  hash <= target: True   difficulty=86,388,558,925,171
tampered nonce -> 8d9639beeb2331ae923f33c777c3e308a69276aee5c97ad6c481ae616cba59cf  valid: False
expected hashes per block at 840000: 3.710e+23
implied network rate (/600 s): 618 EH/s
```

في المخرج أعلاه لاحظ التالي:

- الهاش الذي حسبناه يطابق الهاش المسجل في Bitcoin Core للكتلة الأولى، والهاش المنشور للكتلة 840,000، أي أن أي شخص يستطيع أن يتحقق من العمل دون أن يثق بأحد.
- الحقل `bits` صيغة مضغوطة للهدف: البايت الأول أس Exponent والبايتات الثلاثة الباقية هي الرقم Mantissa، والهدف = الرقم × 256 مرفوعاً للأس ناقص 3، وهذا ما تفعله الدالة `bits_to_target`.
- الصعوبة Difficulty ليست حقلاً في الكتلة، وإنما نسبة بين أسهل هدف مسموح، وهو هدف الكتلة الأولى، والهدف الحالي، فالكتلة الأولى صعوبتها 1، والكتلة 840,000 صعوبتها قرابة 86 تريليون.
- عندما غيرنا بتاً واحداً في الـ Nonce أصبح الهاش مختلفاً تماماً وأكبر من الهدف، فالكتلة لم تعد صالحة، ولذلك لا يستطيع أحد أن يعدل كتلة قديمة دون أن يعيد العمل كله.
- من الهدف نحسب عدد المحاولات المتوقع لإيجاد كتلة واحدة: قرابة 3.7 × 1023 هاش، وبقسمته على 600 ثانية نحصل على تقدير لقوة الشبكة وقتها قرابة 618 إكسا هاش في الثانية EH/s، وهو تقدير حسابي من الهدف وليس قياساً.

ولكي تحس بهذا الرقم، قسنا كم هاش مزدوجاً يحسبه Python في نفس الـ Container على نواة معالج واحدة بالملف `rate.py`:

```python
import hashlib, time
n, end = 0, time.perf_counter() + 3
while time.perf_counter() < end:
    hashlib.sha256(hashlib.sha256(f"block:{n}".encode()).digest()).digest()
    n += 1
rate = n / 3
print(f"double SHA-256 per second here: {rate:,.0f}")
years = 3.710e23 / rate / (365 * 24 * 3600)
print(f"years to expect one block at height 840000: {years:.2e}")
```

```text
double SHA-256 per second here: 196,266
years to expect one block at height 840000: 5.99e+10
```

أي قرابة 60 مليار سنة لكتلة واحدة، وهذا الرقم للتوضيح فقط لأن أجهزة التعدين الحقيقية شرائح ASIC مصممة لهذا الهاش وحده وأسرع من Python بمراتب كثيرة، ولكنه يوضح لماذا لم يعد التعدين على الحاسوب العادي له معنى.

### تعديل الصعوبة Difficulty Adjustment

لو بقي الهدف ثابتاً لأصبحت الكتل أسرع كلما دخلت أجهزة جديدة، ولذلك يعدل Bitcoin الهدف كل 2016 كتلة كما في الدالة `CalculateNextWorkRequired` في الملف [pow.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/pow.cpp?ref=arabroot.io): يقيس الوقت الذي استغرقته هذه الكتل فعلاً، ويقارنه بأسبوعين، أي 2016 × 10 دقائق، ثم يضرب الهدف القديم في النسبة بينهما، فإذا جاءت الكتل أسرع صغر الهدف وصعب اللغز، وإذا جاءت أبطأ كبر الهدف وسهل. وفي نفس الدالة قيد مهم: الوقت المقاس لا يقل عن ربع الأسبوعين ولا يزيد على أربعة أضعافهما، فلا يتغير الهدف في مرة واحدة أكثر من أربعة أضعاف في أي اتجاه.

ولكي نرى ذلك يعمل، كتبنا سلسلة صغيرة بنفس القاعدة ولكن بأرقام تناسب حاسوباً: الهدف 0.2 ثانية للكتلة بدل 10 دقائق، والتعديل كل 40 كتلة بدل 2016، ونبدأ بهدف سهل جداً، وفي الفترة السابعة نجعل كل محاولة تكلف هاشين بدل هاش واحد، وكأن نصف أجهزة التعدين غادرت الشبكة. احفظ الكود باسم `retarget.py`:

```python
import hashlib, time

MAX_TARGET = 2**256 - 1
TARGET_SPACING = 0.2          # seconds we want between blocks (Bitcoin: 600)
INTERVAL = 40                 # blocks between adjustments (Bitcoin: 2016)

def mine(prev, target, work=1):
    nonce = 0
    while True:
        data = f"{prev}:{nonce}".encode()
        h = hashlib.sha256(data).digest()
        for _ in range(work - 1):          # work=2 simulates half the hash power
            h = hashlib.sha256(h).digest()
        if int.from_bytes(h, "big") <= target:
            return nonce, h.hex()
        nonce += 1

target = MAX_TARGET // 1_000          # start easy: about 1,000 tries per block
prev, height, work = "genesis", 0, 1
for period in range(1, 11):
    if period == 7:
        work = 2
        print("---- half of the miners leave (each try now costs two hashes) ----")
    start = time.perf_counter()
    for _ in range(INTERVAL):
        nonce, prev = mine(prev, target, work)
        height += 1
    actual = time.perf_counter() - start
    expected = INTERVAL * TARGET_SPACING
    ratio = min(max(actual / expected, 0.25), 4.0)   # same clamp as Bitcoin's pow.cpp
    print(f"period {period}: height={height:3d} difficulty={MAX_TARGET // target:>9,d} "
          f"avg block={actual / INTERVAL:6.3f}s  -> new target x{ratio:.2f}")
    target = min(int(target * ratio), MAX_TARGET)
```

```bash
docker run --rm --name lab-consensus-py --cpus 1 -v "$PWD:/lab" -w /lab python:3.13.16-slim python retarget.py
```

والمخرج كما ظهر لنا، والأوقات للتوضيح فقط وتختلف من جهاز لآخر ومن مرة لأخرى:

```text
period 1: height= 40 difficulty=    1,000 avg block= 0.007s  -> new target x0.25
period 2: height= 80 difficulty=    3,999 avg block= 0.027s  -> new target x0.25
period 3: height=120 difficulty=   15,999 avg block= 0.061s  -> new target x0.30
period 4: height=160 difficulty=   52,672 avg block= 0.275s  -> new target x1.37
period 5: height=200 difficulty=   38,338 avg block= 0.219s  -> new target x1.10
period 6: height=240 difficulty=   34,963 avg block= 0.190s  -> new target x0.95
---- half of the miners leave (each try now costs two hashes) ----
period 7: height=280 difficulty=   36,846 avg block= 0.283s  -> new target x1.42
period 8: height=320 difficulty=   26,028 avg block= 0.161s  -> new target x0.80
period 9: height=360 difficulty=   32,379 avg block= 0.118s  -> new target x0.59
period 10: height=400 difficulty=   54,745 avg block= 0.184s  -> new target x0.92
```

والصورة التالية ترسم نفس الأرقام بجانب قاعدة Bitcoin:

![مخطط من جزأين: على اليسار متوسط وقت الكتلة في سلسلتنا التجريبية لعشر فترات مقابل الهدف 0.2 ثانية، يبدأ قريباً من الصفر بصعوبة 1000 ثم 3999 ثم 15999 ثم يقفز فوق الهدف عند 52672، ثم يقترب منه، وفي الفترة السابعة يرتفع عندما يغادر نصف أجهزة التعدين ثم يعود، وعلى اليمين قاعدة Bitcoin من pow.cpp: كل 2016 كتلة يقاس الوقت الفعلي ويضرب الهدف القديم في الوقت الفعلي مقسوماً على المتوقع، مع حد أقصى أربعة أضعاف في الاتجاهين، والهدف كتلة كل عشر دقائق](https://arabroot.io/content/images/2026/10/consensus-02-difficulty.webp)

الصعوبة تلحق بقوة التعدين بعد فترة، ولا تتغير في المرة الواحدة أكثر من أربعة أضعاف

في المخرج أعلاه لاحظ التالي:

- في الفترتين الأولى والثانية كانت الكتل أسرع من الهدف بكثير، ولكن الهدف لم يصغر إلا إلى الربع في كل مرة بسبب القيد، فاحتاجت الشبكة ثلاث فترات حتى تلحق بقوة الجهاز.
- في الفترة الرابعة تجاوز التصحيح الهدف فأصبحت الكتل أبطأ، ثم عادت الصعوبة فنزلت، فالقاعدة تصحح نفسها بعد كل فترة ولا تصيب الهدف من أول مرة.
- عندما غادر نصف أجهزة التعدين في الفترة السابعة ارتفع متوسط الكتلة إلى 0.283 ثانية، فخفضت القاعدة الصعوبة من 36,846 إلى 26,028، وعادت الكتل أسرع من الهدف.
- الأوقات لا تستقر تماماً على 0.2 ثانية، والسبب أن إيجاد الـ Nonce حظ، فعدد المحاولات يختلف من كتلة لأخرى، و40 كتلة في الفترة عدد صغير، ولذلك يستخدم Bitcoin فترة 2016 كتلة.

### لماذا يستهلك إثبات العمل كل هذه الكهرباء؟

وقد يتساءل البعض: لماذا لا يجعل المطورون اللغز أخف فيوفروا الكهرباء؟ والإجابة أن تعديل الصعوبة يلغي أي توفير، فإذا جاءت أجهزة أكثر كفاءة أو زاد عددها صعب اللغز تلقائياً حتى تعود الكتلة كل عشر دقائق، ولذلك لا يحدد استهلاك الكهرباء حجم المعاملات، وإنما يحدده كم يربح من يقوم بالتعدين، فهو يضيف أجهزة ما دام الربح أكبر من فاتورة الكهرباء. والأمان نفسه قائم على هذه التكلفة، فمن يريد إعادة كتابة الكتل يجب أن ينفق مثلها.

والمرجع المعروف لقياس هذا الاستهلاك هو [مؤشر Cambridge لاستهلاك Bitcoin للكهرباء CBECI](https://ccaf.io/cbnsi/cbeci?ref=arabroot.io) من مركز Cambridge Centre for Alternative Finance، وهو مؤشر يتحدث يومياً بتقدير أدنى وأعلى ومتوسط. وآخر أرقام نشرها المركز في تقرير مكتوب هي في [Cambridge Digital Mining Industry Report](https://www.jbs.cam.ac.uk/faculty-research/centres/alternative-finance/publications/cambridge-digital-mining-industry-report/?ref=arabroot.io) في أبريل 2025، وفيه أن استهلاك تعدين Bitcoin السنوي المقدر نما 17% في سنة واحدة إلى 138 تيراوات ساعة TWh، أي قرابة 0.54% من استهلاك الكهرباء في العالم. وهذه تقديرات بنماذج وليست عداداً، فخذها كترتيب حجم وليس رقماً دقيقاً، وارجع إلى صفحة المؤشر للرقم الحالي.

## هجوم 51% 51% Attack: ماذا يستطيع المهاجم فعلاً؟

عندما تظهر سلسلتان تتبع العقد السلسلة التي فيها أكبر عمل متراكم، وبالتالي من يملك أكثر من نصف قوة التعدين يستطيع أن يبني سلسلة سرية أسرع من الشبكة كلها ثم ينشرها، فتنتقل العقد إليها وتختفي الكتل التي كانت قبلها، وهذا ما يسمى إعادة التنظيم Reorganization أو Reorg. والصورة التالية تبين كيف يستخدم المهاجم ذلك ليصرف نفس المال مرتين Double Spending:

![مخطط هجوم 51% في أربع خطوات: المهاجم يدفع لمنصة تداول على السلسلة العامة، وفي نفس الوقت يعدن سلسلة سرية يرسل فيها نفس المال لنفسه، وتنتظر المنصة 12 تأكيداً ثم تدفع له، ثم ينشر المهاجم سلسلته السرية الأطول ذات الكتل الثلاث عشرة فتتبعها العقد لأنها أكبر عملاً وتختفي الدفعة، وفي الأسفل أرقام من القسم 11 في ورقة Bitcoin، وحادثة Bitcoin Gold في يناير 2020 حيث أزيلت 14 و15 كتلة](https://arabroot.io/content/images/2026/10/consensus-03-attack.webp)

المهاجم لا يسرق مال غيره، وإنما يلغي دفعته هو بعد أن يقبض مقابلها

لاحظ ما لا يستطيعه المهاجم: لا يستطيع أن يصرف من محفظة غيره، لأن ذلك يحتاج توقيعاً بمفتاح لا يملكه، ولا يستطيع أن ينشئ عملات خارج قواعد الشبكة، لأن كل عقدة ترفض الكتلة المخالفة مهما كان العمل فيها. والذي يستطيعه هو أن يعيد ترتيب الكتل الأخيرة، فيلغي دفعاته ويمنع معاملات غيره من الدخول.

### كم تأكيداً تنتظر؟ الحساب من الورقة الأصلية

في القسم 11 من ورقة Bitcoin حسب Satoshi Nakamoto احتمال أن يلحق مهاجم يملك نسبة q من قوة التعدين بالشبكة إذا كان متأخراً z كتلة، وكتب الدالة بلغة C. والكود التالي هو نفس الخطوات بلغة Python، احفظه باسم `attacker.py`:

```python
# Bitcoin whitepaper, section 11: chance an attacker with share q of the hash power
# ever catches up from z blocks behind.
# Same steps as the C function AttackerSuccessProbability in the paper.
from math import exp

def attacker_success(q, z):
    p = 1.0 - q
    lam = z * (q / p)
    s = 1.0
    for k in range(z + 1):
        poisson = exp(-lam)
        for i in range(1, k + 1):
            poisson *= lam / i
        s -= poisson * (1 - (q / p) ** (z - k))
    return s

for q, zs in ((0.1, range(0, 11)), (0.3, range(0, 51, 5))):
    print(f"q={q}")
    for z in zs:
        print(f"z={z:<3d} P={attacker_success(q, z):.7f}")

print("P < 0.001")
for q in (0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45):
    z = 0
    while attacker_success(q, z) >= 0.001:
        z += 1
    print(f"q={q:.2f}  z={z}")
```

```bash
docker run --rm --name lab-consensus-py -v "$PWD:/lab" -w /lab python:3.13.16-slim python attacker.py
```

```text
q=0.1
z=0   P=1.0000000
z=1   P=0.2045873
z=2   P=0.0509779
z=3   P=0.0131722
z=4   P=0.0034552
z=5   P=0.0009137
z=6   P=0.0002428
z=7   P=0.0000647
z=8   P=0.0000173
z=9   P=0.0000046
z=10  P=0.0000012
q=0.3
z=0   P=1.0000000
z=5   P=0.1773523
z=10  P=0.0416605
z=15  P=0.0101008
z=20  P=0.0024804
z=25  P=0.0006132
z=30  P=0.0001522
z=35  P=0.0000379
z=40  P=0.0000095
z=45  P=0.0000024
z=50  P=0.0000006
P < 0.001
q=0.10  z=5
q=0.15  z=8
q=0.20  z=11
q=0.25  z=15
q=0.30  z=24
q=0.35  z=41
q=0.40  z=89
q=0.45  z=340
```

وكل رقم في المخرج أعلاه يطابق الجداول المنشورة في الورقة حتى الخانة السابعة. ومنها نفهم ثلاثة أشياء: أن مهاجماً يملك 10% يكاد يستحيل أن يلحق بعد خمس كتل، وأن مهاجماً يملك 45% يحتاج أن تنتظر 340 كتلة حتى ينزل احتماله تحت 0.1%، وأن المعادلة كلها مبنية على أن المهاجم يملك أقل من النصف، فإذا ملك النصف أو أكثر فالورقة نفسها تقول إنه يلحق في النهاية باحتمال 1 مهما انتظرت. ولذلك فعدد التأكيدات Confirmations الآمن ليس رقماً ثابتاً، وإنما يعتمد على حجم الشبكة وعلى إمكانية أن يستأجر أحد قوة تعدين تفوقها.

📌

في 23 و24 يناير 2020 رصد فريق MIT Digital Currency Initiative هجومين على شبكة Bitcoin Gold، وهي شبكة إثبات عمل أصغر بكثير من Bitcoin، أزيلت فيهما 14 كتلة ثم 15 كتلة، وصرفت فيهما قرابة 7,170 BTG مرتين، أي قرابة 72 ألف دولار بأسعار ذلك اليوم، كما في [تقرير الفريق](https://gist.github.com/metalicjames/71321570a105940529e709651d0a9765?ref=arabroot.io) المنشور ضمن [مشروع رصد هجمات 51%](https://dci.mit.edu/51-attacks?ref=arabroot.io). وكانت منصة Binance تسمح بالسحب بعد 12 تأكيداً، فتجاوزها الهجومان، وقدر الفريق تكلفة كل هجوم بقرابة 0.2 BTC من استئجار قوة التعدين. والدرس أن التأكيدات لا تحميك إلا بقدر ما يكلف تجاوزها، وأن الشبكة الصغيرة التي يمكن استئجار قوة تعدين تفوقها لا تحميها عشرة تأكيدات أو عشرون.

## إثبات الحصة Proof of Stake في Ethereum

انتقلت Ethereum من إثبات العمل إلى إثبات الحصة في الحدث المعروف باسم The Merge يوم 15 سبتمبر 2022، وتذكر [صفحة The Merge](https://ethereum.org/en/roadmap/merge/?ref=arabroot.io) أن هذا خفض استهلاك الشبكة للطاقة بقرابة 99.95%، وتنقل [صفحة استهلاك الطاقة](https://ethereum.org/en/energy-consumption/?ref=arabroot.io) تقديراً آخر من CCRI بأكثر من 99.988%، والرقمان من نفس الموقع الرسمي بمنهجيتين مختلفتين، والنتيجة واحدة: لم يعد هناك سباق تعدين. وفكرة إثبات الحصة أن الصوت لا يأتي من الكهرباء وإنما من مال يحجزه المدقق Validator كضمان، وفي Ethereum يحجز 32 ETH ويشغل عميل التنفيذ وعميل الإجماع وعميل المدقق كما في [توثيق إثبات الحصة](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/?ref=arabroot.io)، وقد شرحنا هذه الأجزاء في المقال الأول.

### الخانات Slots والحقب Epochs

في إثبات العمل يتحدد وقت الكتلة بالصعوبة، أما في إثبات الحصة فالإيقاع ثابت: الزمن مقسم إلى خانات Slots مدة كل منها 12 ثانية، وكل 32 خانة حقبة Epoch، أي 6.4 دقائق. وفي كل خانة يختار البروتوكول مدققاً عشوائياً ليقترح الكتلة، ولجنة Committee من المدققين تصوت عليها بما يسمى الشهادة Attestation، وتقسم اللجان بحيث يصوت كل مدقق نشط مرة واحدة في كل حقبة.

### النهائية Finality: متى لا تعود الكتلة قابلة للإلغاء؟

في إثبات العمل لا توجد كتلة نهائية بالمعنى الحرفي، وإنما احتمال إلغاء يصغر مع كل كتلة كما رأينا في حساب الورقة. وأما Ethereum فتضيف فوق اختيار السلسلة آلية اسمها Casper the Friendly Finality Gadget، نشرها Vitalik Buterin وVirgil Griffith في [ورقة Casper FFG](https://arxiv.org/abs/1710.09437?ref=arabroot.io)، وتجمع معها قاعدة اختيار السلسلة LMD-GHOST في بروتوكول اسمه [Gasper](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/gasper/?ref=arabroot.io). والفكرة أن أول كتلة في كل حقبة نقطة تفتيش Checkpoint، فإذا صوت مدققون يملكون ثلثي المال المحجوز على زوج من نقاط التفتيش أصبحت الأحدث مبررة Justified وأصبحت الأقدم نهائية Finalized، والصورة التالية تبين ذلك:

![مخطط ثلاث حقب في Ethereum كل منها 32 خانة مدة كل خانة 12 ثانية أي 6.4 دقائق، وأول كتلة في كل حقبة نقطة تفتيش A وB وC، وعندما يصوت ثلثا المال المحجوز من A إلى B ثم من B إلى C تصبح A وB نهائيتين وC مبررة، وإلغاء كتلة نهائية يعني حرق ثلث كل المال المحجوز على الأقل، وفي الأسفل ثلاث طرق للمصادرة: اقتراح كتلتين لنفس الخانة، والتصويت لمرشحين لنفس الكتلة، والتصويت الذي يحيط بتصويت سابق، ثم حرق فوري وخروج إجباري لمدة 36 يوماً وعقوبة في اليوم 18 تكبر إذا عوقب كثيرون معاً، وعلى اليمين تسرب عدم النشاط بعد أربع حقب دون نهائية](https://arabroot.io/content/images/2026/10/consensus-04-finality.webp)

الكتلة النهائية لا تلغى إلا بحرق ثلث كل المال المحجوز على الأقل

ولماذا ثلث المال بالذات؟ لأن النهائية تحتاج ثلثي المال، فإذا ظهرت سلسلتان نهائيتان متعارضتان فلا بد أن ثلثاً على الأقل صوت للاثنتين، والتصويت المزدوج مخالفة تعاقب بالمصادرة كما سيأتي، ولذلك تقول صفحة Gasper إن إلغاء كتلة نهائية يحتاج أن يملك المهاجم ثلثي المال المحجوز، أو أن يحرق ثلثه على الأقل. ومن هذا التصميم نحسب أن الكتلة تصبح نهائية في الظروف العادية بعد حقبتين تقريباً، أي قرابة 12.8 دقيقة، وهذا حساب من الأرقام السابقة وليس قيمة ثابتة في التوثيق.

### المصادرة Slashing وتسرب عدم النشاط Inactivity Leak

يذكر [توثيق المكافآت والعقوبات](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/?ref=arabroot.io) ثلاث مخالفات فقط تؤدي إلى المصادرة، وكلها أفعال يصعب أن تحدث بالخطأ: أن يوقع المدقق كتلتين مختلفتين لنفس الخانة، أو يصوت لمرشحين اثنين لنفس الكتلة، أو يصوت تصويتاً يحيط بتصويت سابق له فيغير التاريخ. والعقوبة على مراحل: حرق فوري صغير، وفي مثال التوثيق 0.0078125 ETH لمدقق رصيده 32 ETH، ثم إخراج إجباري من الشبكة يستغرق 36 يوماً يتسرب فيها رصيده، ثم عقوبة إضافية في اليوم 18 تسمى عقوبة الارتباط Correlation Penalty تكبر كلما زاد عدد المدققين المعاقبين في نفس الفترة، وقد تصل إلى الرصيد كله. والفكرة أن المدقق المنفرد الذي أخطأ مرة يخسر قليلاً، أما الهجوم المنسق فيخسر أصحابه كل شيء.

وأما المدقق الغائب فلا يصادر ماله، وإنما يخسر المكافآت وغرامات صغيرة، إلا في حالة واحدة: إذا مرت أكثر من أربع حقب دون نهائية، بدأ تسرب عدم النشاط Inactivity Leak الذي يستنزف مال المدققين الغائبين تدريجياً حتى يعود الحاضرون ثلثي المال فتعود النهائية. ولو غاب ثلث الشبكة أو أكثر لما وصلت إلى النهائية أبداً بدون هذه الآلية.

### كم تحتاج لتهاجم إثبات الحصة؟

في إثبات العمل الرقم المهم هو 51%، أما في إثبات الحصة فهناك عدة عتبات تذكرها [صفحة الهجوم والدفاع](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/attack-and-defense/?ref=arabroot.io)، وكلها نسب من المال المحجوز:

| نسبة المال المحجوز | ما يستطيعه المهاجم                                                                           |
| ------------------ | -------------------------------------------------------------------------------------------- |
| 33%                | تأخير النهائية                                                                               |
| 34%                | تأخير النهائية، ونهائية مزدوجة Double Finality بشرط التحكم في توقيت الرسائل، مع حرق ماله كله |
| 51%                | ما سبق، مع حجب المعاملات Censorship والتحكم في الكتل القادمة                                 |
| 66%                | ما سبق، مع إعادة كتابة الكتل النهائية الماضية                                                |

ويذكر نفس التوثيق أن الدفاع الأخير في هذه الهجمات الكبيرة اجتماعي وليس تقنياً، أي أن يتفق مجتمع الشبكة خارج البروتوكول على اتباع السلسلة الصادقة وترك سلسلة المهاجم، وهذه نقطة يجب أن تعرفها قبل أن تعتمد على أي شبكة عامة في عملك.

## الشبكات الخاصة: BFT أم Raft؟

عندما يكون المشاركون معروفين ومعدودين، مثل خمس شركات في سلسلة توريد، لا يوجد هجوم Sybil أصلاً، لأن كل عقدة لها هوية وشهادة، وبالتالي لا نحتاج الكهرباء ولا المال المحجوز، ونعود إلى التصويت الكلاسيكي. والسؤال هنا سؤال واحد: هل تثق أن العقد قد تتوقف ولكنها لا تكذب؟

- إذا كانت كل العقد تحت إدارة جهة واحدة، أو تثق الجهات ببعضها في هذه النقطة، فإن Raft الذي شرحناه في [مقال الأنظمة الموزعة](https://arabroot.io/articles/%D8%A7%D9%84%D8%A7%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D9%88%D8%B2%D8%B9%D8%A9-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-cap-%D9%88%D8%A7%D9%84%D8%A7%D8%AA%D8%B3%D8%A7%D9%82-%D9%88%D8%A7%D9%84%D8%A7%D8%AC%D9%85%D8%A7%D8%B9/#raft) يكفي، وهو أبسط وأسرع ويحتاج 2f + 1 عقدة، وهو ما تستخدمه خدمة الترتيب في [Hyperledger Fabric](https://hyperledger-fabric.readthedocs.io/en/latest/orderer/ordering%5Fservice.html?ref=arabroot.io) افتراضياً.
- إذا كانت الجهات لا تثق ببعضها وقد تحاول إحداها الغش، فتحتاج خوارزمية من عائلة BFT، وأشهرها PBFT التي نشرها Miguel Castro وBarbara Liskov في [مؤتمر OSDI سنة 1999](https://www.usenix.org/conference/osdi-99/practical-byzantine-fault-tolerance?ref=arabroot.io)، وتمر كل عملية فيها بثلاث مراحل من الرسائل وتنتظر كل مرحلة 2f + 1 رسالة متطابقة من 3f + 1 عقدة. ومن أمثلتها اليوم QBFT في [Hyperledger Besu](https://docs.besu-eth.org/private-networks/concepts/poa?ref=arabroot.io) وخيار BFT في Fabric.

![مخطط من جزأين: على اليمين Raft حيث يرسل القائد الإدخال لأربعة تابعين ويثبته عندما تملكه الأغلبية ثلاثة من خمسة، وعلى اليسار BFT مثل PBFT وQBFT وSmartBFT بثلاث مراحل pre-prepare وprepare وcommit بين أربع عقد إحداها تكذب، وكل مرحلة تنتظر 2f+1 رسالة متطابقة، وفي الأسفل جدول عدد العقد: لتحمل عطل واحد يحتاج Raft ثلاث عقد وBFT أربعاً، ولعطلين خمساً وسبعاً، ولثلاثة سبعاً وعشراً](https://arabroot.io/content/images/2026/10/consensus-05-bft-raft.webp)

كل كاذب تتحمله يكلفك عقدة إضافية مقارنة بعطل التوقف

والنتيجة في الحالتين نهائية فورية بعد التصويت، فلا توجد تأكيدات تنتظرها كما في إثبات العمل، ولكن الثمن أن عدد العقد محدود، والسبب أن رسائل BFT تزيد بسرعة مع كل عقدة تضيفها، ولذلك تعمل هذه الشبكات بعشرات العقد وليس آلافها. ولماذا نختار ثلاثاً أو خمساً وليس أربعاً في Raft شرحناه في [قسم النصاب](https://arabroot.io/articles/%D8%A7%D9%84%D8%A7%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D9%88%D8%B2%D8%B9%D8%A9-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-cap-%D9%88%D8%A7%D9%84%D8%A7%D8%AA%D8%B3%D8%A7%D9%82-%D9%88%D8%A7%D9%84%D8%A7%D8%AC%D9%85%D8%A7%D8%B9/#quorum).

## مقارنة سريعة

|                      | إثبات العمل              | إثبات الحصة                 | BFT                   | Raft                   |
| -------------------- | ------------------------ | --------------------------- | --------------------- | ---------------------- |
| من يشارك؟            | أي شخص لديه أجهزة        | أي شخص يحجز المبلغ          | أعضاء معروفون         | سيرفرات تملكها         |
| ما يحمي من Sybil     | تكلفة الكهرباء           | المال المحجوز               | الهوية والشهادات      | الهوية                 |
| الأعطال التي يتحملها | مهاجم أقل من النصف       | مهاجم أقل من الثلث للنهائية | أقل من ثلث العقد تكذب | أقل من نصف العقد تتوقف |
| النهائية             | احتمالية تقوى مع كل كتلة | نهائية بعد حقبتين تقريباً   | فورية                 | فورية                  |
| التكلفة الأساسية     | كهرباء وأجهزة            | رأس مال محجوز               | رسائل كثيرة بين العقد | قليلة                  |

## تدريب عملي

1. عدل `retarget.py` حتى يلغي القيد على أربعة أضعاف، وشغله مرة أخرى، ثم قارن عدد الفترات التي احتاجتها الشبكة حتى تقترب من الهدف، ولاحظ هل أصبح التذبذب أكبر.
2. اطلب رأس كتلة حديثة من `mempool.space/api/block/<hash>/header`، وضعه مكان رأس الكتلة 840,000 في `verify_header.py`، وقارن صعوبتها بصعوبة أبريل 2024.

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- الإجماع بين سيرفرات تثق ببعضها يكفيه 2f + 1، أما مع أطراف قد تكذب فتحتاج 3f + 1 كما أثبتت ورقة Lamport سنة 1982، والشبكة العامة تحتاج فوق ذلك ما يمنع هجوم Sybil.
- إثبات العمل يقارن هاش رأس الكتلة بهدف رقمي، وأي شخص يستطيع التحقق من العمل بهاش واحد، كما تحققنا من الكتلة الأولى والكتلة 840,000.
- تعديل الصعوبة يجعل الكهرباء تتبع ربح التعدين وليس عدد المعاملات، والقيد على أربعة أضعاف يمنع التذبذب الكبير.
- هجوم 51% يلغي الدفعات الأخيرة ولا يسرق محافظ غيره، والتأكيدات تحميك بقدر تكلفة تجاوزها، كما في هجوم Bitcoin Gold في يناير 2020.
- إثبات الحصة يجعل الغش مكلفاً بمال المدقق، والنهائية تحتاج ثلثي المال المحجوز، والمصادرة تعاقب الهجوم المنسق أكثر من الخطأ المنفرد.
- في الشبكات الخاصة يكفيك Raft إذا كانت العقد لا تكذب، وتحتاج BFT إذا كانت الجهات لا تثق ببعضها.

[![](https://arabroot.io/content/images/2026/10/blockchain-basics-cover-cover.webp)دليلكيف يعمل البلوكتشين Blockchain ومتى لا تحتاجهما المشكلة التي يحلها البلوكتشين أصلاً وكيف يعمل من الداخل، ومتى تكون قاعدة البيانات العادية هي الحل الأصح.](https://arabroot.io/articles/%D8%A7%D9%84%D8%A8%D9%84%D9%88%D9%83%D8%AA%D8%B4%D9%8A%D9%86-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-%D9%83%D9%8A%D9%81-%D9%8A%D8%B9%D9%85%D9%84-%D9%88%D9%85%D8%AA%D9%89-%D9%84%D8%A7-%D8%AA%D8%AD%D8%AA%D8%A7%D8%AC%D9%87/)[![](https://arabroot.io/content/images/2026/10/distributed-systems-cover-cover.webp)دليلالأنظمة الموزعة للمبتدئين: ماذا يحدث عندما تنقطع الشبكةلماذا تتصرف الأنظمة الموزعة بشكل غريب عند انقطاع الشبكة، وكيف تتفق السيرفرات على قرار واحد رغم ذلك.](https://arabroot.io/articles/%D8%A7%D9%84%D8%A7%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D9%88%D8%B2%D8%B9%D8%A9-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-cap-%D9%88%D8%A7%D9%84%D8%A7%D8%AA%D8%B3%D8%A7%D9%82-%D9%88%D8%A7%D9%84%D8%A7%D8%AC%D9%85%D8%A7%D8%B9/)[![](https://arabroot.io/content/images/2026/10/crypto-for-devs-cover-cover.webp)دليلالتشفير للمطورين: ماذا تستخدم ولماذا لا تخترع خوارزميتكأي هاش تستخدم لكلمات المرور، ومتى تحتاج التشفير المتماثل أو غير المتماثل، وأين تحفظ المفاتيح بأمان في تطبيقك.](https://arabroot.io/articles/%D8%A7%D9%84%D8%AA%D8%B4%D9%81%D9%8A%D8%B1-%D9%84%D9%84%D9%85%D8%B7%D9%88%D8%B1%D9%8A%D9%86-%D8%A7%D9%84%D9%87%D8%A7%D8%B4-%D9%88%D9%83%D9%84%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%B1%D9%88%D8%B1-%D9%88%D8%A7%D9%84%D9%85%D9%81%D8%A7%D8%AA%D9%8A%D8%AD/)

## سجل التحديثات

- أكتوبر 2026: كتابة المقال، وتشغيل التجارب على Docker Engine 29.8.0 مع Python 3.13.16 (python:3.13.16-slim) على نواة معالج واحدة، والتحقق من الكتلة الأولى والكتلة 840,000 في Bitcoin.