مقدمة لمبرمجي بايثون حول إيثريوم، الجزء الأول
إذن، هل سمعت عن إيثريوم هذا ومستعد للمغامرة في المجهول؟ سيغطي هذا المنشور بسرعة بعض أساسيات البلوكتشين، ثم يجعلك تتفاعل مع عقدة إيثريوم تمت محاكاتها – قراءة بيانات الكتل، والتحقق من أرصدة الحسابات، وإرسال المعاملات. على طول الطريق، سنسلط الضوء على الاختلافات بين الطرق التقليدية لبناء التطبيقات وهذا النموذج اللامركزي الجديد.
المتطلبات الأساسية (غير الإلزامية)
يطمح هذا المنشور إلى أن يكون في متناول مجموعة واسعة من المبرمجين. سيتم إشراك أدوات بايثون، لكنها مجرد وسيلة للأفكار – لا توجد مشكلة إذا لم تكن مبرمج بايثون. لكنني سأضع بعض الافتراضات حول ما تعرفه بالفعل، حتى نتمكن من الانتقال بسرعة إلى التفاصيل الخاصة بـ إيثريوم.
الافتراضات:
- يمكنك التعامل مع الوحدة الطرفية،
- لقد كتبت بضعة أسطر من نص بايثون البرمجي،
- أن يكون إصدار بايثون 3.6 أو أحدث مثبتًا على جهازك (يُنصح بشدة باستخدام بيئة افتراضية (opens in a new tab))، و
- أنك استخدمت
pip، وهو مثبت حزم بايثون. مرة أخرى، إذا كان أي من هذا غير صحيح، أو كنت لا تخطط لإعادة إنتاج النص البرمجي في هذه المقالة، فمن المحتمل أنه لا يزال بإمكانك المتابعة على ما يرام.
البلوكتشين، باختصار
هناك طرق عديدة لوصف إيثريوم، لكن في جوهره يوجد بلوكتشين. تتكون سلاسل البلوكتشين من سلسلة من الكتل، لذا دعنا نبدأ من هناك. بأبسط العبارات، كل كتلة على بلوكتشين إيثريوم هي مجرد بعض البيانات الوصفية وقائمة من المعاملات. بتنسيق JSON، يبدو الأمر كالتالي:
1{2 "number": 1234567,3 "hash": "0xabc123...",4 "parentHash": "0xdef456...",5 ...,6 "transactions": [...]7}تحتوي كل كتلة على مرجع للكتلة التي سبقتها؛ parentHash هي ببساطة التجزئة (هاش) للكتلة السابقة.
البلوكتشين هي في الأساس قائمة مرتبطة؛ كل كتلة لديها إشارة إلى الكتلة السابقة.
هيكل البيانات هذا ليس جديدًا، ولكن القواعد (أي بروتوكولات نظير إلى نظير) التي تحكم الشبكة هي الجديدة. لا توجد سلطة مركزية؛ يجب على شبكة النظراء التعاون للحفاظ على الشبكة، والتنافس لتحديد المعاملات التي سيتم تضمينها في الكتلة التالية. لذا، عندما ترغب في إرسال بعض الأموال إلى صديق، ستحتاج إلى بث تلك المعاملة إلى الشبكة، ثم الانتظار حتى يتم تضمينها في كتلة قادمة.
الطريقة الوحيدة للتحقق من أن الأموال قد أُرسلت بالفعل من مستخدم إلى آخر في البلوكتشين هي استخدام عملة أصلية خاصة بتلك البلوكتشين (أي تم إنشاؤها وتحكمها من قبلها). في إيثريوم، تسمى هذه العملة إيثر، وتحتوي بلوكتشين إيثريوم على السجل الرسمي الوحيد لأرصدة الحسابات.
نموذج جديد
لقد أدى هذا المكدس التكنولوجي اللامركزي الجديد إلى ظهور أدوات جديدة للمبرمجين. توجد مثل هذه الأدوات في العديد من لغات البرمجة، لكننا سننظر من خلال عدسة بايثون. للتكرار: حتى لو لم تكن بايثون هي لغتك المفضلة، فلن يكون من الصعب عليك المتابعة.
من المرجح أن يلجأ مبرمجو بايثون الذين يرغبون في التفاعل مع إيثريوم إلى ويب3.باي (opens in a new tab). ويب3.باي هي مكتبة تبسط إلى حد كبير طريقة اتصالك بعقدة إيثريوم، ثم إرسال البيانات واستلامها منها.
يمكن تكوين عملاء إيثريوم ليكونوا قابلين للوصول عن طريق IPC (opens in a new tab)، أو HTTP، أو Websockets، لذلك ستحتاج ويب3.باي إلى محاكاة هذا التكوين. تشير ويب3.باي إلى خيارات الاتصال هذه باسم الموفرين. ستحتاج إلى اختيار أحد الموفرين الثلاثة لربط مثيل ويب3.باي بعقدتك.
قم بتكوين عقدة إيثريوم وويب3.باي للتواصل عبر نفس البروتوكول، على سبيل المثال، IPC في هذا الرسم التخطيطي.
بمجرد تكوين ويب3.باي بشكل صحيح، يمكنك البدء في التفاعل مع البلوكتشين. إليك بعض أمثلة استخدام ويب3.باي كمعاينة لما هو قادم:
1# قراءة بيانات الكتلة:2w3.eth.get_block('latest')34# إرسال معاملة:5w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...})التثبيت
في هذا الشرح التفصيلي، سنعمل فقط داخل مترجم بايثون. لن ننشئ أي أدلة أو ملفات أو فئات أو وظائف.
$ في الوحدة الطرفية. (لا تكتب $، فهي تشير فقط إلى بداية السطر.)أولًا، قم بتثبيت IPython (opens in a new tab) للحصول على بيئة سهلة الاستخدام للاستكشاف. يوفر IPython الإكمال التلقائي بعلامة التبويب، من بين ميزات أخرى، مما يسهل كثيرًا رؤية ما هو ممكن داخل ويب3.باي.
pip install ipythonيتم نشر ويب3.باي تحت اسم web3. قم بتثبيته على النحو التالي:
pip install web3شيء آخر – سنقوم بمحاكاة البلوكتشين لاحقًا، الأمر الذي يتطلب بعض التبعيات الإضافية. يمكنك تثبيتها عبر:
pip install 'web3[tester]'أنت الآن جاهز للانطلاق!
ملاحظة: تعمل حزمة web3[tester] حتى بايثون 3.10.xx
تجهيز بيئة اختبارية
افتح بيئة بايثون جديدة عن طريق تشغيل ipython في الوحدة الطرفية الخاصة بك. هذا مشابه لتشغيل python، لكنه يأتي مع المزيد من الميزات الإضافية.
ipythonسيؤدي هذا إلى طباعة بعض المعلومات حول إصدارات بايثون وIPython التي تقوم بتشغيلها، ثم يجب أن ترى مطالبة تنتظر الإدخال:
1In [1]:أنت الآن تنظر إلى واجهة بايثون التفاعلية. بشكل أساسي، إنها بيئة اختبارية للعب بها. إذا وصلت إلى هذا الحد، فقد حان الوقت لاستيراد ويب3.باي:
1In [1]: from web3 import Web3تقديم وحدة ويب3
إلى جانب كونها بوابة إلى إيثريوم، توفر وحدة ويب3 (opens in a new tab) بعض الوظائف المساعدة. دعنا نستكشف بعضها.
في تطبيق إيثريوم، ستحتاج عادةً إلى تحويل فئات العملات. توفر وحدة ويب3 طريقتين مساعدتين لهذا الغرض فقط: from_wei (opens in a new tab) وto_wei (opens in a new tab).
ملاحظة: تشتهر أجهزة الكمبيوتر بسوء تعاملها مع العمليات الحسابية العشرية. للتغلب على هذا، غالبًا ما يقوم المبرمجون بتخزين مبالغ الدولار بالسنت. على سبيل المثال، قد يتم تخزين عنصر بسعر 5.99 دولارًا في قاعدة البيانات على أنه 599.
يتم استخدام نمط مماثل عند التعامل مع المعاملات بـالإيثر. ومع ذلك، بدلًا من خانتين عشريتين، يحتوي الإيثر على 18! تُسمى أصغر فئة من الإيثر wei، لذا هذه هي القيمة المحددة عند إرسال المعاملات.
1 إيثر = 1000000000000000000 wei
1 wei = 0.000000000000000001 إيثر
حاول تحويل بعض القيم من وإلى wei. لاحظ أن هناك أسماء للعديد من الفئات (opens in a new tab) بين الإيثر وwei. من أشهرها غوي (gwei)، حيث إنها الطريقة التي يتم بها تمثيل رسوم المعاملات غالبًا.
1In [2]: Web3.to_wei(1, 'ether')2Out[2]: 100000000000000000034In [3]: Web3.from_wei(500000000, 'gwei')5Out[3]: Decimal('0.5')تشمل الطرق المساعدة الأخرى في وحدة ويب3 محولات تنسيق البيانات (على سبيل المثال، toHex (opens in a new tab))، ومساعدات العناوين (على سبيل المثال، isAddress (opens in a new tab))، ودوال التجزئة (الهاش) (على سبيل المثال، keccak (opens in a new tab)). سيتم تغطية العديد من هذه في وقت لاحق في السلسلة. لعرض جميع الطرق والخصائص المتاحة، استخدم الإكمال التلقائي لـ IPython عن طريق كتابة Web3. والضغط على مفتاح tab مرتين بعد النقطة.
تحدث إلى السلسلة
الطرق المساعدة رائعة، لكن دعنا ننتقل إلى البلوكتشين. الخطوة التالية هي تكوين ويب3.باي للتواصل مع عقدة إيثريوم. لدينا هنا خيار استخدام موفري IPC أو HTTP أو Websocket.
لن نسلك هذا المسار، ولكن مثالًا لسير عمل كامل باستخدام موفر HTTP قد يبدو كالتالي:
- تنزيل عقدة إيثريوم، على سبيل المثال، غيث (opens in a new tab).
- ابدأ تشغيل غيث في نافذة طرفية واحدة وانتظر حتى تتم مزامنة الشبكة. منفذ HTTP الافتراضي هو
8545، لكنه قابل للتكوين. - أخبر ويب3.باي بالاتصال بالعقدة عبر HTTP، على
localhost:8545.w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545')) - استخدم مثيل
w3للتفاعل مع العقدة.
في حين أن هذه طريقة "حقيقية" واحدة للقيام بذلك، فإن عملية المزامنة تستغرق ساعات وهي غير ضرورية إذا كنت تريد فقط بيئة تطوير. تعرض ويب3.باي موفرًا رابعًا لهذا الغرض، وهو EthereumTesterProvider. يرتبط هذا الموفر التجريبي بعقدة إيثريوم تمت محاكاتها مع أذونات مخففة وعملة مزيفة للعب بها.
يتصل EthereumTesterProvider بعقدة تمت محاكاتها وهو مفيد لبيئات التطوير السريعة.
تسمى تلك العقدة التي تمت محاكاتها eth-tester (opens in a new tab) وقمنا بتثبيتها كجزء من أمر pip install web3[tester]. تكوين ويب3.باي لاستخدام هذا الموفر التجريبي بسيط مثل:
1In [4]: w3 = Web3(Web3.EthereumTesterProvider())الآن أنت مستعد لتصفح السلسلة! هذا ليس تعبيرًا شائعًا. لقد اختلقته للتو. دعنا نأخذ جولة سريعة.
الجولة السريعة
أولًا وقبل كل شيء، فحص سريع للتأكد من السلامة:
1In [5]: w3.is_connected()2Out[5]: Trueنظرًا لأننا نستخدم الموفر التجريبي، فإن هذا ليس اختبارًا ذا قيمة كبيرة، ولكن إذا فشل، فمن المحتمل أنك كتبت شيئًا خاطئًا عند إنشاء متغير w3. تأكد مرة أخرى من أنك قمت بتضمين الأقواس الداخلية، أي Web3.EthereumTesterProvider().
المحطة الأولى في الجولة: الحسابات
للتسهيل، أنشأ الموفر التجريبي بعض الحسابات وقام بتحميلها مسبقًا بإيثر اختباري.
أولًا، دعنا نرى قائمة بتلك الحسابات:
1In [6]: w3.eth.accounts2Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',3 '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',4 '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...]إذا قمت بتشغيل هذا الأمر، يجب أن ترى قائمة من عشر سلاسل نصية تبدأ بـ 0x. كل منها عنوان عام وهو، في بعض النواحي، مماثل لرقم الحساب في حساب جارٍ. ستقدم هذا العنوان لشخص يريد أن يرسل لك الإيثر.
كما ذكرنا، قام الموفر التجريبي بتحميل كل من هذه الحسابات مسبقًا ببعض الإيثر الاختباري. دعنا نكتشف المبلغ الموجود في الحساب الأول:
1In [7]: w3.eth.get_balance(w3.eth.accounts[0])2Out[7]: 1000000000000000000000000هذا عدد كبير من الأصفار! قبل أن تذهب ضاحكًا إلى البنك المزيف، تذكر ذلك الدرس حول فئات العملات من قبل. يتم تمثيل قيم الإيثر بأصغر فئة، وهي wei. حول ذلك إلى إيثر:
1In [8]: w3.from_wei(1000000000000000000000000, 'ether')2Out[8]: Decimal('1000000')مليون إيثر اختباري - لا يزال ليس سيئًا للغاية.
المحطة الثانية في الجولة: بيانات الكتلة
دعنا نلقي نظرة خاطفة على حالة هذا البلوكتشين الذي تمت محاكاته:
1In [9]: w3.eth.get_block('latest')2Out[9]: AttributeDict({3 'number': 0,4 'hash': HexBytes('0x9469878...'),5 'parentHash': HexBytes('0x0000000...'),6 ...7 'transactions': []8})يتم إرجاع الكثير من المعلومات حول الكتلة، ولكن هناك شيئان فقط يجب الإشارة إليهما هنا:
- رقم الكتلة هو صفر - بغض النظر عن المدة التي قمت فيها بتكوين الموفر التجريبي. على عكس شبكة إيثريوم الحقيقية، التي تضيف كتلة جديدة كل 12 ثانية، ستنتظر هذه المحاكاة حتى تعطيها بعض العمل للقيام به.
transactionsهي قائمة فارغة، لنفس السبب: لم نفعل أي شيء بعد. هذه الكتلة الأولى هي كتلة فارغة، فقط لبدء السلسلة.- لاحظ أن
parentHashهو مجرد مجموعة من البايتات الفارغة. هذا يدل على أنها الكتلة الأولى في السلسلة، والمعروفة أيضًا باسم الكتلة التكوينية (genesis block).
المحطة الثالثة في الجولة: المعاملات
نحن عالقون في الكتلة صفر حتى تكون هناك معاملة معلقة، لذا دعنا نعطها واحدة. أرسل بعض الإيثر الاختباري من حساب إلى آخر:
1In [10]: tx_hash = w3.eth.send_transaction({2 'from': w3.eth.accounts[0],3 'to': w3.eth.accounts[1],4 'value': w3.to_wei(3, 'ether'),5 'gas': 210006})هذه هي النقطة التي تنتظر فيها عادةً عدة ثوانٍ حتى يتم تضمين معاملتك في كتلة جديدة. العملية الكاملة تسير على النحو التالي:
- أرسل معاملة واحتفظ بتجزئة (هاش) المعاملة. حتى يتم إنشاء الكتلة التي تحتوي على المعاملة وبثها، تكون المعاملة "معلقة".
tx_hash = w3.eth.send_transaction({ … }) - انتظر حتى يتم تضمين المعاملة في كتلة:
w3.eth.wait_for_transaction_receipt(tx_hash) - تابع منطق التطبيق. لعرض المعاملة الناجحة:
w3.eth.get_transaction(tx_hash)
ستضيف بيئتنا التي تمت محاكاتها المعاملة في كتلة جديدة على الفور، لذا يمكننا عرض المعاملة على الفور:
1In [11]: w3.eth.get_transaction(tx_hash)2Out[11]: AttributeDict({3 'hash': HexBytes('0x15e9fb95dc39...'),4 'blockNumber': 1,5 'transactionIndex': 0,6 'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',7 'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',8 'value': 3000000000000000000,9 ...10})إظهار الكلسترى بعض التفاصيل المألوفة هنا: يجب أن تتطابق حقول from وto وvalue مع مدخلات استدعاء send_transaction الخاص بنا. الشيء المطمئن الآخر هو أن هذه المعاملة تم تضمينها كأول معاملة ('transactionIndex': 0) ضمن الكتلة رقم 1.
يمكننا أيضًا التحقق بسهولة من نجاح هذه المعاملة عن طريق التحقق من أرصدة الحسابين المعنيين. يجب أن يكون قد تم نقل ثلاثة إيثر من أحدهما إلى الآخر.
1In [12]: w3.eth.get_balance(w3.eth.accounts[0])2Out[12]: 99999699997900000000000034In [13]: w3.eth.get_balance(w3.eth.accounts[1])5Out[13]: 1000003000000000000000000الأخير يبدو جيدًا! انتقل الرصيد من 1,000,000 إلى 1,000,003 إيثر. ولكن ماذا حدث للحساب الأول؟ يبدو أنه فقد أكثر من ثلاثة إيثر بقليل. للأسف، لا شيء في الحياة مجاني، واستخدام شبكة إيثريوم العامة يتطلب منك تعويض أقرانك عن دورهم الداعم. تم خصم رسوم معاملات صغيرة من الحساب الذي أرسل المعاملة - هذه الرسوم هي كمية الغاز المحترقة (21000 وحدة من الغاز لتحويل ETH) مضروبة في الرسوم الأساسية التي تختلف وفقًا لنشاط الشبكة بالإضافة إلى إكرامية تذهب إلى برنامج المدقق الذي يدرج المعاملة في كتلة.
المزيد عن الغاز
والآن استرح
لقد أمضينا وقتًا طويلًا في هذا، لذا يبدو هذا مكانًا جيدًا لأخذ قسط من الراحة. تستمر المغامرة، وسنواصل الاستكشاف في الجزء الثاني من هذه السلسلة. بعض المفاهيم القادمة: الاتصال بعقدة حقيقية، والعقود الذكية، والرموز. هل لديك أسئلة للمتابعة؟ أعلمني! ستؤثر ملاحظاتك على وجهتنا التالية. نرحب بالطلبات عبر تويتر (opens in a new tab).
آخر تحديث للصفحة: 6 فبراير 2025


