Buat Ethereum Geth Private Network di Docker Containers



Jika Anda perlu menggunakan jaringan Ethereum pribadi berdasarkan Geth, maka ini dapat dilakukan, misalnya, dengan membuat node jaringan pada server fisik atau mesin virtual. Namun, jauh lebih mudah untuk menggunakan wadah Geth dari repositori hub Docker. Dalam hal ini, Anda dapat menginstal seluruh jaringan node bahkan pada satu mesin virtual atau pada satu server fisik.

Pada artikel ini kami akan memberi tahu Anda cara memasang Docker pada server yang menjalankan Debian 9 (virtual atau fisik), cara membuat beberapa kontainer dengan menjalankan Geth dan menggabungkannya ke dalam jaringan pribadi. Kami akan memberikan contoh skrip untuk Node.js yang mengakses node Geth yang berfungsi dalam wadah.

Instal Docker


Instalasi Docker dijelaskan di situs web resmi. Untuk Debian 9 dan 10, Anda akan menemukan petunjuk terperinci di https://docs.docker.com/install/linux/docker-ce/debian/ .

Instal Docker
Pertama-tama, perbarui paket:

# apt-get update 

Selanjutnya, instal paket yang diperlukan dengan perintah berikut:

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

Tambahkan kunci GPG resmi:

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

Pastikan Anda mendapatkan kunci dengan sidik jari 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 

Tambahkan repositori Docker yang stabil:

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

Perbarui paket dan instal Docker:

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

Sekarang tinggal memverifikasi bahwa semuanya dilakukan dengan benar. Untuk melakukan ini, jalankan gambar (dunia) hello-world:

 # docker run hello-world 

Perintah ini akan mengunduh gambar yang diinginkan, dan menjalankannya untuk dieksekusi. Seperti yang Anda harapkan, Anda akan melihat pesan "Hello from Docker!" Di konsol.

Seperti yang Anda lihat, tidak ada yang rumit! Sekarang Anda dapat mulai membuat jaringan Geth pribadi dengan node berjalan dalam wadah.

Buat pengguna, direktori, dan file


Buat buku di server pengguna, dan subdirektori berikut di direktori rumahnya:

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

Selanjutnya, di direktori / home / book / dock-test, buat Dockerfile:

Daftar 1. File / home / book / dock-test / 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 


File ini akan digunakan saat membuat wadah Docker.

Anda juga perlu membuat file /home/book/dock-test/distr/genesis.json, yang diperlukan untuk menginisialisasi node jaringan Ethereum:

Daftar 2. File /home/book/dock-test/distr/genesis.json
 { "config": { "chainId": 98760, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0 }, "difficulty": "10", "gasLimit": "5100000", "alloc": {} } 


Di sini kami menetapkan pengidentifikasi jaringan pribadi kami ke 98760. Untuk kemudahan penambangan, kami tentukan 10 pada parameter kesulitan. Ini akan memungkinkan kami untuk bekerja pada mesin virtual dengan jumlah memori yang relatif kecil (misalnya, 4 GB).

Buat jaringan dan wadah


Agar node kami dapat saling bertukar data, kami akan membuat jaringan antar wadah:

 # docker network create PRIVATENET 

Selanjutnya, Anda perlu membuat direktori / home / book / dock-test saat ini, di mana Dockerfile berada. Kemudian buat jumlah kontainer yang diperlukan, misalnya, tiga:

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

Membuat wadah pertama membutuhkan waktu yang relatif lama, karena Anda perlu mengunduh gambar yang diperlukan. Namun wadah berikut ini dibuat hampir secara instan - bandingkan dengan kecepatan pembuatan mesin virtual, bahkan melalui kloning.

Sekarang buka empat jendela konsol. Tiga diantaranya, kami akan bekerja dengan kontainer, dan yang keempat, kami akan menerima data yang kami butuhkan tentang kontainer dan jaringan.

Di jendela konsol pertama, keluarkan perintah berikut:

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

Anda akan melihat prompt seperti:

 eth_book@304bf4f09063:~$ 

Di jendela konsol kedua dan ketiga, masukkan perintah berikut, masing-masing:

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

Membuat Node dan Akun Jaringan Pribadi Ethereum


Saat ini, kami memiliki tiga kontainer dengan Geth. Mari kita buat di masing-masing simpul jaringan dan akun Ethereum pribadi kita.

Masukkan perintah di tiga jendela konsol pertama:

 $ geth account new 

Anda harus memasukkan kata sandi. Untuk kesederhanaan, gunakan kata sandi yang sama pada setiap node untuk pengujian, tetapi tulis di suatu tempat. Jika Anda lupa kata sandi, maka kata sandi tidak akan berfungsi untuk memulihkan.

Setelah membuat akun di konsol, alamat kunci publik yang serupa dengan ini akan muncul:

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

Simpan alamat (Anda akan memiliki orang lain), sebagai kita membutuhkan mereka untuk menjalankan node.

Sekarang Anda perlu memulai inisialisasi node. Ini dilakukan dengan menggunakan perintah:

 $ geth --nousb init distr/genesis.json 

Masukkan perintah ini di semua jendela konsol wadah kami. Opsi --nousb menonaktifkan semua komunikasi dengan perangkat USB.

Menjalankan Geth Nodes


Sekarang buka masing-masing jendela konsol secara bergantian dan jalankan Geth di sana menggunakan perintah di bawah ini.

Jendela pertama:

 $ 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 

Jendela kedua:

 $ 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 

Jendela ketiga:

 $ 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 

Di setiap jendela yang terbuka, pesan tentang pembuatan DAG akan muncul:

 … 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 … 

Tunggu sampai generasi selesai. Setelah itu, eth.hashrate dan eth.blockNumber akan berbeda dari 0:

 > eth.hashrate 4 > eth.blockNumber 2 

Anda dapat memeriksa saldo akun saat ini sebagai berikut:

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

Agar Anda tidak terganggu oleh pesan tentang membuat blok baru dan pesan lain di jendela konsol, keluar dari Geth dengan perintah keluar dan mulai lagi dengan parameter verbosity diatur ke 1.

Node Jaringan


Untuk memulai, kita akan melihat daftar kontainer yang sedang berjalan. Keluarkan perintah berikut dari jendela konsol keempat:

 # 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 

Di sini, untuk setiap wadah, pengidentifikasi, nama gambar, nama wadah, dan informasi lainnya ditampilkan.

Untuk bergabung dengan wadah ke dalam jaringan, Anda akan memerlukan alamat IP wadah di jaringan PRIVATENET pribadi kami. Anda bisa mendapatkan alamat ini dengan ID kontainer, misalnya, sebagai berikut:

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

Anda juga dapat menggunakan jaringan buruh pelabuhan untuk memeriksa perintah PRIVATENET:

jaringan buruh pelabuhan memeriksa 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": {} } ] 

Membandingkan data yang diterima oleh perintah ini, kami akan membuat daftar alamat IP untuk wadah kami:

 node01 - 172.21.0.2 node02 - 172.21.0.3 node03 - 172.21.0.4 

Tentu saja, Anda akan memiliki daftar yang berbeda, dan ketika Anda me-restart wadah, alamat ini dapat berubah.

Setelah menerima daftar alamat, mulai ulang geth di semua wadah, tentukan alamat wadah Anda di parameter --rpcaddr. Anda bisa, tentu saja, mengatur alamat 0.0.0.0, tetapi ini buruk dari sudut pandang keamanan - siapa pun atau apa pun dapat terhubung ke node. Sebagai contoh, bisa jadi bot yang mencoba "menarik" semua dana dari node ini, menunggu simpul dibuka.

Untuk menggabungkan node, Anda harus menggunakan perintah admin.addPeer. Sebagai parameter untuk perintah ini, Anda harus meneruskan URL dalam format enode. Dapatkan URL ini untuk setiap wadah menggunakan perintah 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" 

Alamat yang diterima disimpan.

Untuk menghubungkan satu simpul ke simpul lainnya, buka jendela konsol simpul pertama dan masukkan perintah berikut di sana:

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

Di sini kami melewati alamat URL, yang menunjukkan di dalamnya alamat IP dari host yang terhubung. Ikuti prosedur yang sama pada node jaringan lain.

Untuk memverifikasi bahwa koneksi dibuat, gunakan perintah admin.peers. Jika tidak ada koneksi, perintah akan mengembalikan hasil kosong:

 > admin.peers [] 

Dalam kasus kami, perintah menunjukkan bahwa node pertama dengan alamat 172.21.0.2 terhubung ke node dengan alamat 172.21.0.3 dan 172.21.0.4:

Lihat hasilnya ketika ada koneksi
 > 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 } } }] 

Harap dicatat bahwa setelah node berhasil digabungkan dan disinkronkan, perintah eth.blockNumber akan mengembalikan nilai yang sama ketika diluncurkan di salah satu dari tiga kontainer kami.

Perintah web3.fromWei (eth.getBalance (eth.coinbase)), sebaliknya, akan menunjukkan keseimbangan yang berbeda pada node yang berbeda, karena setiap node memiliki akunnya sendiri.

Bekerja dengan host menggunakan Node.js


Dalam Listing 3, kami menyajikan skrip sederhana yang menjalankan Node.js yang menampilkan daftar akun untuk node yang ditentukan dan saldo dari masing-masing konsol:

Daftar 3. File / home / book / 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); }); 


Anda dapat menjalankan skrip ini secara terpisah, misalnya, di jendela konsol keempat:

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

Apa selanjutnya


Topik pengembangan perangkat lunak untuk cryptocurrency secara umum dan untuk Ethereum khususnya cukup menarik. Jika setelah membaca artikel ini Anda memiliki pertanyaan dan ingin tahu lebih banyak, baca buku saya β€œMembuat kontrak pintar Solidity untuk blockchain Ethereum. Panduan Praktis ” , yang diterbitkan oleh Liters Publishing House.

Anda mungkin juga membutuhkan lembar cheat Docker yang bagus.

Saya akan berterima kasih atas komentar dan penambahan pada artikel dan buku!

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


All Articles