إنشاء Ethereum Geth شبكة خاصة في حاويات دوكر



إذا كنت بحاجة إلى نشر شبكة Ethereum خاصة تستند إلى Geth ، فيمكن القيام بذلك ، على سبيل المثال ، من خلال إنشاء عقد شبكة على الخوادم الفعلية أو الأجهزة الظاهرية. ومع ذلك ، من الأسهل بكثير استخدام حاويات Geth من مستودع Docker hub. في هذه الحالة ، يمكنك تثبيت شبكة كاملة من العقد حتى على جهاز ظاهري واحد أو على خادم فعلي واحد.

في هذه المقالة ، سنخبرك بكيفية تثبيت Docker على خادم يقوم بتشغيل Debian 9 (افتراضي أو مادي) ، وكيفية إنشاء عدة حاويات مع تشغيل Geth ودمجها في شبكة خاصة. سنقدم مثالًا نصيًا لـ Node.js يصل إلى عقد Geth التي تعمل في حاويات.

تثبيت عامل الميناء


يوصف تثبيت عامل الميناء على الموقع الرسمي. بالنسبة إلى دبيان 9 و 10 ، ستجد تعليمات مفصلة على https://docs.docker.com/install/linux/docker-ce/debian/ .

تثبيت عامل الميناء
بادئ ذي بدء ، قم بتحديث الحزم:

# apt-get update 

بعد ذلك ، قم بتثبيت الحزم اللازمة باستخدام الأمر التالي:

 # apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common 

أضف مفتاح GPG الرسمي:

 # curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - 

تأكد من حصولك على المفتاح باستخدام بصمة 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88:

 # apt-key fingerprint 0EBFCD88 pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid Docker Release (CE deb) docker@docker.com sub 4096R/F273FCD8 2017-02-22 

إضافة مستودع Docker مستقر:

 # add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" 

تحديث الحزم وتثبيت Docker:

 # apt-get update # apt-get install docker-ce docker-ce-cli containerd.io 

الآن يبقى فقط للتحقق من أن كل شيء يتم بشكل صحيح. للقيام بذلك ، قم بتشغيل (hello-world) صورة (صورة):

 # docker run hello-world 

سيقوم هذا الأمر بتنزيل الصورة المطلوبة وتشغيلها للتنفيذ. كما تتوقع ، سترى رسالة "Hello from Docker!" على وحدة التحكم.

كما ترون ، لا شيء معقد! الآن يمكنك البدء في إنشاء شبكة Geth خاصة مع عقد العقد في حاويات.

إنشاء المستخدم والدلائل والملفات


قم بإنشاء كتاب على خادم المستخدم والأدلة الفرعية التالية في دليله الرئيسي:

 /home/book/dock-test /home/book/dock-test/distr 

بعد ذلك ، في الدليل / home / book / dock-test ، قم بإنشاء Dockerfile:

قائمة 1. ملف / الوطن / كتاب / قفص الاتهام اختبار / Dockerfile
 FROM ubuntu:16.04 LABEL version="1.0" LABEL maintainer="alexandre@frolov.pp.ru" ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install --yes software-properties-common RUN add-apt-repository ppa:ethereum/ethereum RUN apt-get update && apt-get install --yes geth RUN adduser --disabled-login --gecos "" eth_book COPY distr /home/eth_book/distr RUN chown -R eth_book:eth_book /home/eth_book/distr USER eth_book WORKDIR /home/eth_book RUN geth --nousb init distr/genesis.json ENTRYPOINT bash 


سيتم استخدام هذا الملف عند إنشاء حاويات Docker.

ستحتاج أيضًا إلى إنشاء الملف / home/book/dock-test/distr/genesis.json ، وهو أمر ضروري لتهيئة عقد شبكة Ethereum:

قائمة 2. ملف / منزل / كتاب / قفص - اختبار / distr / genesis.json
 { "config": { "chainId": 98760, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0 }, "difficulty": "10", "gasLimit": "5100000", "alloc": {} } 


قمنا هنا بتعيين معرف شبكتنا الخاصة على 98760. لسهولة التعدين ، حددنا 10 في معلمة الصعوبة ، مما سيتيح لنا العمل على أجهزة افتراضية ذات مقدار صغير نسبياً من الذاكرة (على سبيل المثال ، 4 جيجابايت).

إنشاء شبكة والحاويات


لكي تتبادل نقاطنا البيانات مع بعضها البعض ، سننشئ شبكة بين الحاويات:

 # docker network create PRIVATENET 

بعد ذلك ، تحتاج إلى إجراء الدليل الحالي / home / book / dock-test ، حيث يوجد Dockerfile. ثم قم بإنشاء العدد المطلوب من الحاويات ، على سبيل المثال ، ثلاثة:

 # docker build -t node01 . # docker build -t node02 . # docker build -t node03 . 

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

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

في نافذة وحدة التحكم الأولى ، أصدر الأمر التالي:

 # docker run --rm -it -p 8545:8545 --net=PRIVATENET node01 

سترى موجه مثل:

 eth_book@304bf4f09063:~$ 

في نوافذ وحدة التحكم الثانية والثالثة ، أدخل الأمرين التاليين ، على التوالي:

 # docker run --rm -it -p 8546:8546 --net=PRIVATENET node02 # docker run --rm -it -p 8547:8547 --net=PRIVATENET node03 

إنشاء Ethereum عقد الشبكة الخاصة والحسابات


في الوقت الحالي ، لدينا ثلاث حاويات مع Geth. فلننشئ في كلٍ منها عقدة شبكة وحساب Ethereum الخاصين بنا.

أدخل الأمر في أول ثلاث نوافذ وحدة التحكم:

 $ geth account new 

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

بعد إنشاء الحسابات على وحدة التحكم ، ستظهر عناوين المفاتيح العامة المشابهة لتلك:

 Public address of the key: 0xc5Df10a76Bb559332c385F8cA789C0F37dD77A54 Public address of the key: 0x0C976006a5762779bA36AC590D1D8Ebac1Ca2981 Public address of the key: 0xaB627feab4e962222a3333F3b09182dF68bB9422 

حفظ العناوين (سيكون لديك الآخرين) ، كما نحن في حاجة إليها لتشغيل العقد.

الآن تحتاج إلى بدء تهيئة العقد. يتم ذلك باستخدام الأمر:

 $ geth --nousb init distr/genesis.json 

أدخل هذا الأمر في جميع نوافذ وحدة التحكم في حاوياتنا. - - الخيار nousb يعطل كل الاتصالات مع أجهزة USB.

تشغيل العقد Geth


افتح الآن كل من نوافذ وحدة التحكم بدوره وتشغيل Geth هناك باستخدام الأوامر أدناه.

النافذة الأولى:

 $ geth --identity="Node01" --etherbase "0xc5Df10a76Bb559332c385F8cA789C0F37dD77A54" --mine --minerthreads 1 --verbosity 3 --networkid 98760 --rpc --rpcaddr 127.0.0.1 --nousb --rpcapi="db,eth,net,web3,personal,web3" console 

النافذة الثانية:

 $ geth --identity="Node02" --etherbase "0x0C976006a5762779bA36AC590D1D8Ebac1Ca2981" --mine --minerthreads 1 --verbosity 3 --networkid 98760 --rpc --rpcaddr 127.0.0.1 --rpcport=8546 --nousb --rpcapi="db,eth,net,web3,personal,web3" console 

النافذة الثالثة:

 $ geth --identity="Node03" --etherbase "0xaB627feab4e962222a3333F3b09182dF68bB9422" --mine --minerthreads 1 --verbosity 3 --networkid 98760 --rpc --rpcaddr 127.0.0.1 --rpcport=8547 --nousb --rpcapi="db,eth,net,web3,personal,web3" console 

في كل من النوافذ المفتوحة ، ستظهر رسائل حول إنشاء DAG:

 … INFO [12-19|17:57:44.072] Generating DAG in progress epoch=0 percentage=34 elapsed=29.740s INFO [12-19|17:57:44.898] Generating DAG in progress epoch=0 percentage=35 elapsed=30.566s INFO [12-19|17:57:45.671] Generating DAG in progress epoch=0 percentage=36 elapsed=31.339s … 

انتظر حتى اكتمال الجيل. بعد ذلك ، سيكون eth.hashrate و eth.blockNumber مختلفين عن 0:

 > eth.hashrate 4 > eth.blockNumber 2 

يمكنك التحقق من رصيد الحساب الحالي على النحو التالي:

 > web3.fromWei( eth.getBalance(eth.coinbase) ) 

من أجل عدم إزعاجك من الرسائل حول إنشاء كتل جديدة ورسائل أخرى في نوافذ وحدة التحكم ، قم بإنهاء Geth باستخدام الأمر exit وإعادة التشغيل مرة أخرى مع تعيين المعلمة لفظية على 1.

عقد الشبكات


للبدء ، سوف ننظر إلى قائمة الحاويات الجارية. لإصدار الأمر التالي من إطار وحدة التحكم الرابعة:

 # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fa70a5418618 node03 "/bin/sh -c bash" 2 hours ago Up 2 hours 0.0.0.0:8547->8547/tcp gifted_curran 49a028744b4b node02 "/bin/sh -c bash" 2 hours ago Up 2 hours 0.0.0.0:8546->8546/tcp reverent_wescoff 5a9ade2947eb node01 "/bin/sh -c bash" 2 hours ago Up 2 hours 0.0.0.0:8545->8545/tcp clever_ellis 

هنا ، لكل حاوية ، يتم عرض معرفها واسم الصورة واسم الحاوية وغيرها من المعلومات.

لربط الحاويات في شبكة ، ستحتاج إلى عناوين IP للحاويات في شبكة PRIVATENET الخاصة بنا. يمكنك الحصول على هذه العناوين بواسطة معرف الحاوية ، على سبيل المثال ، كما يلي:

 # docker inspect 5a9ade2947eb | grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "", "IPAddress": "172.21.0.2", 

يمكنك أيضًا استخدام شبكة عامل ميناء لتفحص أمر PRIVATENET:

شبكة عامل ميناء تفقد PRIVATENET
 [ { "Name": "PRIVATENET", "Id": "576ec7edba5b4c228740deaf7fabb5e2ba003d310086153dd7f15e2c7de0c1b2", "Created": "2019-12-20T11:52:07.90695857+03:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "49a028744b4b6073f6dbca23e78625bc58fc0cdacadec7cded4bb0e888c7e37b": { "Name": "reverent_wescoff", "EndpointID": "11006b596b5a46df9bf9f95a9456784795d333a3e6901b15bd2db746fd4b5513", "MacAddress": "02:42:ac:15:00:03", "IPv4Address": "172.21.0.3/16", "IPv6Address": "" }, "5a9ade2947ebd8e55594ede9763aac71f5e6529c03e762ef723adb2c592c5ccd": { "Name": "clever_ellis", "EndpointID": "41ef69a0a93b5b1de495836028bac1742c303de92ffe42a0855ed32c93c28953", "MacAddress": "02:42:ac:15:00:02", "IPv4Address": "172.21.0.2/16", "IPv6Address": "" }, "fa70a54186185de01db3647e7333bf6c71250162fafefb78dbe9998e5ac93f34": { "Name": "gifted_curran", "EndpointID": "d368c032bc0886c27ad4895d1856e4f00cf1b25ce040f3b42393dbff778c18e5", "MacAddress": "02:42:ac:15:00:04", "IPv4Address": "172.21.0.4/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] 

بمقارنة البيانات التي تلقتها هذه الأوامر ، سنقوم بعمل قائمة من عناوين IP للحاويات الخاصة بنا:

 node01 - 172.21.0.2 node02 - 172.21.0.3 node03 - 172.21.0.4 

بالطبع ، سيكون لديك قائمة مختلفة ، وعند إعادة تشغيل الحاويات ، قد تتغير هذه العناوين.

بعد تلقي قائمة العناوين ، أعد تشغيل geth في جميع الحاويات ، مع تحديد عنوان الحاوية الخاصة بك في المعلمة --rpcaddr. يمكنك بالطبع تعيين العنوان 0.0.0.0 ، لكن هذا سيء من وجهة نظر الأمان - يمكن لأي شخص أو أي شيء الاتصال بالعقدة. على سبيل المثال ، يمكن أن يكون الروبوتات التي تحاول "سحب" جميع الأموال من هذه العقد ، في انتظار إلغاء العقدة.

لدمج العقد ، ستحتاج إلى استخدام الأمر admin.addPeer. كمعلمة لهذا الأمر ، تحتاج إلى تمرير URL بتنسيق enode. احصل على عنوان URL هذا لكل حاوية باستخدام الأمر admin.nodeInfo.enode:

 > admin.nodeInfo.enode "enode://0a84e562c9b22e43269b7dca215cf2ed8c20bbf35da67bae8d5ee81b36d8bbb69e3ec704b9b6f7501059fe861843a836b2fbab641f36616cdd77365b1a522d5b@62.152.63.28:30303?discport=1350" "enode://ee49f69e25c068e006fec4a8d74370370b1d2be9715b86eddd99f97a3a5a9c692a265ab7d01fb36410d59c3f6e2b253a22f652ecbf1941eef0b3f1d30b19a535@62.152.63.28:30303?discport=1345" "enode://156d43648b47078439c7481e54f697bbf1c6b6e762029ba2969f1556ceb94e51ad03f8bd2bed35f466073165810600f52925d155f0fceef832ae86fc39a8c135@62.152.63.28:30303?discport=1348" 

تلقي عناوين حفظ.

من أجل توصيل إحدى العقدين بأخرى ، افتح نافذة وحدة التحكم الخاصة بالعقدة الأولى وأدخل الأمر التالي هناك:

 > admin.addPeer( "enode://0a84e562c9b22e43269b7dca215cf2ed8c20bbf35da67bae8d5ee81b36d8bbb69e3ec704b9b6f7501059fe861843a836b2fbab641f36616cdd77365b1a522d5b@172.21.0.3:30303") 

هنا قمنا بتمرير عنوان URL ، مع الإشارة فيه إلى عنوان IP للمضيف المتصل. اتبع نفس الإجراء على عقد الشبكة الأخرى.

للتحقق من تأسيس الاتصال ، استخدم الأمر admin.peers. في حالة عدم وجود اتصالات ، سيعود الأمر بنتيجة فارغة:

 > admin.peers [] 

في حالتنا ، يُظهر الأمر أن العقدة الأولى بالعنوان 172.21.0.2 متصلة بالعقد ذات العناوين 172.21.0.3 و 172.21.0.4:

انظر النتيجة عندما تكون هناك اتصالات
 > admin.peers [{ caps: ["eth/63", "eth/64"], enode: "enode://156d43648b47078439c7481e54f697bbf1c6b6e762029ba2969f1556ceb94e51ad03f8bd2bed35f466073165810600f52925d155f0fceef832ae86fc39a8c135@172.21.0.4:30303", id: "4dac1d10cb6ae8bfc1fdebd3f5334b24ee62ec38a50bc92c89104cfc3251b5fc", name: "Geth/Node03/v1.9.9-stable-01744997/linux-amd64/go1.13.4", network: { inbound: false, localAddress: "172.21.0.2:40652", remoteAddress: "172.21.0.4:30303", static: true, trusted: false }, protocols: { eth: { difficulty: 98414119, head: "0x6b31a5bb9cde06fab5a8cc1ae9b18bada30de0d1b76cb3286c1081e76dbf5b83", version: 64 } } }, { caps: ["eth/63", "eth/64"], enode: "enode://ee49f69e25c068e006fec4a8d74370370b1d2be9715b86eddd99f97a3a5a9c692a265ab7d01fb36410d59c3f6e2b253a22f652ecbf1941eef0b3f1d30b19a535@172.21.0.3:30303", id: "b74277d278c15317fa7f7fa492daca60492ea22053bfc53281dd0071eba1c16b", name: "Geth/Node02/v1.9.9-stable-01744997/linux-amd64/go1.13.4", network: { inbound: false, localAddress: "172.21.0.2:42576", remoteAddress: "172.21.0.3:30303", static: true, trusted: false }, protocols: { eth: { difficulty: 99041423, head: "0x0ec44735bbb425cb8db96103f52300dfaae1147ba0e03aa4892d041250ce4408", version: 64 } } }] 

يرجى ملاحظة أنه بعد دمج العقد بنجاح ومزامنتها ، سيعود الأمر eth.blockNumber بنفس القيمة عند إطلاقه في أي من الحاويات الثلاثة.

الأمر web3.fromWei (eth.getBalance (eth.coinbase)) ، على العكس من ذلك ، سيُظهر توازنًا مختلفًا على العقد المختلفة ، لأن كل عقدة لها حساب خاص بها.

العمل مع المضيفين باستخدام Node.js


في القائمة 3 ، قدمنا ​​نصًا بسيطًا يشغّل Node.js يعرض على وحدة التحكم قائمة بحسابات العقدة المحددة ورصيد كل منها:

القائمة 3. ملف / الصفحة الرئيسية / كتاب / list_accounts.js
 var Web3 = require('web3') var web3 = new Web3(new Web3.providers.HttpProvider("http://172.21.0.2:8545")); web3.eth.getAccounts() .then(accList => { return accList; }) .then(function (accounts) { var balancePromeses = []; for(let i = 0; i < accounts.length; i++) { balancePromeses[i] = web3.eth.getBalance(accounts[i]); } Promise.all(balancePromeses).then(values => { for(let i = 0; i < values.length; i++) { console.log('Account: ', accounts[i], 'balance: ', values[i], 'wei, ', web3.utils.fromWei(values[i], 'ether'), 'ether'); } }); }) .catch(function (error) { console.error(error); }); 


يمكنك تشغيل هذا البرنامج النصي بشكل منفصل ، على سبيل المثال ، في نافذة وحدة التحكم الرابعة:

 # node list_accounts.js Account: 0x0C976006a5762779bA36AC590D1D8Ebac1Ca2981 balance: 3350000000000000000000 wei, 3350 ether 

ما التالي


موضوع تطوير البرمجيات للعملات المشفرة بشكل عام و Ethereum على وجه الخصوص رائعة. إذا كانت لديك أسئلة بعد قراءة هذا المقال وتريد معرفة المزيد ، فاقرأ كتابي "إنشاء عقود ذكية لتخلق صلابة في سلسلة Ethereum blockchain". الدليل العملي " ، الذي نشرته دار ليترز للنشر.

قد تحتاج أيضا ورقة الغش دوكر جيدة.

سأكون ممتنا لأية تعليقات والإضافات على المقال والكتاب!

Source: https://habr.com/ru/post/ar481052/


All Articles