دليلك الشامل: بناء بلوك تشين من الصفر باستخدام لغة Go
مقدمة إلى عالم البلوك تشين ولغة Go
مع تزايد انتشار تقنيات Web 3.0 والبلوك تشين يومًا بعد يوم، هل تعرف ما هي البلوك تشين حقًا؟ وهل تدرك مزاياها التقنية وحالات استخدامها المتعددة؟ يهدف هذا الدليل التعليمي إلى تقديم تقنية البلوك تشين من منظور تقني بحت، وذلك من خلال بناء نظام بلوك تشين خاص بك من الصفر.
انسَ كل ما سمعته عن البلوك تشين من وسائل التواصل الاجتماعي. الآن، ستبدأ في بناء نظام بلوك تشين من الألف إلى الياء لتفهم حقًا تفاصيل هذه التقنية الموزعة من نظير إلى نظير (peer-to-peer). بعد ذلك، ستكوّن رأيك الخاص حول مستقبلها ومزاياها. تنبيه: ستعشق برمجة برمجيات البلوك تشين!
كيف؟ ستتبع قصة مطور برمجيات يسعى لإحداث ثورة في حانته المحلية من خلال تطبيق تقنية البلوك تشين لنظام الدفع الخاص بها. على الرغم من أن البلوك تشين لديها العديد من حالات الاستخدام التي لا يمكن إنكارها، إلا أن التطبيق الأول حاليًا هو المدفوعات. هذا لأن البنوك لا تزال تعمل على بنية تحتية غير فعالة، عمرها 40 عامًا، مدعومة بملفات CSV وبروتوكول FTP.
تأتي القصة مع الكثير من الحقائق الممتعة والمثيرة للاهتمام حول النظام البيئي العام للبلوك تشين والبروتوكولات المختلفة مثل Bitcoin و Ethereum و XRP.
ماذا ستبني، تتعلم، وتفعل في هذا الدليل التعليمي؟
- ستقوم بإعداد مشروع
Goعلى جهازك المحلي دون أي خبرة سابقة فيGoLang. - ستقوم بإنشاء وتوزيع أول رموز بلوك تشين خاصة بك.
- ستطور قاعدة بيانات (
DB) يتم التحكم فيها عبر واجهة سطر الأوامر (CLI) بلغةGoمن الصفر. - ستكتشف مدى قلة الحقوق التي يمتلكها المستخدمون في تطبيقاتهم المفضلة.
- ستتعرف على القيمة الأساسية التي تقدمها البلوك تشين.
- ستجعل قاعدة بياناتك غير قابلة للتغيير (
immutable) باستخدام دالة تجزئة تشفيرية آمنة.
لنبدأ القصة وننغمس فيها. ⭐
تعرف على بطل القصة، أندريه
أندريه هو صاحب حانة ليلاً ومطور برمجيات نهارًا في بلدة سلوفاكية صغيرة تُدعى بارديوف. سئم أندريه من:
- برمجة تطبيقات
PHP/Java/Javascriptالصلبة والقديمة. - نسيان مقدار الأموال التي يدين بها أصدقاؤه وعملاؤه له مقابل جميع جرعات الفودكا غير المدفوعة ليلة الجمعة.
- قضاء الوقت في جمع وعدّ العملات المعدنية، وإرجاع الباقي، ولمس الأوراق النقدية المعرضة لـ
COVID-19بشكل عام. - صيانة رقائق بلاستيكية مختلفة لكرة الطاولة، السهام، البلياردو، والبوكر.
يتمنى أندريه أن:
- يمتلك سجلًا تدقيقيًا مثاليًا لأنشطة الحانة ومبيعاتها لجعل حانته متوافقة مع اللوائح الضريبية.
- يحوّل حانته إلى بيئة مستقلة، فعالة في الدفع، لا مركزية، وآمنة يمكن لعملائه الوثوق بها والاستفادة منها.
هدفه هو كتابة برنامج بسيط والاحتفاظ بجميع أرصدة عملائه في شكل افتراضي. يشارك أندريه أفكاره هنا:
“كل عميل جديد سيعطيني نقودًا، وسأقوم بإضافة ما يعادلها من رموزي الرقمية (عملات / عملة مشفرة). ستمثل الرموز وحدة نقدية داخل وخارج الحانة. سيستخدم المستخدمون الرموز لجميع وظائف الحانة، من دفع ثمن المشروبات، واستعارتها وإقراضها لأصدقائهم، ولعب تنس الطاولة، البوكر، والكيكر. إن امتلاك حانة مدعومة برموز البلوك تشين سيولد الكثير من القيمة لعملائي. على عكس منافسي والحانات الأخرى في هذا الشارع، حيث ينفق العملاء المال فقط ويحصلون على صداع في المقابل، فإن عملاء حانتي الذين يمتلكون رموز الحانة سيكون لديهم حقوق المساهمين. على غرار امتلاك جزء كبير من الأسهم في شركة مثل
AppleأوMicrosoft، سيتمكن العملاء الذين يمتلكون رموز الحانة هذه من تحديد كيفية عمل الحانة عن طريق التصويت واتخاذ القرارات بشأن:
- أسعار المشروبات
- ساعات العمل
- الميزات الجديدة (تلفزيون، جهاز موسيقى…)
- التصميم الداخلي والخارجي
- تخصيص الأرباح
- إلخ.
أوه، سيكون هذا حلمًا برمجيًا! سأطلق على الرموز اسم: رموز بلوك تشين البار،
TBB!”
الآن بعد أن شارك أندريه حلمه، لنبدأ.
جدول المحتويات
- المتطلبات
- إعداد المشروع
- 01 | قاعدة بيانات
MVP - 02 | تغيير حالة قاعدة البيانات العالمية
- 03 | الحدث المتكامل مقابل المعاملة
- 04 | البشر جشعون
- 05 | لماذا نحتاج إلى البلوك تشين
- 06 | التجزئة: نحو قاعدة بيانات غير قابلة للتغيير
- الخطوات التالية
المتطلبات
دعنا نتعمق في دليلنا التعليمي. أوصي بسنتين أو أكثر من الخبرة في البرمجة بلغات Java / PHP / Javascript، أو لغة أخرى مشابهة لـ Go. إذا كنت ترغب في الحصول على مقدمة سريعة جيدة للغة Go، فإليك دورة مجانية ستساعدك على البدء. يمكنك أيضًا إكمال المحاضرات الرسمية الـ 17 من A Tour Of Go لتتعرف على بناء الجملة والمفاهيم الأساسية للغة (~20 دقيقة).
لماذا لغة Go؟
لأنها، مثل البلوك تشين، تقنية رائعة لمسيرتك المهنية في البرمجة بشكل عام. Go لغة رائعة ومطورو Go يتقاضون رواتب أفضل من متوسط وظائف Java / PHP / Javascript.
- تم تحسين
Goلهندسة معالجاتCPUمتعددة النوى. يمكنك إنشاء آلاف الخيوط خفيفة الوزن (Go-routines) دون مشاكل. إنها عملية للغاية للبرامج المتوازية والمتزامنة للغاية مثل شبكات البلوك تشين. - من خلال كتابة برنامجك بلغة
Go، يمكنك تحقيق أداء يقارب مستوىC++بشكل مباشر دون إرهاق نفسك بسبب نسيان تحرير الذاكرة. - كما أن
Goتُجمّع إلى ملفات ثنائية (binary) مما يجعلها قابلة للنقل للغاية.
إعداد المشروع
يحتوي هذا المقال على مستودع Github مفتوح المصدر مخصص له مع الكود المصدري الكامل، حتى تتمكن من تجميع الكود وتشغيل البرنامج على جهازك المحلي. إذا واجهتك مشكلة في أي فصل أو سطر معين من الكود، فأنشئ Github Issue في هذا المستودع واصفًا مشكلتك وسأساعدك في أقرب وقت ممكن!
↓ قم بزيارة مستودع Github واتبع تعليمات التثبيت ↓
https://github.com/web3coach/the-blockchain-bar-newsletter-edition/
01 | قاعدة بيانات MVP
git checkout c1_genesis_json
أتقن أندريه قواعد بيانات SQL العلائقية في التسعينيات. إنه يعرف كيفية إنشاء نماذج بيانات متقدمة وكيفية تحسين استعلامات SQL. حان الوقت لأندريه لمواكبة الابتكار والبدء في بناء برمجيات Web 3.0. لحسن الحظ، بعد قراءة كتاب “The Lean Startup” الأسبوع الماضي، يشعر أندريه أنه لا ينبغي له المبالغة في هندسة الحل بعد. ومن ثم، يختار ملف JSON بسيطًا ولكنه فعال لقاعدة بيانات MVP الخاصة بالحانة.
في البداية، كانت هناك قاعدة بيانات مركزية بدائية.
ملخص: البلوك تشين هي قاعدة بيانات
المستخدم 1، أندريه، الاثنين 18 مارس. يقوم أندريه بإنشاء مليون رمز منفعة (utility tokens). في عالم البلوك تشين، الرموز هي وحدات داخل قاعدة بيانات البلوك تشين. تتذبذب قيمتها الحقيقية بالدولار أو اليورو بناءً على طلبها وشعبيتها. كل بلوك تشين لديها ملف “Genesis“. يُستخدم ملف Genesis لتوزيع الرموز الأولى على المشاركين الأوائل في البلوك تشين. كل شيء يبدأ بملف genesis.json بسيط وواضح.
ينشئ أندريه الملف ./database/genesis.json حيث يحدد أن قاعدة بيانات The Blockchain Bar ستحتوي على مليون رمز، وجميعها ستخص أندريه:
{
"genesis_time": "2019-03-18T00:00:00.000000000Z",
"chain_id": "the-blockchain-bar-ledger",
"balances": {
"andrej": 1000000
}
}
يجب أن يكون للرموز “فائدة” حقيقية، أي حالة استخدام. يجب أن يتمكن المستخدمون من الدفع بها من اليوم الأول! يجب على أندريه الامتثال للمنظمين القانونيين (هيئة الأوراق المالية والبورصات SEC). من غير القانوني إصدار أوراق مالية غير مسجلة. من ناحية أخرى، فإن رموز المنفعة (utility tokens) لا بأس بها، لذلك يقوم على الفور بطباعة ولصق ملصق تسعير أبيض جديد على باب الحانة.
يخصص أندريه قيمة نقدية أولية لرموزه حتى يتمكن من استبدالها باليورو أو الدولار أو أي عملة ورقية أخرى.
1 TBB token = 1 €
| Item | Price |
| ------------------------- | ------- |
| Vodka shot | 1 TBB |
| Orange juice | 5 TBB |
| Burger | 2 TBB |
| Crystal Head Vodka Bottle | 950 TBB |
يقرر أندريه أيضًا أنه يجب أن يحصل على 100 رمز يوميًا مقابل صيانة قاعدة البيانات وامتلاكه لمثل هذه الفكرة الرائدة.
حقائق شيقة
- تم إنشاء وتوزيع أول عملة
Ether (ETH)في بلوك تشينEthereumعلى المستثمرين والمطورين الأوائل بنفس طريقة رموز المنفعة الخاصة بأندريه. - في عام 2017، خلال طفرة عروض العملات الأولية (
ICO) على شبكة بلوك تشينEthereum، كتب مؤسسو المشاريع وقدموا أوراقًا بيضاء (whitepapers) للمستثمرين. الورقة البيضاء هي وثيقة تقنية تحدد قضية معقدة وحلاً ممكنًا، وتهدف إلى تثقيف وتوضيح مسألة معينة. في عالم البلوك تشين، تعمل الورقة البيضاء على تحديد مواصفات كيف ستبدو وتتصرف تلك البلوك تشين بمجرد تطويرها. - جمعت مشاريع البلوك تشين ما بين 10 ملايين يورو إلى 300 مليون يورو لكل فكرة ورقة بيضاء، مقابل المال (تمويل
ICO)، يتم تضمين أسماء المستثمرين في “أرصدةgenesis” الأولية، على غرار ما فعله أندريه. - آمال المستثمرين من خلال
ICOهي أن ترتفع قيمة عملاتgenesisوأن تقدم الفرق البلوك تشين المحددة. بطبيعة الحال، لا تتحقق جميع أفكار الأوراق البيضاء. الاستثمارات الضخمة التي ضاعت بسبب أفكار غير واضحة أو غير مكتملة هي السبب في أن البلوك تشين تلقت تغطية سلبية في وسائل الإعلام خلال هذه العروض الأولية، ولماذا لا يزال البعض يعتبرها مجرد ضجة. لكن تقنية البلوك تشين الأساسية رائعة ومفيدة، كما ستتعلم لاحقًا في هذا الكتاب. لقد تم إساءة استخدامها من قبل بعض الجهات السيئة.
ملخص: البلوك تشين هي قاعدة بيانات موزعة
يبدأ كل نظام بلوك تشين بملف Genesis يحدد إمداد الرموز الأولية والأرصدة الافتتاحية للمشاركين، مما يمثل نقطة البداية الموثوقة للسلسلة.
02 | تغيير حالة قاعدة البيانات العالمية
git checkout c2_db_changes_txt
حفلة ميتة
الاثنين 25 مارس. بعد أسبوع من العمل، أصبحت مرافق الحانة جاهزة لقبول الرموز. لسوء الحظ، لم يحضر أحد، لذلك طلب أندريه ثلاث جرعات فودكا لنفسه وكتب تغييرات قاعدة البيانات على قطعة من الورق:
andrej-3; // 3 shots of vodka
andrej+3; // technically purchasing from his own bar
andrej+700; // Reward for a week of work (7x100 per day)
لتجنب إعادة حساب أحدث حالة لرصيد كل عميل، ينشئ أندريه ملف ./database/state.json يخزن الأرصدة بتنسيق مجمع. حالة قاعدة البيانات الجديدة:
{
"balances": {
"andrej": 1000700
}
}
مكافأة لـ BabaYaga
الثلاثاء 26 مارس. لجذب الزوار إلى حانته، يعلن أندريه عن مكافأة حصرية بنسبة 100% لكل من يشتري رموز TBB في الـ 24 ساعة القادمة. بينغ! يحصل على أول عميلة له تُدعى BabaYaga. تشتري BabaYaga مسبقًا ما قيمته 1000 يورو من الرموز، وللاحتفال، تنفق فورًا 1 TBB على جرعة فودكا. لديها مشكلة في الشرب.
معاملات قاعدة البيانات المكتوبة على قطعة من الورق:
andrej-2000; // transfer to BabaYaga
babayaga+2000; // pre-purchase with 100% bonus
babayaga-1;
andrej+1;
andrej+100; // 1 day of sun coming up
حالة قاعدة البيانات الجديدة:
{
"balances": {
"andrej": 998801,
"babayaga": 1999
}
}
حقائق شيقة
- غالبًا ما توزع مشاريع
ICO(عروض العملات الأولية القائمة على الأوراق البيضاء) رموزgenesisبمكافآت مختلفة، اعتمادًا على عدد الرموز التي تشتريها ومدى مبادرتك. تقدم الفرق، في المتوسط، مكافآت تتراوح بين 10-40% لـ “المشاركين” الأوائل. يتم تجنب كلمة “مستثمر” حتى لا يعتبر المنظمون القانونيون الرموز أوراقًا مالية. - كانت المشاريع تبرر أن منتجها الرئيسي، رموز البلوك تشين، تعمل كـ “نقاط ولاء طائرة”. وقد حقق “المشاركون” لاحقًا ما يصل إلى 1000% على استثماراتهم من خلال البيع للجمهور عبر بورصة بعد عدة أشهر.
ملخص: المعاملات هي جوهر البلوك تشين
تُعد المعاملات (TX) جوهر أي بلوك تشين، حيث تمثل تغييرات الحالة في قاعدة البيانات. بينما يحدد ملف Genesis الحالة الأولية، فإن المعاملات هي التي تسجل التفاعلات اللاحقة وتعدّل الأرصدة، مما يخلق سجلًا ديناميكيًا للنشاط.
03 | الحدث المتكامل مقابل المعاملة
git checkout c3_state_blockchain_component
لا بد أن المطورين الذين اعتادوا على هندسة event-sourcing architecture قد تعرفوا على الفور على المبادئ المألوفة وراء المعاملات. إنهم على حق. تمثل معاملات البلوك تشين سلسلة من الأحداث، وقاعدة البيانات هي حالة مجمعة ونهائية محسوبة بعد إعادة تشغيل جميع المعاملات بتسلسل محدد.
أندريه يبرمج
مساء الثلاثاء، 26 مارس. إنه مساء الثلاثاء مريح لأندريه. احتفالًا بأول عميل له، يقرر أن يلعب بعض Starcraft وينظف جهاز التطوير المحلي الخاص به عن طريق إزالة بعض الصور القديمة. لسوء الحظ، ضغط على enter قبل الأوان عند كتابة مسار أمر الإزالة في الطرفية: sudo rm -rf / .. أوه! لقد اختفت جميع ملفاته، بما في ذلك ملفات genesis.json و state.json الخاصة بالحانة. أندريه، كونه مطورًا خبيرًا، صرخ ببعض الكلمات البذيئة بصوت عالٍ جدًا لبضع ثوانٍ، لكنه لم يذعر! بينما لم يكن لديه نسخة احتياطية، كان لديه شيء أفضل — قطعة من الورق تحتوي على جميع معاملات قاعدة البيانات.
الشيء الوحيد الذي يحتاج إلى فعله هو إعادة تشغيل جميع المعاملات واحدة تلو الأخرى، وسيتم استعادة حالة قاعدة بياناته. أعجب بمزايا الهندسة القائمة على الأحداث، وقرر تمديد حل قاعدة بيانات MVP الخاص به. يجب تسجيل كل نشاط في الحانة، مثل عمليات شراء المشروبات الفردية، داخل قاعدة بيانات البلوك تشين.
سيتم تمثيل كل عميل في قاعدة البيانات باستخدام بنية حساب (Account Struct):
type Account string
ستحتوي كل معاملة (TX – تغيير في قاعدة البيانات) على السمات الأربع التالية: from و to و value و data. السمة data بقيمة واحدة ممكنة (reward) تلتقط مكافأة أندريه لاختراعه البلوك تشين وتزيد إجمالي إمداد رموز TBB الأولية بشكل مصطنع (تضخم).
type Tx struct {
From Account `json:"from"`
To Account `json:"to"`
Value uint `json:"value"`
Data string `json:"data"`
}
func (t Tx) IsReward() bool {
return t.Data == "reward"
}
ستظل قاعدة بيانات Genesis DB ملف JSON:
{
"genesis_time": "2019-03-18T00:00:00.000000000Z",
"chain_id": "the-blockchain-bar-ledger",
"balances": {
"andrej": 1000000
}
}
سيتم تخزين جميع المعاملات، التي كانت مكتوبة سابقًا على قطعة من الورق، في قاعدة بيانات ملف نصي محلية تُسمى tx.db، بتنسيق JSON مفصول بحرف فاصل الأسطر (line-break character):
{
"from": "andrej",
"to": "andrej",
"value": 3,
"data": ""
}
{
"from": "andrej",
"to": "andrej",
"value": 700,
"data": "reward"
}
{
"from": "andrej",
"to": "babayaga",
"value": 2000,
"data": ""
}
{
"from": "andrej",
"to": "andrej",
"value": 100,
"data": "reward"
}
{
"from": "babayaga",
"to": "andrej",
"value": 1,
"data": ""
}
المكون الأكثر أهمية في قاعدة البيانات الذي يغلف جميع منطق الأعمال سيكون State:
type State struct {
Balances map[Account]uint
txMempool []Tx
dbFile *os.File
}
ستعرف بنية State جميع أرصدة المستخدمين ومن قام بتحويل رموز TBB إلى من، وكم تم تحويله. يتم إنشاؤها بقراءة أرصدة المستخدمين الأولية من ملف genesis.json:
func NewStateFromDisk() (*State, error) {
// get current working directory
cwd, err := os.Getwd()
if err != nil {
return nil, err
}
genFilePath := filepath.Join(cwd, "database", "genesis.json")
gen, err := loadGenesis(genFilePath)
if err != nil {
return nil, err
}
balances := make(map[Account]uint)
for account, balance := range gen.Balances {
balances[account] = balance
}
بعد ذلك، يتم تحديث أرصدة State الأولية عن طريق إعادة تشغيل جميع أحداث قاعدة البيانات بالتسلسل من tx.db:
txDbFilePath := filepath.Join(cwd, "database", "tx.db")
f, err := os.OpenFile(txDbFilePath, os.O_APPEND|os.O_RDWR, 0600)
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(f)
state := &State{balances, make([]Tx, 0), f}
// Iterate over each the tx.db file's line
for scanner.Scan() {
if err := scanner.Err(); err != nil {
return nil, err
}
// Convert JSON encoded TX into an object (struct)
var tx Tx
json.Unmarshal(scanner.Bytes(), &tx)
// Rebuild the state (user balances),
// as a series of events
if err := state.apply(tx); err != nil {
return nil, err
}
}
return state, nil
}
مكون State مسؤول عن:
- إضافة معاملات جديدة إلى
Mempool. - التحقق من صحة المعاملات مقابل
Stateالحالي (رصيد المرسل الكافي). - تغيير الحالة.
- استمرارية المعاملات على القرص.
- حساب أرصدة الحسابات عن طريق إعادة تشغيل جميع المعاملات منذ
Genesisبتسلسل.
إضافة معاملات جديدة إلى Mempool:
func (s *State) Add(tx Tx) error {
if err := s.apply(tx); err != nil {
return err
}
s.txMempool = append(s.txMempool, tx)
return nil
}
استمرارية المعاملات على القرص:
func (s *State) Persist() error {
// Make a copy of mempool because the s.txMempool will be modified
// in the loop below
mempool := make([]Tx, len(s.txMempool))
copy(mempool, s.txMempool)
for i := 0; i < len(mempool); i++ {
txJson, err := json.Marshal(mempool[i])
if err != nil {
return err
}
if _, err = s.dbFile.Write(append(txJson, '\n')); err != nil {
return err
}
// Remove the TX written to a file from the mempool
s.txMempool = s.txMempool[1:]
}
return nil
}
تغيير الحالة والتحقق من صحتها:
func (s *State) apply(tx Tx) error {
if tx.IsReward() {
s.Balances[tx.To] += tx.Value
return nil
}
if tx.Value > s.Balances[tx.From] {
return fmt.Errorf("insufficient balance")
}
s.Balances[tx.From] -= tx.Value
s.Balances[tx.To] += tx.Value
return nil
}
بناء واجهة سطر الأوامر (CLI)
مساء الثلاثاء، 26 مارس. يريد أندريه طريقة مريحة لإضافة معاملات جديدة إلى قاعدة بياناته (DB) وسرد أحدث أرصدة عملائه. نظرًا لأن برامج Go تُجمّع إلى ملفات ثنائية (binary)، فإنه يبني واجهة سطر أوامر (CLI) لبرنامجه. أسهل طريقة لتطوير برامج قائمة على CLI في Go هي باستخدام مكتبة الطرف الثالث github.com/spf13/cobra.
يقوم أندريه بتهيئة مدير التبعيات المدمج في Go لمشروعه، والذي يُسمى go modules:
cd $GOPATH/src/github.com/web3coach/the-blockchain-way-of-programming-newsletter-edition
go mod init github.com/web3coach/the-blockchain-way-of-programming-newsletter-edition
سيقوم أمر Go modules تلقائيًا بجلب أي مكتبة تشير إليها داخل ملفات Go الخاصة بك. ينشئ أندريه دليلًا جديدًا يُسمى: cmd مع دليل فرعي tbb:
mkdir -p ./cmd/tbb
بداخله ينشئ ملف main.go، يعمل كنقطة دخول لـ CLI للبرنامج:
package main
import (
"github.com/spf13/cobra"
"os"
"fmt"
)
func main() {
var tbbCmd = &cobra.Command{
Use: "tbb",
Short: "The Blockchain Bar CLI",
Run: func(cmd *cobra.Command, args []string) {
},
}
err := tbbCmd.Execute()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
يتم تجميع برامج Go باستخدام أمر install:
go install ./cmd/tbb/...
go: finding github.com/spf13/cobra v1.0.0
go: downloading github.com/spf13/cobra v1.0.0
go: extracting github.com/spf13/cobra v1.0.0
ستكتشف Go المكتبات المفقودة وتجلبها تلقائيًا قبل تجميع البرنامج. اعتمادًا على $GOPATH الخاص بك، سيتم حفظ البرنامج الناتج في مجلد $GOPATH/bin.
echo $GOPATH
/home/web3coach/go
which tbb
/home/web3coach/go/bin/tbb
يمكنك تشغيل tbb من طرفيتك الآن، لكنه لن يفعل شيئًا لأن دالة Run داخل ملف main.go فارغة. أول شيء يحتاجه أندريه هو دعم الإصدار لبرنامج CLI الخاص به tbb. بجانب ملف main.go، ينشئ أمر version.go:
package main
import (
"fmt"
"github.com/spf13/cobra"
)
const Major = "0"
const Minor = "1"
const Fix = "0"
const Verbal = "TX Add && Balances List"
var versionCmd = &cobra.Command{
Use: "version",
Short: "Describes version.",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Version: %s.%s.%s-beta %s", Major, Minor, Fix, Verbal)
},
}
يقوم بتجميعه وتشغيله:
go install ./cmd/tbb/...
tbb version
Version: 0.1.0-beta TX Add && Balances List
ممتاز. تمامًا مثل ملف version.go، ينشئ ملف balances.go:
func balancesCmd() *cobra.Command {
var balancesCmd = &cobra.Command{
Use: "balances",
Short: "Interact with balances (list...)",
PreRunE: func(cmd *cobra.Command, args []string) error {
return incorrectUsageErr()
},
Run: func(cmd *cobra.Command, args []string) {
},
}
balancesCmd.AddCommand(balancesListCmd)
return balancesCmd
}
سيكون أمر balances مسؤولًا عن تحميل أحدث حالة لقاعدة البيانات (DB State) وطباعتها إلى الإخراج القياسي:
var balancesListCmd = &cobra.Command{
Use: "list",
Short: "Lists all balances.",
Run: func(cmd *cobra.Command, args []string) {
state, err := database.NewStateFromDisk()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer state.Close()
fmt.Println("Accounts balances:")
fmt.Println("__________________")
fmt.Println("")
for account, balance := range state.Balances {
fmt.Println(fmt.Sprintf("%s: %d", account, balance))
}
},
}
يتحقق أندريه مما إذا كان الأمر يعمل كما هو متوقع. يجب أن يطبع الأرصدة الدقيقة المحددة في ملف Genesis لأن ملف tx.db لا يزال فارغًا.
go install ./cmd/tbb/...
tbb balances list
Accounts balances:
__________________
andrej : 1000000
يعمل بشكل جيد! الآن يحتاج فقط إلى أمر لتسجيل نشاط الحانة. ينشئ أندريه أمر ./cmd/tbb/tx.go:
func txCmd() *cobra.Command {
var txsCmd = &cobra.Command{
Use: "tx",
Short: "Interact with txs (add...).",
PreRunE: func(cmd *cobra.Command, args []string) error {
return incorrectUsageErr()
},
Run: func(cmd *cobra.Command, args []string) {
},
}
txsCmd.AddCommand(txAddCmd())
return txsCmd
}
يستخدم أمر tbb tx add دالة State.Add(tx) لاستمرارية أحداث الحانة في نظام الملفات:
func txAddCmd() *cobra.Command {
var cmd = &cobra.Command{
Use: "add",
Short: "Adds new TX to database.",
Run: func(cmd *cobra.Command, args []string) {
from, _ := cmd.Flags().GetString(flagFrom)
to, _ := cmd.Flags().GetString(flagTo)
value, _ := cmd.Flags().GetUint(flagValue)
fromAcc := database.NewAccount(from)
toAcc := database.NewAccount(to)
tx := database.NewTx(fromAcc, toAcc, value, "")
state, err := database.NewStateFromDisk()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// defer means, at the end of this function execution,
// execute the following statement (close DB file with all TXs)
defer state.Close()
// Add the TX to an in-memory array (pool)
err = state.Add(tx)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Flush the mempool TXs to disk
err = state.Persist()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println("TX successfully added to the ledger.")
},
}
يحتوي أمر tbb tx add على 3 أعلام إلزامية: --from و --to و --value.
cmd.Flags().String(flagFrom, "", "From what account to send tokens")
cmd.MarkFlagRequired(flagFrom)
cmd.Flags().String(flagTo, "", "To what account to send tokens")
cmd.MarkFlagRequired(flagTo)
cmd.Flags().Uint(flagValue, 0, "How many tokens to send")
cmd.MarkFlagRequired(flagValue)
return cmd
}
تم الانتهاء من CLI! يقوم أندريه بترحيل جميع المعاملات من الورق إلى قاعدة بياناته الجديدة:
tbb tx add --from=andrej --to=andrej --value=3
tbb tx add --from=andrej --to=andrej --value=700
tbb tx add --from=babayaga --to=andrej --value=2000
tbb tx add --from=andrej --to=andrej --value=100 --data=reward
tbb tx add --from=babayaga --to=andrej --value=1
اقرأ جميع المعاملات من القرص واحسب أحدث حالة:
tbb balances list
Accounts balances:
__________________
andrej : 998801
babayaga : 1999
تم استعادة بيانات البار بنجاح! يا لها من ليلة!
حول مكتبة Cobra CLI
الشيء الجيد في مكتبة Cobra لبرمجة CLI هو الميزات الإضافية التي تأتي معها. على سبيل المثال، يمكنك الآن تشغيل: tbb help cmd وسيطبع جميع الأوامر الفرعية المسجلة لـ TBB مع تعليمات حول كيفية استخدامها.
tbb help
The Blockchain Bar CLI
Usage:
tbb [flags]
tbb [command]
Available Commands:
balances Interact with balances (list...).
help Help about any command
tx Interact with txs (add...).
version Describes version.
Flags:
-h, --help help for tbb
Use "tbb [command] --help" for more information about a command.
حقائق شيقة
- فقدان بيانات العملاء عن طريق الخطأ هو أمر شائع في عالم الشركات هذه الأيام. البلوك تشين تُصلح هذا عن طريق لامركزية تخزين البيانات.
- الخدعة التي أضافها أندريه إلى البرنامج بتخطي التحقق من الرصيد للمعاملات التي تم وضع علامة عليها كمكافآت. يعمل
BitcoinوEthereumبنفس الطريقة. يزداد رصيد الحساب الذي قام بتعدين كتلة (block) فجأة كجزء من تضخم إجمالي إمداد الرموز الذي يؤثر على السلسلة بأكملها. - إجمالي إمداد عملات
Bitcoinمحدد بـ 21 مليونBTC. ستتعلم المزيد عن “التعدين” و “الكتل” في الفصلين 7 و 10. - مكونات
StateوMempoolليست فريدة لهذا البرنامج. اختار أندريه الأسماء والتصاميم لتتناسب مع نموذجgo-Ethereumالمبسط، حتى تتمكن من إلقاء نظرة داخل الكود المصدري الأساسي لـEthereum.
ملخص: المعاملات هي أحداث نظامية
تُعتبر المعاملات (TX) أحداثًا أساسية ضمن نظام البلوك تشين، حيث تسجل كل تغيير في الحالة. يتيح هذا النهج القائم على الأحداث استعادة حالة قاعدة البيانات بالكامل عن طريق إعادة تشغيل تسلسل المعاملات من ملف Genesis، مما يعزز المرونة والشفافية. تُعد مكونات مثل State و Mempool حاسمة لإدارة هذه المعاملات وتطبيقها.
⚒ دراسة الكود: Commit: 5d4b0b

دعنا نتحدث عن الجشع.
04 | البشر جشعون
git checkout c4_caesar_transfer
جشع الأعمال النموذجي
الأربعاء 27 مارس. استثمرت BabaYaga أكثر من اللازم. لقد نسيت أن موعد دفع إيجار شقتها كان وشيكًا، وليس لديها المال. تتصل BabaYaga بمالك شقتها، Caesar.
BabaYaga: مرحبًا Caesar، أنا آسفة، لكن ليس لدي نقود لأدفع لك الإيجار هذا الشهر…
Caesar: لماذا لا؟
BabaYaga: عرضت ICO حانة البلوك تشين مكافأة ضخمة، واشتريت رموزًا بقيمة 2000 يورو مقابل 1000 يورو فقط. كانت صفقة رائعة!
Caesar: ما الذي تتحدثين عنه؟ ما هو ICO؟ ما هي الرموز بحق الجحيم؟ هل يمكنك الدفع لي بطريقة أخرى؟
BabaYaga: أوه، ليس مرة أخرى. يمكنني أن أعطيك 1000 رمز TBB بقيمة 1000 يورو، ويمكنك استخدامها في الحانة لدفع ثمن مشروباتك! دعني أتصل بصاحب الحانة، أندريه، وأقوم بالتحويل!
Caesar: حسنًا… سأقبل بذلك.
يقوم أندريه بالتحويل، لكنه يقرر فرض رسوم إضافية قدرها 50 رمز TBB مقابل جهوده. لا يريد ذلك، لكن المساهمين في الحانة الذين استثمروا فيه قبل بضع سنوات يجبرونه على تحقيق الربح في أقرب وقت ممكن. لن تلاحظ BabaYaga هذه الرسوم الصغيرة على الأرجح على أي حال، يقول أندريه لنفسه. في النهاية، هو الوحيد الذي لديه حق الوصول إلى قاعدة البيانات (DB).
// دفع الإيجار
tbb tx add --from=babayaga --to=caesar --value=1000
// رسوم خفية
tbb tx add --from=babayaga --to=andrej --value=50
// مكافأة جديدة ليوم آخر من صيانة قاعدة البيانات
tbb tx add --from=andrej --to=andrej --value=100 --data=reward
حقائق شيقة
- حالة الاستخدام الأولى للبلوك تشين هي الخدمات المصرفية. تهدف العديد من مشاريع البلوك تشين إلى تحسين التبادل المحلي والدولي للأموال عبر ممرات العملات المختلفة (
XRP). - تركز مشاريع أخرى على الحرية والهوية ذات السيادة الذاتية (
SSI) – وهي حركة رقمية تعترف بضرورة امتلاك الفرد والتحكم في هويته وأمواله دون تدخل السلطات الإدارية أو الوسطاء المركزيين الآخرين. تتيحSSIللأشخاص التفاعل في العالم الرقمي بنفس الحرية والقدرة على الثقة كما يفعلون في العالم غير المتصل بالإنترنت (Bitcoin/Ethereum). - إليك بعض الحقائق الممتعة لماذا البلوك تشين مناسبة تمامًا لاستبدال البنية التحتية المصرفية الحالية لبنكك:
- الشيء الجيد في الرموز الافتراضية هو قابليتها للاستبدال (
fungibility) – أي قدرتها على التداول، حيث تكون كل وحدة صالحة للاستخدام مثل الأخرى. يمكن إجراء التحويل من حساب إلى حساب ببساطة عن طريق تغيير حالة قاعدة البيانات. - يمكن تداول العملات المشفرة على مدار الساعة طوال أيام الأسبوع. لا يمكنك تداول الأسهم مباشرة. تحتاج إلى المرور عبر وسيط يأخذ نسبة مئوية من إجمالي المعاملة كرسوم (1-3% إلى 7% متوسط الربح السنوي).
- يستغرق التحويل البنكي الدولي ما بين 3-10 أيام عمل ويمكن أن يكلف ما يصل إلى 5% من القيمة المحولة! إذا كنت ترسل 10,000 دولار، فقد تضطر إلى دفع ما يصل إلى 500 دولار. ما هي التقنية المستخدمة في الأربعين عامًا الماضية؟ ملفات
FTP + CSV. - هل تعتقد أن سوق الأوراق المالية عادل؟ البنوك والمؤشرات والأسهم مركزية للغاية وتتحكم فيها الحكومات ومجموعات
Wall Streetالخاصة. سوق حرة؟ تتحكمWall Streetفي مقدار ما يمكن أن ترتفع/تنخفض به الأسعار في يوم واحد. على سبيل المثال، أوقفتWall Streetتداول “مؤشرS&P 500 Index” بعد انخفاض بنسبة 7% لحماية مستثمريها وصناديق التحوط من خسارة الأموال من الأشخاص الذين يبيعون أسهمهم خلال مارس 2020 بعد أخبارCOVID. بعد ذلك، طبع الاحتياطي الفيدرالي (FED) تريليونات الدولارات لنفسه لدعم سعر السهم. إذا كنت مطورًا يحب توفير المال وتجنب الديون، فقد فقدت مدخراتك قيمتها بين عشية وضحاها بنسبة غير معروفة بعد. - العديد من البلدان تتجه نحو عوائد سلبية، وهي منطقة غير مستكشفة ذات عواقب غير معروفة. ماذا يعني هذا؟ قريبًا سيتعين عليك دفع البنك للاحتفاظ بمدخراتك. التضخم في أفضل حالاته. أنت مجبر على إنفاق أموالك لدعم نظام لا تتحكم فيه.
ملخص: البلوك تشين كحل لمشاكل الثقة
تُظهر حوادث التلاعب بالبيانات أهمية الأنظمة اللامركزية. تسعى البلوك تشين إلى استبدال البنى التحتية المالية المركزية التي تفتقر إلى الشفافية وتفرض رسومًا باهظة، وذلك بتقديم بديل يعزز السيادة الذاتية للمستخدمين والتحويلات الفورية والشفافة.
⚒ دراسة الكود: Commit: 00d6ed
05 | لماذا نحتاج إلى البلوك تشين
git checkout c5_broken_trust
BabaYaga تسعى لتحقيق العدالة
الخميس 28 مارس. تدخل BabaYaga البار للاحتفال بعيد ميلادها.
BabaYaga: مرحبًا أندريه! اليوم عيد ميلادي! أحضر لي أغلى زجاجة لديك!
أندريه: عيد ميلاد سعيد! تفضلي: Crystal Head Vodka. لكنك تحتاجين إلى شراء رمز TBB إضافي واحد. الزجاجة تكلف 950 رمزًا، ورصيدك هو 949.
BabaYaga: ماذا؟! من المفترض أن يكون رصيدي 999 TBB!
أندريه: تحويل الأموال إلى Caesar الذي طلبتيه الأسبوع الماضي كلفك 50 رمزًا.
BabaYaga: هذا غير مقبول! لم أكن لأوافق أبدًا على مثل هذه الرسوم المرتفعة. لا يمكنك فعل هذا يا أندريه. لقد وثقت بنظامك، لكنك غير موثوق به مثل أي صاحب عمل آخر. يجب أن تتغير الأمور!
أندريه: حسنًا، انظري. أنتِ أهم عميلة لي، ولم أرغب في فرض رسوم عليك، لكن مساهمي أجبروني. دعيني أعيد برمجة نظامي وأجعله شفافًا تمامًا ولا مركزيًا. بعد كل شيء، إذا كان الجميع قادرًا على التفاعل مع البار دون المرور بي، فسيؤدي ذلك إلى تحسين كفاءة البار بشكل كبير وتوازن مستوى الثقة!
- سيستغرق طلب المشروبات ثوانٍ بدلاً من دقائق.
- يمكن للعملاء الذين نسوا محافظهم في المنزل استعارة أو إقراض الرموز لبعضهم البعض.
- لن أقلق بشأن فقدان بيانات العملاء (مرة أخرى) حيث سيكون لدى الجميع نسخة منها.
- ستكون قاعدة البيانات غير قابلة للتغيير (
immutable)، لذلك بمجرد موافقة الجميع على حالة معينة، لا يمكن لأي شخص آخر تغييرها أو تعديل التاريخ بشكل ضار. ستساعد اللامركزية في عمليات التدقيق الضريبي السنوية أيضًا! - إذا أراد المساهمون فرض رسوم جديدة أو رفع الرسوم الحالية، فسيلاحظ الجميع المشاركون في نظام البلوك تشين ذلك وسيتعين عليهم الموافقة عليه. حتى المستخدمون وأصحاب الأعمال سيتعين عليهم الانخراط في نظام حوكمة لا مركزي معًا، يعتمد على التصويت، على الأرجح.
- في حالة عدم الاتفاق، يغادر المستخدمون بجميع بياناتهم!
BabaYaga: حسنًا، يبدو ذلك جيدًا بالتأكيد، ولكن هل هذا ممكن حتى؟
أندريه: نعم، أعتقد ذلك. مع قليل من التجزئة (hashing)، والقوائم المتصلة (linked lists)، وهيكل البيانات غير القابل للتغيير (immutable data structure)، والنسخ المتماثل الموزع (distributed replication)، والتشفير غير المتماثل (asymmetric cryptography)!
BabaYaga: ليس لدي أي فكرة عما قلته للتو، لكن اذهب وافعل شيئك التقني يا أندريه!
حقائق شيقة
- يتلقى معدنو
BitcoinوEthereumأيضًا مكافآت كل ~15 دقيقة لتشغيل خوادم البلوك تشين (nodes) والتحقق من صحة المعاملات. - كل 15 دقيقة، يتلقى عامل تعدين
Bitcoinواحد 12.5BTC(100 ألف دولار في وقت كتابة هذه الصفحة) لتغطية تكاليف خوادمه + تحقيق بعض الأرباح. - تستهلك شبكة
Bitcoinقدرًا من الكهرباء يعادل استهلاك دولة النمسا بأكملها. وتمثل 0.29% من استهلاك الكهرباء السنوي العالمي. تستهلك سنويًا 76.84 تيراواط/ساعة، وتنتج 36.50 مليون طن من انبعاثاتCO2(نيوزيلندا). المصدر. لماذا؟ ستتعلم المزيد لاحقًا (في الفصل 11) حيث ستقوم ببرمجة خوارزمية تعدينBitcoinمن الصفر! - ملاحظة: خوارزميتنا ستستهلك كهرباء أقل قليلاً 🙂
ملخص: لماذا اللامركزية ضرورية
تُسلط هذه التجربة الضوء على الحاجة الملحة لأنظمة شفافة وغير مركزية. تُقدم البلوك تشين حلولًا لمشكلات الثقة والمركزية من خلال توفير سجل بيانات غير قابل للتغيير، وشفافية كاملة في المعاملات، ونظام حوكمة يعتمد على موافقة المستخدمين، مما يضمن العدالة ويمنع التلاعب بالبيانات.
⚒ دراسة الكود: Commit: 642045
06 | التجزئة: نحو قاعدة بيانات غير قابلة للتغيير
git checkout c6_immutable_hash
تبدأ الصعوبة التقنية مع هذا القسم! ستصبح المفاهيم أكثر تحديًا ولكن في نفس الوقت، مثيرة للغاية. استعدوا 🙂
كيفية برمجة قاعدة بيانات غير قابلة للتغيير؟
الجمعة 29 مارس. إذا أراد أندريه معرفة كيفية برمجة قاعدة بيانات (DB) غير قابلة للتغيير (immutable)، فعليه أن يدرك سبب قابلية أنظمة قواعد البيانات الأخرى للتغيير (mutable) بطبيعتها. يقرر تحليل جدول قاعدة بيانات MySQL DB Table القوية:
| id | name | balance |
| -- | -------- | ------- |
| 1 | Andrej | 998951 |
| 2 | BabaYaga | 949 |
| 3 | Caesar | 1000 |
في قاعدة بيانات MySQL DB، يمكن لأي شخص لديه حق الوصول وسبب وجيه بما يكفي إجراء تحديث للجدول مثل:
UPDATE user_balance SET balance = balance + 100 WHERE id > 1
تحديث القيم عبر صفوف مختلفة ممكن لأن صفوف الجدول مستقلة، قابلة للتغيير، والحالة الأحدث ليست واضحة. ما هو أحدث تغيير في قاعدة البيانات؟ آخر عمود تم تغييره؟ آخر صف تم إدراجه؟ إذا كان الأمر كذلك، فكيف يمكن لأندريه معرفة الصف الذي تم حذفه مؤخرًا؟ إذا كانت الصفوف وحالة الجدول مرتبطة بإحكام، أي أن تحديث الصف 1 سيولد جدولًا جديدًا ومختلفًا تمامًا، فإن أندريه سيحقق خاصية عدم قابلية التغيير (immutability).
كيف يمكنك معرفة ما إذا كان أي بايت في قاعدة البيانات قد تغير؟
عدم قابلية التغيير عبر وظائف التجزئة (Hash Functions)
التجزئة (Hashing) هي عملية أخذ مدخل سلسلة من طول عشوائي وإنتاج سلسلة تجزئة (hash string) ذات طول ثابت. أي تغيير في المدخل سيؤدي إلى تجزئة جديدة ومختلفة.
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
balancesHash := sha256.Sum256([]byte("| 1 | Andrej | 99895 |"))
fmt.Printf("%x\n", balancesHash)
// Output: 6a04bd8e2...f70a3902374f21e089ae7cc3b200751
// Change balance from 99895 -> 99896
balancesHashDiff := sha256.Sum256([]byte("| 1 | Andrej | 99896 |"))
fmt.Printf("%x\n", balancesHashDiff)
// Output: d04279207...ec6d280f6c7b3e2285758030292d5e1
}
جربها: https://play.golang.org/p/FTPUa7IhOCE
يتطلب أندريه أيضًا مستوى معينًا من الأمان لقاعدة بياناته، لذلك يختار دالة تجزئة تشفيرية (Cryptographic Hash Function) بالخصائص التالية:
- إنها حتمية – نفس الرسالة دائمًا تنتج نفس التجزئة.
- إنها سريعة لحساب قيمة التجزئة لأي رسالة معينة.
- من غير المجدي توليد رسالة من قيمة التجزئة الخاصة بها إلا عن طريق تجربة جميع الرسائل الممكنة.
- يجب أن يغير التغيير الطفيف في الرسالة قيمة التجزئة بشكل كبير بحيث تبدو قيمة التجزئة الجديدة غير مرتبطة بقيمة التجزئة القديمة.
- من غير المجدي العثور على رسالتين مختلفتين بنفس قيمة التجزئة.

تطبيق تجزئة محتوى قاعدة البيانات
مساء السبت، 30 مارس. يقوم أندريه بتعديل دالة Persist() لإرجاع تجزئة محتوى جديدة، Snapshot، في كل مرة يتم فيها حفظ معاملة جديدة.
type Snapshot [32]byte
يتم إنتاج Snapshot بواسطة دالة التجزئة الآمنة sha256 الجديدة هذه:
func (s *State) doSnapshot() error {
// Re-read the whole file from the first byte
_, err := s.dbFile.Seek(0, 0)
if err != nil {
return err
}
txsData, err := ioutil.ReadAll(s.dbFile)
if err != nil {
return err
}
s.snapshot = sha256.Sum256(txsData)
return nil
}
يتم استدعاء doSnapshot() بواسطة دالة Persist() المعدلة. عندما تُكتب معاملة جديدة في ملف tx.db، تقوم دالة Persist() بتجزئة محتوى الملف بأكمله وتُرجع تجزئة “بصمة الإصبع” المكونة من 32 بايت.

من هذه اللحظة، يمكن للجميع بثقة وأمان 100% الإشارة إلى أي حالة معينة من قاعدة البيانات (مجموعة من البيانات) باستخدام تجزئة لقطة محددة.
⚓ وقت الممارسة
-
شغل أمر
tbb balances listوتحقق من تطابق الأرصدة.tbb balances listAccount balances at 7d4a360f465d... | id | name | balance | | -- | -------- | ------- | | 1 | Andrej | 999251 | | 2 | BabaYaga | 949 | | 3 | Caesar | 1000 | -
احذف آخر سطرين من
./database/tx.dbوتحقق من الأرصدة مرة أخرى.tbb balances listAccount balances at 841770dcd3... | id | name | balance | | -- | -------- | ------- | | 1 | Andrej | 999051 | | 2 | BabaYaga | 949 | | 3 | Caesar | 1000 | -
كافئ أندريه على اليومين الأخيرين (من 28 إلى 30 مارس):
معاملة المكافأة 1:
tbb tx add --from=andrej --to=andrej --value=100 --data=rewardPersisting new TX to disk: { "from" : "andrej" , "to" : "andrej" , "value" :100, "data" : "reward" } New DB Snapshot: ff2470c7043f5a34169b5dd38921ba6825b03b3facb83e426 TX successfully persisted to the ledger.معاملة المكافأة 2:
tbb tx add --from=andrej --to=andrej --value=100 --data=rewardPersisting new TX to disk: { "from" : "andrej" , "to" : "andrej" , "value" :100, "data" : "reward" } New DB Snapshot: 7d4a360f468b837b662816bcdc52c1869f99327d53ab4a9ca TX successfully persisted to the ledger. -
شغل أمر
tbb balances listوتأكد من أن الأرصدة وتجزئة اللقطة (snapshot hash) هي نفسها كما في البداية.tbb balances listAccount balances at 7d4a360f465d... | id | name | balance | | -- | -------- | ------- | | 1 | Andrej | 999251 | | 2 | BabaYaga | 949 | | 3 | Caesar | 1000 |
تم! نظرًا لأن دالة التجزئة التشفيرية sha256 تنتج نفس الإخراج (بافتراض نفس المدخلات (ملف tx.db الحالي و 2x tbb tx add))، إذا اتبعت الخطوات الدقيقة على جهاز الكمبيوتر الخاص بك، فستولد نفس حالة قاعدة البيانات والتجزئات تمامًا!
ملخص: التجزئة التشفيرية أساس اللامركزية
تُعد البلوك تشين قاعدة بيانات غير قابلة للتغيير، وتتحقق هذه الخاصية الأساسية من خلال وظائف التجزئة التشفيرية (Cryptographic Hash Functions). كل تغيير في البيانات ينتج عنه تجزئة فريدة، مما يربط حالة قاعدة البيانات السابقة باللاحقة ويضمن سلامة السجل وشفافيته. يستخدم المشاركون التجزئة الناتجة للإشارة إلى حالة قاعدة بيانات معينة بثقة تامة.
⚒ دراسة الكود: Commit: b99e51
الخطوات التالية ⭐
لقد أنهيت الفصول القليلة الأولى! تهانينا! █▒▒▒▒▒▒▒▒▒ 10%
لكن هذا كان مجرد إحماء سريع. البلوك تشين تقنية صعبة وواسعة النطاق للغاية، وستحتاج إلى كتاب كامل يشرح كيفية بناء النظام بالكامل وجميع مكوناته من الصفر – لذلك كتبت واحدًا. يمكنك متابعة القراءة في الفصل المجاني التالي في نسخة النشرة الإخبارية من كتابي الإلكتروني “The Blockchain Way of Programming“.
07 | نموذج برمجة البلوك تشين
- تحسين أداء قاعدة بيانات غير قابلة للتغيير (
Immutable DB). - المعالجة الدفعية + التجزئة + القائمة المتصلة ⇒ الكتل (
Blocks). - الترحيل من
TX.dbإلىBLOCKS.db. - التعلم: تقوم بإعادة تصميم وهيكلة قاعدة بيانات
MVPالخاصة بك إلى بنية بلوك تشين (blockchain architecture).
تابع في الدليل التعليمي: https://web3.coach#book
شكرًا للقراءة! إذا قرأت إلى هذا الحد، اشكر المؤلف لتظهر له اهتمامك. قل شكرًا.
تعلم البرمجة مجانًا. ساعد منهج freeCodeCamp مفتوح المصدر أكثر من 40,000 شخص في الحصول على وظائف كمطورين. ابدأ.
الخلاصة التقنية
يُقدم هذا الدليل العملي رحلة متعمقة في بناء نظام بلوك تشين أساسي باستخدام لغة Go، بدءًا من مفاهيم قواعد البيانات المركزية وصولًا إلى تحقيق اللامركزية وعدم قابلية التغيير عبر التجزئة التشفيرية. لقد أظهرت قصة أندريه الحاجة الماسة للشفافية والثقة في الأنظمة المالية، وكيف يمكن لتقنيات مثل Go ووظائف التجزئة SHA256 أن توفر حلولًا قوية لهذه التحديات. إن التركيز على المعاملات كأحداث، وإعادة بناء الحالة من سجل المعاملات، واستخدام التجزئة لتأمين البيانات، يمثل جوهر تصميم البلوك تشين ويؤكد على قيمتها في بناء أنظمة موزعة وموثوقة.