Artikel ini adalah yang pertama dalam seri kode sumber Geth. Melalui seri ini, kita akan membangun kerangka penelitian tentang implementasi Geth, di mana para pengembang dapat mendalami bagian-bagian yang mereka minati berdasarkan kerangka ini. Seri ini terdiri dari enam artikel, dan dalam artikel pertama ini, kita akan mempelajari arsitektur desain klien lapisan eksekusi Geth serta alur proses awal Geth Node. Kecepatan pembaruan kode Geth sangat cepat, jadi kode yang akan dilihat kemudian mungkin akan berbeda, namun desain keseluruhan tetap konsisten, dan kode baru juga dapat dibaca dengan pemikiran yang sama.
01\Klien Ethereum
Sebelum peningkatan The Merge Ethereum, Ethereum hanya memiliki satu klien, yang bertanggung jawab atas pelaksanaan transaksi dan konsensus blockchain, memastikan bahwa blockchain menghasilkan blok baru dalam urutan tertentu. Setelah peningkatan The Merge, klien Ethereum dibagi menjadi lapisan eksekusi dan lapisan konsensus, lapisan eksekusi bertanggung jawab atas pelaksanaan transaksi, pemeliharaan status dan data, lapisan konsensus bertanggung jawab atas implementasi fungsi konsensus, dan lapisan eksekusi dan lapisan konsensus berkomunikasi melalui API. Lapisan eksekusi dan lapisan konsensus memiliki spesifikasi mereka sendiri, dan klien dapat mengimplementasikannya dalam bahasa yang berbeda, tetapi mereka harus sesuai dengan spesifikasi yang sesuai, dan Geth adalah implementasi dari klien lapisan eksekusi. Saat ini, lapisan eksekusi utama dan klien lapisan konsensus memiliki implementasi berikut:
Lapisan Eksekusi
Geth: Dipelihara oleh tim yang didanai langsung oleh Ethereum Foundation, dikembangkan dengan bahasa Go, diakui sebagai klien yang paling stabil dan telah teruji.
Nethermind: Dikembangkan dan dipelihara oleh tim Nethermind, menggunakan bahasa C#, awalnya didanai oleh Ethereum Foundation dan komunitas Gitcoin.
Besu: Awalnya dikembangkan oleh tim PegaSys dari ConsenSys, sekarang menjadi proyek komunitas Hyperledger, dikembangkan menggunakan bahasa Java.
Erigon: Dikembangkan dan dipelihara oleh tim Erigon, didanai oleh Yayasan Ethereum dan BNB Chain. Berasal dari fork Geth pada tahun 2017, bertujuan untuk meningkatkan kecepatan sinkronisasi dan efisiensi disk.
Reth: Dikembangkan oleh Paradigm, bahasa pemrograman yang digunakan adalah Rust, menekankan modularitas dan performa tinggi, saat ini sudah mendekati matang, dapat digunakan di lingkungan produksi.
Lapisan Konsensus
Prysm: Dikelola oleh Prysmatic Labs, merupakan salah satu klien lapisan konsensus pertama Ethereum, dikembangkan dengan bahasa Go, fokus pada kegunaan dan keamanan, awalnya didanai oleh yayasan Ethereum.
Lighthouse: Dikelola oleh tim Sigma Prime, dikembangkan menggunakan bahasa Rust, mengutamakan kinerja tinggi dan keamanan tingkat perusahaan, cocok untuk skenario beban tinggi.
Teku: Awalnya dikembangkan oleh tim PegaSys dari ConsenSys, kemudian menjadi bagian dari komunitas Hyperledger Besu, dikembangkan menggunakan bahasa Java.
Nimbus: Dikembangkan dan dikelola oleh tim Status Network, menggunakan bahasa Nim, dioptimalkan untuk perangkat dengan sumber daya terbatas (seperti ponsel, perangkat IoT), bertujuan untuk mencapai operasi ringan dalam sistem embedded.
02\Ringkasan Lapisan Eksekusi
Lapisan eksekusi Ethereum dapat dilihat sebagai mesin status yang digerakkan oleh transaksi, fungsi dasar dari lapisan eksekusi adalah untuk memperbarui data status melalui eksekusi transaksi oleh EVM. Selain eksekusi transaksi, terdapat juga fungsi untuk menyimpan dan memverifikasi blok dan data status, menjalankan jaringan p2p, dan memelihara kumpulan transaksi.
Transaksi dihasilkan oleh pengguna (atau program) dalam format yang ditentukan oleh spesifikasi lapisan eksekusi Ethereum. Pengguna perlu menandatangani transaksi tersebut, jika transaksi tersebut sah (Nonce berurutan, tanda tangan benar, biaya gas cukup, dan logika bisnis benar), maka transaksi akhirnya akan dieksekusi oleh EVM, yang akan memperbarui status jaringan Ethereum. Status di sini merujuk pada kumpulan struktur data, data, dan basis data, termasuk alamat akun eksternal, alamat kontrak, saldo alamat, serta kode dan data.
Lapisan eksekusi bertanggung jawab untuk mengeksekusi transaksi dan mempertahankan keadaan transaksi setelah dieksekusi, dan lapisan konsensus bertanggung jawab untuk memilih transaksi mana yang akan dieksekusi. EVM adalah fungsi transisi keadaan dalam mesin keadaan ini, dan input fungsi akan datang dari banyak tempat, baik dari informasi blok terbaru yang disediakan oleh lapisan konsensus, atau dari blok yang diunduh oleh jaringan p2p.
Lapisan konsensus dan lapisan eksekusi berkomunikasi melalui Engine API, yang merupakan satu-satunya cara komunikasi antara lapisan eksekusi dan lapisan konsensus. Jika lapisan konsensus mendapatkan hak untuk memproduksi blok, maka akan menggunakan Engine API untuk membuat blok baru di lapisan eksekusi. Jika tidak mendapatkan hak untuk memproduksi blok, lapisan konsensus akan menyinkronkan blok terbaru untuk divalidasi dan dieksekusi oleh lapisan eksekusi, sehingga tetap menjaga konsensus dengan seluruh jaringan Ethereum.
Lapisan eksekusi secara logis dapat dibagi menjadi 6 bagian:
EVM: Bertanggung jawab untuk mengeksekusi transaksi, eksekusi transaksi juga merupakan satu-satunya cara untuk mengubah status.
Penyimpanan: Bertanggung jawab untuk penyimpanan data seperti state dan blok.
Kolam perdagangan: digunakan untuk transaksi yang diajukan oleh pengguna, disimpan sementara, dan akan disebarkan melalui jaringan p2p antar Node yang berbeda.
jaringan p2p: digunakan untuk menemukan Node, menyinkronkan transaksi, mengunduh blok, dan lain-lain.
Layanan RPC: Menyediakan kemampuan untuk mengakses Node, seperti pengguna mengirim transaksi ke Node, interaksi antara lapisan konsensus dan lapisan eksekusi
BlockChain: Bertanggung jawab untuk mengelola data blockchain Ethereum
Gambar di bawah menunjukkan proses kunci dari lapisan eksekusi, serta fungsi setiap bagiannya:
Untuk lapisan eksekusi (di sini hanya membahas Full Node), ada tiga proses kunci:
Jika node Ethereum baru bergabung, perlu mensinkronkan blok dan data status dari node lain melalui jaringan p2p. Jika melakukan Full Sync, akan mulai mengunduh blok satu per satu dari blok genesis, memverifikasi blok, dan membangun basis data status melalui EVM. Jika melakukan Snap Sync, maka akan melewati seluruh proses verifikasi blok dan langsung mengunduh data status checkpoint terbaru serta data blok berikutnya.
Jika itu adalah Node yang sudah disinkronkan dengan status terbaru, maka akan terus-menerus mendapatkan blok terbaru yang dihasilkan saat ini dari lapisan konsensus melalui Engine API, memverifikasi blok, kemudian menjalankan semua transaksi dalam blok menggunakan EVM untuk memperbarui database status, dan menulis blok ke rantai lokal.
Jika node sudah disinkronkan ke status terbaru dan lapisan konsensus telah mendapatkan hak untuk memproduksi blok, maka akan menggunakan Engine API untuk menggerakkan lapisan eksekusi menghasilkan blok terbaru. Lapisan eksekusi mengambil transaksi dari pool transaksi dan mengeksekusinya, kemudian merakitnya menjadi blok yang diteruskan ke lapisan konsensus melalui Engine API, di mana lapisan konsensus akan menyebarkan blok ke jaringan p2p lapisan konsensus.
03\Struktur Sumber
struktur kode go-ethereum sangat besar, tetapi banyak kode di dalamnya adalah kode bantu dan pengujian unit. Saat mempelajari kode sumber Geth, Anda hanya perlu fokus pada implementasi inti protokol. Fungsi masing-masing modul adalah sebagai berikut. Perhatikan dengan seksama modul core, eth, ethdb, node, p2p, rlp, trie & triedb:
akun: mengelola akun Ethereum, termasuk pembuatan pasangan kunci publik dan pribadi, verifikasi tanda tangan, turunan alamat, dan lain-lain.
beacon: Mengelola logika interaksi dengan rantai sinyal Ethereum (Beacon Chain), mendukung fungsi setelah penggabungan (The Merge) dengan konsensus bukti kepemilikan (PoS)
build:script pembangunan dan konfigurasi kompilasi (seperti Dockerfile, dukungan kompilasi lintas platform)
cmd:pintu masuk alat baris perintah, berisi beberapa subperintah
umum:Alat umum, seperti pengolahan byte, konversi format alamat, fungsi matematika
konsensus:mendefinisikan mesin konsensus, termasuk sebelumnya bukti kerja (Ethash) dan bukti kepemilikan tunggal (Clique) serta mesin Beacon dan lain-lain
konsol: menyediakan konsol JavaScript interaktif, memungkinkan pengguna untuk berinteraksi langsung dengan Node Ethereum melalui baris perintah (seperti memanggil API Web3, mengelola akun, dan menanyakan data blockchain)
core: Logika inti blockchain, mengelola siklus hidup blok/transaksi, mesin keadaan, perhitungan Gas, dll.
crypto: Implementasi algoritma kriptografi, termasuk kurva elips (secp256k1), hash (Keccak-256), verifikasi tanda tangan
eth: Implementasi lengkap dari protokol jaringan Ethereum, termasuk layanan node, sinkronisasi blok (seperti sinkronisasi cepat, mode arsip), siaran transaksi, dll.
ethclient: Mengimplementasikan pustaka klien Ethereum, membungkus antarmuka JSON-RPC, untuk pengembang Go berinteraksi dengan Node Ethereum (seperti menanyakan blok, mengirim transaksi, menerapkan kontrak)
ethdb: lapisan abstraksi basis data, mendukung LevelDB, Pebble, basis data dalam memori, dan menyimpan data blockchain (blok, status, transaksi)
ethstats: Mengumpulkan dan melaporkan status operasi Node ke layanan statistik, untuk memantau kesehatan jaringan.
event: Mewujudkan mekanisme langganan dan penerbitan peristiwa, mendukung komunikasi asinkron antar modul di dalam node (seperti kedatangan blok baru, pembaruan kolam transaksi)
graphql: Menyediakan antarmuka GraphQL, mendukung kueri kompleks (menggantikan beberapa fungsi JSON-RPC)
internal:alat internal atau kode yang membatasi akses eksternal
log: Sistem log, mendukung keluaran log bertingkat dan pencatatan log konteks.
miner: logika terkait penambangan, menghasilkan blok baru dan mengemas transaksi (dalam skenario PoW)
node: Manajemen layanan Node, mengintegrasikan peluncuran dan konfigurasi modul p2p, RPC, basis data, dan lainnya.
P2P: Implementasi protokol jaringan point-to-point, mendukung penemuan node, transmisi data, dan komunikasi terenkripsi
params:menentukan parameter jaringan Ethereum (mainnet, testnet, konfigurasi blok genesis)
rlp: Mengimplementasikan protokol serialisasi data khusus Ethereum RLP (Recursive Length Prefix), digunakan untuk encoding/decoding struktur data seperti blok, transaksi, dll.
rpc: Mengimplementasikan antarmuka JSON-RPC dan IPC, untuk program eksternal berinteraksi dengan Node
signer:Manajemen tanda tangan transaksi (integrasi dompet keras)
tes: pengujian terintegrasi dan pengujian status, memverifikasi kompatibilitas protokol
trie & triedb: Implementasi Pohon Merkle Patricia (Merkle Patricia Trie) untuk penyimpanan dan pengelolaan status akun serta penyimpanan kontrak yang efisien.
04\Pembagian Modul Lapisan Eksekusi
Akses eksternal ke node Geth memiliki dua bentuk, yaitu melalui RPC dan melalui Console. RPC cocok dibuka untuk pengguna eksternal, sedangkan Console lebih sesuai untuk pengelola node. Namun, baik melalui RPC maupun Console, keduanya menggunakan kemampuan yang sudah terbungkus secara internal, yang dibangun dengan cara berlapis.
Lapisan terluar adalah API yang digunakan untuk akses eksternal ke berbagai kemampuan node, Engine API digunakan untuk komunikasi antara lapisan eksekusi dan lapisan konsensus, Eth API digunakan untuk pengguna eksternal atau program yang mengirimkan transaksi, mendapatkan informasi blok, Net API digunakan untuk mendapatkan status jaringan p2p, dan lain-lain. Misalnya, jika pengguna mengirimkan transaksi melalui API, maka transaksi tersebut pada akhirnya akan dikirim ke kolam transaksi untuk dikelola. Contoh lain, jika pengguna perlu mendapatkan data blok, maka perlu memanggil kemampuan basis data untuk mendapatkan blok yang sesuai.
Pada lapisan API berikutnya, implementasi fungsi inti meliputi pengumpulan transaksi, pengemasan transaksi, produksi blok, sinkronisasi blok dan status, dll. Fungsi-fungsi ini perlu bergantung pada kemampuan tingkat yang lebih rendah, seperti kemampuan jaringan P2P untuk menyinkronkan kumpulan transaksi, blok dan status, dan pembuatan blok dan blok yang disinkronkan dari node lain perlu divalidasi sebelum dapat ditulis ke database lokal, yang perlu bergantung pada EVM dan kemampuan penyimpanan data.
Struktur Ethereum dalam eth/backend.go adalah abstraksi dari seluruh protokol Ethereum, yang pada dasarnya mencakup komponen utama di Ethereum, tetapi EVM adalah pengecualian, yang akan diinstansiasi setiap kali memproses transaksi, tanpa perlu diinisialisasi bersama seluruh Node. Ethereum yang disebutkan di bawah ini merujuk pada struktur ini:
ketik Ethereum struct { // Ethereum config, termasuk chain config *ethconfig. Config // Transaction pool, setelah transaksi pengguna dikirimkan, buka transaction pool txPool *txpool. TxPool // Digunakan untuk melacak dan mengelola transaksi lokal localTxTracker *locals. TxTracker // Struktur blockchain blockchain *inti. BlockChain // adalah komponen inti dari lapisan jaringan node Ethereum, bertanggung jawab untuk menangani semua komunikasi dengan node lain, termasuk sinkronisasi blok, penyiaran transaksi, dan penerimaan, serta mengelola penangan koneksi node peer // bertanggung jawab untuk penemuan node dan manajemen sumber node discmix *enode. FairMix // Bertanggung jawab atas penyimpanan persisten rantai data blockchainDb ethdb. Database // Bertanggung jawab untuk menangani penerbitan dan berlangganan berbagai acara internal ke eventMux *event. TypeMux // Konsensus mesin. Mesin // Kelola akun pengguna dan kunci accountManager * akun. Manajer // Mengelola filter log dan potongan filterMaps *filtermaps. FilterMaps // Saluran untuk mematikan filterMaps dengan aman, memastikan bahwa sumber daya dibersihkan dengan benar ketika node dimatikan closeFilterMaps chan chan struct{} // Menyediakan dukungan backend untuk RPC API APIBackend *EthAPIBackend // Di bawah PoS, bekerja dengan mesin konsensus untuk memvalidasi penambang blok *miner. Penambang // Harga gas terendah yang diterima oleh node adalah gasPrice *big. Int // ID Jaringan networkID uint64 // Menyediakan layanan RPC terkait jaringan, memungkinkan status jaringan ditanyakan melalui RPC netRPCService *ethapi. NetAPI // Mengelola koneksi jaringan P2P, menangani penemuan node dan pembentukan koneksi, dan menyediakan fungsi transportasi jaringan underlay p2pServer *p2p. Server // Lindungi akses bersamaan ke sinkronisasi kunci bidang yang dapat diubah. RWMutex // Melacak apakah node turun dengan anggun dan membantu memulihkan shutdownTracker setelah shutdown *shutdown yang tidak normal. ShutdownTracker}
Node
Node di node/node.go adalah struktur data inti lain yang bertindak sebagai wadah untuk mengelola dan mengoordinasikan operasi berbagai layanan. Dalam struktur di bawah ini, penting untuk fokus pada bidang siklus hidup, yang digunakan siklus hidup untuk mengelola siklus hidup fungsi internal. Misalnya, abstraksi Ethereum di atas perlu bergantung pada Node untuk memulai dan mendaftar dalam siklus hidup. Dengan cara ini, fungsi spesifik dapat dipisahkan dari abstraksi node, dan skalabilitas seluruh arsitektur perlu dibedakan, yang perlu dibedakan dari node di devp2p.
type Node struct { eventmux *event.TypeMux config *Config // Pengelola akun, bertanggung jawab untuk mengelola dompet dan akun accman *accounts.Manager log log.Logger keyDir string keyDirTemp bool dirLock *flock.Flock stop chan struct{} // instance jaringan p2p server *p2p.Server startStopLock sync.Mutex // Melacak status siklus hidup node (inialisasi, berjalan, ditutup) state int lock sync.Mutex // Semua backend, layanan, dan layanan pendukung yang terdaftar lifecycles []Lifecycle // Daftar API yang saat ini disediakan rpcAPIs []rpc.API // Berbagai cara akses yang disediakan untuk RPC http *httpServer ws *httpServer httpAuth *httpServer wsAuth *httpServer ipc *ipcServer inprocHandler *rpc.Server databases map[*closeTrackingDB]struct{} }
Jika dilihat dari dimensi abstrak lapisan eksekusi Ethereum, Ethereum sebagai komputer dunia perlu mencakup tiga bagian, yaitu jaringan, komputasi, dan penyimpanan. Maka komponen yang sesuai dengan ketiga bagian ini di lapisan eksekusi Ethereum adalah:
Jaringan: devp2p
Menghitung: EVM
Penyimpanan: ethdb
devp2p
Ethereum pada dasarnya adalah sistem terdistribusi, di mana setiap Node terhubung dengan Node lainnya melalui jaringan p2p. Implementasi protokol jaringan p2p di Ethereum adalah devp2p.
devp2p memiliki dua fungsi inti, yang pertama adalah penemuan Node, yang memungkinkan Node untuk terhubung dengan Node lain saat bergabung ke jaringan; yang kedua adalah layanan transfer data, setelah terhubung dengan Node lain, maka bisa melakukan pertukaran data.
Struktur Node di p2p/enode/node.go mewakili node dalam jaringan p2p, di mana enr. Struktur Record menyimpan pasangan kunci-nilai detail node, termasuk informasi identitas (algoritma tanda tangan yang digunakan oleh identitas node, kunci publik), informasi jaringan (alamat IP, nomor port), informasi protokol yang didukung (misalnya, dukungan untuk protokol eth / 68 dan snap), dan informasi kustom lainnya, yang dikodekan dalam RLP dan didefinisikan dalam EIP-778:
type Node struct { // Node record, contains various properties of the node r enr.Record // Unique identifier of the node, 32 bytes length id ID // hostname tracking the DNS name of the node hostname string // IP address of the node ip netip.Addr // UDP port udp uint16 // TCP port tcp uint16 }// enr.Recordtype Record struct { // Serial number seq uint64 // Signature signature []byte // RLP encoded record raw []byte // Sorted list of all key-value pairs pairs []pair }
Struktur Table di p2p/discover/table.go adalah struktur data inti dari implementasi protokol penemuan node devp2p, yang menerapkan tabel hash terdistribusi mirip Kademlia, untuk memelihara dan mengelola informasi node di jaringan.
printf("ketik Table struct { mutex sync. Mutex // Indeks bucket node yang diketahui berdasarkan jarak [nBuckets]*bucket // bootstrap node nursery []*enode. Node rand reseedingRandom ips netutil. Tabel validasi ulang DistinctNetSetRevalidasi // Database node yang diketahui db *enode. DB net transport cfg Log log konfigurasi. Logger // Secara berkala memproses berbagai peristiwa dalam jaringan refreshReq chan chan struct{} revalResponseCh chan revalidationResponse addNodeCh chan addNodeOp addNodeHandled chan bool trackRequestCh chan trackRequestOp initDone chan struct{} closeReq chan struct{} closed chan struct{} // Menambahkan dan menghapus antarmuka untuk node nodeAddedHook func(*bucket, *tableNode) nodeRemovedHook func(*ember, *tableNode)} dunia!" );
ethdb
ethdb menyelesaikan abstraksi penyimpanan data Ethereum, menyediakan antarmuka penyimpanan yang seragam, dan database konkret di lapisan bawah bisa berupa leveldb, pebble, atau database lainnya. Banyak ekstensi dapat dilakukan, asalkan tetap menjaga keseragaman di tingkat antarmuka.
Beberapa data (seperti data blok) dapat dibaca dan ditulis langsung ke basis data bawah melalui antarmuka ethdb, sedangkan antarmuka penyimpanan data lainnya dibangun di atas dasar ethdb, misalnya sebagian besar data dalam basis data adalah data status, data ini akan diorganisir dalam struktur MPT, yang dalam Geth diimplementasikan sebagai trie. Selama proses menjalankan node, data trie akan menghasilkan banyak status sementara, data ini tidak dapat langsung dipanggil menggunakan ethdb untuk dibaca dan ditulis, perlu triedb untuk mengelola data dan status sementara ini, dan akhirnya akan dipersistensikan melalui ethdb.
Di ethdb/database.go, antarmuka untuk kemampuan baca-tulis basis data yang mendasari didefinisikan, tetapi tidak mencakup implementasi konkret, yang akan diimplementasikan oleh basis data yang berbeda. Misalnya leveldb atau pebble database. Dalam Database, dua lapisan antarmuka baca-tulis data didefinisikan, di mana antarmuka KeyValueStore digunakan untuk menyimpan data yang aktif dan mungkin sering berubah, seperti blok terbaru, status, dll. AncientStore digunakan untuk menangani data blok sejarah, yang jarang berubah setelah ditulis.
// Antarmuka puncak basis data type Database interface { KeyValueStore AncientStore}// Antarmuka baca tulis data KV type KeyValueStore interface { KeyValueReader KeyValueWriter KeyValueStater KeyValueRangeDeleter Batcher Iteratee Compacter io.Closer}// Antarmuka baca tulis data lama type AncientStore interface { AncientReader AncientWriter AncientStater io.Closer}
EVM
EVM adalah fungsi transisi status dari mesin status Ethereum, semua pembaruan data status hanya dapat dilakukan melalui EVM, jaringan p2p dapat menerima informasi transaksi dan blok, informasi ini setelah diproses oleh EVM akan menjadi bagian dari basis data status. EVM menyembunyikan perbedaan perangkat keras yang mendasarinya, sehingga program yang dijalankan di EVM di berbagai platform dapat menghasilkan hasil yang konsisten. Ini adalah cara desain yang sangat matang, di mana JVM dalam bahasa Java juga memiliki desain serupa.
Implementasi EVM memiliki tiga komponen utama, struktur EVM yang didefinisikan dalam core/vm/evm.go menetapkan struktur keseluruhan EVM dan ketergantungannya, termasuk konteks eksekusi, ketergantungan basis data status, dan lain-lain; struktur EVMInterpreter yang didefinisikan dalam core/vm/interpreter.go menetapkan implementasi interpreter, bertanggung jawab untuk mengeksekusi bytecode EVM; struktur Contract yang dibungkus dalam core/vm/contract.go mengemas parameter spesifik untuk pemanggilan kontrak, termasuk pemanggil, kode kontrak, input, dan lain-lain, dan semua opcode saat ini didefinisikan dalam core/vm/opcodes.go:
EVMtype EVM struct { // Block context, berisi informasi terkait blok Context BlockContext // Konteks transaksi, berisi informasi terkait transaksi TxContext // State database, digunakan untuk mengakses dan memodifikasi status akun StateDB StateDB // Current call depth int // Parameter konfigurasi rantai chainConfig *params. ChainConfig parameter chainRules. Aturan // EVM Config Config // Bytecode Interpreter interpreter *EVMInterpreter // Abort execution flag abort atomic. Bool callGasTemp uint64 // precompiles map[common. Alamat]PrecompiledContract jumpDests map[common. Hash]bitvec }type EVMInterpreter struct { // Tunjuk instance EVM yang menjadi miliknya evm *EVM // Opcode Jump Table table *JumpTable // Keccak256 hasher instance, bagikan hasher crypto antar opcode. KeccakState // Keccak256 hasil hash buffer hasherBuf umum. Hash // Apakah itu mode read-only, modifikasi status tidak diperbolehkan dalam mode read-only readOnly bool // Data pengembalian dari CALL terakhir digunakan untuk penggunaan kembali berikutnya returnData []byte }type Contract struct { // caller's address caller caller common. Alamat // Alamat kontrak alamat umum. Alamat jumpdests map[common. Hash]analisis bitvec bitvec // Kode Bytecode Kontrak []byte // Kode hash CodeHash umum. Hash // Input panggilan []byte // Apakah akan menggunakan IsDeployment bool untuk kontrak // Apakah akan memanggil IsSystemCall bool // Gas gas yang tersedia uint64 // Jumlah ETH yang melekat pada nilai panggilan *uint256. Int }
Implementasi Modul Lain
Fungsi lapisan eksekusi diimplementasikan melalui pendekatan berlapis, modul dan fungsi lainnya dibangun di atas tiga komponen inti ini. Berikut adalah beberapa modul inti yang akan diperkenalkan.
Di bawah eth/protocols terdapat implementasi subprotokol jaringan p2p Ethereum saat ini. Ada subprotokol eth/68 dan snap, yang dibangun di atas devp2p.
eth/68 adalah protokol inti Ethereum, nama protokolnya adalah eth, 68 adalah nomor versinya, kemudian di atas protokol ini diimplementasikan fungsi seperti kolam transaksi (TxPool), sinkronisasi blok (Downloader), dan sinkronisasi transaksi (Fetcher). Protokol snap digunakan untuk melakukan sinkronisasi blok dan data status dengan cepat ketika node baru bergabung ke jaringan, yang dapat sangat mengurangi waktu startup node baru.
ethdb menyediakan kemampuan baca dan tulis untuk database dasar. Karena ada banyak struktur data yang kompleks dalam protokol Ethereum, pengelolaan data ini tidak dapat dilakukan secara langsung melalui ethdb. Oleh karena itu, rawdb dan statedb diimplementasikan di atas ethdb untuk mengelola data blok dan status secara terpisah.
EVM mengalir melalui semua proses utama, baik dalam pembangunan blok maupun verifikasi blok, semua transaksi perlu dieksekusi menggunakan EVM.
05\Proses Memulai Node Geth
Peluncuran Geth dibagi menjadi dua tahap, tahap pertama akan menginisialisasi komponen dan sumber daya yang diperlukan untuk memulai Node, tahap kedua Node akan secara resmi memulai Node dan kemudian melayani eksternal.
Inisialisasi Node
Saat memulai sebuah node geth, kode berikut akan terlibat:
Inisialisasi setiap modul adalah sebagai berikut:
cmd/geth/main.go: titik masuk untuk memulai Node geth
eth/ethconfig/config.go: Menginisialisasi instance mesin konsensus (mesin konsensus di sini tidak benar-benar berpartisipasi dalam konsensus, hanya akan memverifikasi hasil lapisan konsensus, serta menangani permintaan penarikan validator)
core/txpool/legacypool/legacypool.go: inisialisasi kolam transaksi biasa
cord/txpool/locals/tx_tracker.go: Pelacakan transaksi lokal (perlu dikonfigurasi untuk mengaktifkan pelacakan transaksi lokal, transaksi lokal akan diproses dengan prioritas lebih tinggi)
eth/handler.go: Menginisialisasi instance Handler dari protokol
miner/miner.go: modul untuk menginstansiasi pengemasan transaksi (modul penambangan asli)
eth/api_backend.go: Menginstansikan layanan RPC
eth/gasprice/gasprice.go: Menginstansikan layanan pencarian harga gas
internal/ethapi/api.go: Menginstansikan API RPC jaringan P2P
node/node.go(RegisterLifecycle): Mendaftarkan siklus hidup berbagai komponen
cmd/utils/flags.go(RegisterFilterAPI): Mendaftarkan API RPC Filter
cmd/utils/flags.go(DaftarLayananGraphQL): Mendaftar API RPC GraphQL (jika dikonfigurasi)
cmd/utils/flags.go(RegisterEthStatsService): Mendaftar layanan EthStats RPC API (jika sudah dikonfigurasi)
eth/catalyst/api.go:mendaftarkan Engine API
Inisialisasi Node akan dilakukan di makeFullNode dalam cmd/geth/config.go, dengan fokus untuk menginisialisasi tiga modul berikut.
Pada langkah pertama, struktur Node dalam node/node.go akan diinisialisasi, yaitu seluruh kontainer node, semua fungsi perlu dijalankan dalam kontainer ini. Langkah kedua adalah menginisialisasi struktur Ethereum, yang mencakup implementasi berbagai fungsi inti Ethereum, Etherereum juga perlu didaftarkan ke dalam Node. Langkah ketiga adalah mendaftarkan Engine API ke dalam Node.
Di antara Node yang diinisialisasi, itu adalah membuat sebuah instansi Node, kemudian menginisialisasi server p2p, manajemen akun, serta port protokol http yang diekspos ke luar.
Inisialisasi Ethereum akan jauh lebih kompleks, sebagian besar fungsi inti diinisialisasi di sini. Pertama, ethdb akan diinisialisasi dan konfigurasi rantai akan dimuat dari penyimpanan, kemudian mesin konsensus akan dibuat. Mesin konsensus di sini tidak akan melakukan operasi konsensus, tetapi hanya akan memverifikasi hasil yang dikembalikan oleh lapisan konsensus. Jika ada permintaan penarikan dari lapisan konsensus, operasi penarikan nyata juga akan diselesaikan di sini. Kemudian, struktur Block Chain dan kolam transaksi akan diinisialisasi.
Setelah semuanya selesai, handler akan diinisialisasi. Handler adalah titik masuk untuk semua permintaan jaringan p2p, termasuk sinkronisasi transaksi, pengunduhan blok, dan lain-lain. Ini adalah komponen kunci untuk implementasi operasi terdesentralisasi di Ethereum. Setelah semua ini selesai, beberapa subprotokol yang diimplementasikan di atas devp2p, seperti eth/68, snap, dll., akan didaftarkan ke dalam kontainer Node, dan akhirnya Ethereum akan didaftarkan sebagai lifecycle ke dalam kontainer Node, dan inisialisasi Ethereum selesai.
Akhirnya, inisialisasi Engine API relatif sederhana, hanya mendaftarkan Engine API ke dalam Node. Dengan ini, inisialisasi node telah selesai sepenuhnya.
Node mulai
Setelah menyelesaikan inisialisasi Node, Anda perlu memulai Node. Proses memulai Node relatif sederhana, Anda hanya perlu menyalakan semua layanan RPC dan Lifecycle yang telah terdaftar, maka seluruh Node dapat memberikan layanan kepada eksternal.
06\ringkasan
Sebelum memahami implementasi lapisan eksekusi Ethereum secara mendalam, perlu ada pemahaman keseluruhan tentang Ethereum, yang dapat dianggap sebagai mesin status yang didorong oleh transaksi. Lapisan eksekusi bertanggung jawab untuk pelaksanaan transaksi dan perubahan status, sedangkan lapisan konsensus bertanggung jawab untuk mendorong lapisan eksekusi berjalan, termasuk menghasilkan blok dari lapisan eksekusi, menentukan urutan transaksi, memberikan suara untuk blok, dan memastikan blok mendapatkan finalitas. Karena mesin status ini terdesentralisasi, komunikasi dengan node lain melalui jaringan p2p diperlukan untuk menjaga konsistensi data status.
Di lapisan eksekusi tidak bertanggung jawab untuk menentukan urutan transaksi, hanya bertanggung jawab untuk mengeksekusi transaksi dan merekam perubahan status setelah eksekusi transaksi. Ada dua bentuk pencatatan di sini, satu adalah merekam semua perubahan status dalam bentuk blok, yang lainnya adalah merekam status saat ini dalam basis data. Sementara itu, lapisan eksekusi juga merupakan pintu masuk transaksi, melalui kolam transaksi untuk menyimpan transaksi yang belum dibundel ke dalam blok. Jika node lain perlu mendapatkan data blok, status, dan transaksi, lapisan eksekusi akan mengirimkan informasi ini melalui jaringan p2p.
Untuk lapisan eksekusi, ada tiga modul inti: komputasi, penyimpanan, dan jaringan. Komputasi sesuai dengan implementasi EVM, penyimpanan sesuai dengan implementasi ethdb, dan jaringan sesuai dengan implementasi devp2p. Setelah memiliki pemahaman keseluruhan seperti itu, kita bisa memahami setiap submodul dengan lebih mendalam tanpa tersesat dalam detail spesifik.
Konten ini hanya untuk referensi, bukan ajakan atau tawaran. Tidak ada nasihat investasi, pajak, atau hukum yang diberikan. Lihat Penafian untuk pengungkapan risiko lebih lanjut.
Klien utama Ethereum: Arsitektur keseluruhan Geth
Artikel ini adalah yang pertama dalam seri kode sumber Geth. Melalui seri ini, kita akan membangun kerangka penelitian tentang implementasi Geth, di mana para pengembang dapat mendalami bagian-bagian yang mereka minati berdasarkan kerangka ini. Seri ini terdiri dari enam artikel, dan dalam artikel pertama ini, kita akan mempelajari arsitektur desain klien lapisan eksekusi Geth serta alur proses awal Geth Node. Kecepatan pembaruan kode Geth sangat cepat, jadi kode yang akan dilihat kemudian mungkin akan berbeda, namun desain keseluruhan tetap konsisten, dan kode baru juga dapat dibaca dengan pemikiran yang sama.
01\Klien Ethereum
Sebelum peningkatan The Merge Ethereum, Ethereum hanya memiliki satu klien, yang bertanggung jawab atas pelaksanaan transaksi dan konsensus blockchain, memastikan bahwa blockchain menghasilkan blok baru dalam urutan tertentu. Setelah peningkatan The Merge, klien Ethereum dibagi menjadi lapisan eksekusi dan lapisan konsensus, lapisan eksekusi bertanggung jawab atas pelaksanaan transaksi, pemeliharaan status dan data, lapisan konsensus bertanggung jawab atas implementasi fungsi konsensus, dan lapisan eksekusi dan lapisan konsensus berkomunikasi melalui API. Lapisan eksekusi dan lapisan konsensus memiliki spesifikasi mereka sendiri, dan klien dapat mengimplementasikannya dalam bahasa yang berbeda, tetapi mereka harus sesuai dengan spesifikasi yang sesuai, dan Geth adalah implementasi dari klien lapisan eksekusi. Saat ini, lapisan eksekusi utama dan klien lapisan konsensus memiliki implementasi berikut:
Lapisan Eksekusi
Lapisan Konsensus
02\Ringkasan Lapisan Eksekusi
Lapisan eksekusi Ethereum dapat dilihat sebagai mesin status yang digerakkan oleh transaksi, fungsi dasar dari lapisan eksekusi adalah untuk memperbarui data status melalui eksekusi transaksi oleh EVM. Selain eksekusi transaksi, terdapat juga fungsi untuk menyimpan dan memverifikasi blok dan data status, menjalankan jaringan p2p, dan memelihara kumpulan transaksi.
Transaksi dihasilkan oleh pengguna (atau program) dalam format yang ditentukan oleh spesifikasi lapisan eksekusi Ethereum. Pengguna perlu menandatangani transaksi tersebut, jika transaksi tersebut sah (Nonce berurutan, tanda tangan benar, biaya gas cukup, dan logika bisnis benar), maka transaksi akhirnya akan dieksekusi oleh EVM, yang akan memperbarui status jaringan Ethereum. Status di sini merujuk pada kumpulan struktur data, data, dan basis data, termasuk alamat akun eksternal, alamat kontrak, saldo alamat, serta kode dan data.
Lapisan eksekusi bertanggung jawab untuk mengeksekusi transaksi dan mempertahankan keadaan transaksi setelah dieksekusi, dan lapisan konsensus bertanggung jawab untuk memilih transaksi mana yang akan dieksekusi. EVM adalah fungsi transisi keadaan dalam mesin keadaan ini, dan input fungsi akan datang dari banyak tempat, baik dari informasi blok terbaru yang disediakan oleh lapisan konsensus, atau dari blok yang diunduh oleh jaringan p2p.
Lapisan konsensus dan lapisan eksekusi berkomunikasi melalui Engine API, yang merupakan satu-satunya cara komunikasi antara lapisan eksekusi dan lapisan konsensus. Jika lapisan konsensus mendapatkan hak untuk memproduksi blok, maka akan menggunakan Engine API untuk membuat blok baru di lapisan eksekusi. Jika tidak mendapatkan hak untuk memproduksi blok, lapisan konsensus akan menyinkronkan blok terbaru untuk divalidasi dan dieksekusi oleh lapisan eksekusi, sehingga tetap menjaga konsensus dengan seluruh jaringan Ethereum.
Lapisan eksekusi secara logis dapat dibagi menjadi 6 bagian:
Gambar di bawah menunjukkan proses kunci dari lapisan eksekusi, serta fungsi setiap bagiannya:
Untuk lapisan eksekusi (di sini hanya membahas Full Node), ada tiga proses kunci:
03\Struktur Sumber
struktur kode go-ethereum sangat besar, tetapi banyak kode di dalamnya adalah kode bantu dan pengujian unit. Saat mempelajari kode sumber Geth, Anda hanya perlu fokus pada implementasi inti protokol. Fungsi masing-masing modul adalah sebagai berikut. Perhatikan dengan seksama modul core, eth, ethdb, node, p2p, rlp, trie & triedb:
04\Pembagian Modul Lapisan Eksekusi
Akses eksternal ke node Geth memiliki dua bentuk, yaitu melalui RPC dan melalui Console. RPC cocok dibuka untuk pengguna eksternal, sedangkan Console lebih sesuai untuk pengelola node. Namun, baik melalui RPC maupun Console, keduanya menggunakan kemampuan yang sudah terbungkus secara internal, yang dibangun dengan cara berlapis.
Lapisan terluar adalah API yang digunakan untuk akses eksternal ke berbagai kemampuan node, Engine API digunakan untuk komunikasi antara lapisan eksekusi dan lapisan konsensus, Eth API digunakan untuk pengguna eksternal atau program yang mengirimkan transaksi, mendapatkan informasi blok, Net API digunakan untuk mendapatkan status jaringan p2p, dan lain-lain. Misalnya, jika pengguna mengirimkan transaksi melalui API, maka transaksi tersebut pada akhirnya akan dikirim ke kolam transaksi untuk dikelola. Contoh lain, jika pengguna perlu mendapatkan data blok, maka perlu memanggil kemampuan basis data untuk mendapatkan blok yang sesuai.
Pada lapisan API berikutnya, implementasi fungsi inti meliputi pengumpulan transaksi, pengemasan transaksi, produksi blok, sinkronisasi blok dan status, dll. Fungsi-fungsi ini perlu bergantung pada kemampuan tingkat yang lebih rendah, seperti kemampuan jaringan P2P untuk menyinkronkan kumpulan transaksi, blok dan status, dan pembuatan blok dan blok yang disinkronkan dari node lain perlu divalidasi sebelum dapat ditulis ke database lokal, yang perlu bergantung pada EVM dan kemampuan penyimpanan data.
! Klien utama Ethereum: Arsitektur keseluruhan Geth
Struktur Data Inti Lapisan Eksekusi
Ethereum
Struktur Ethereum dalam eth/backend.go adalah abstraksi dari seluruh protokol Ethereum, yang pada dasarnya mencakup komponen utama di Ethereum, tetapi EVM adalah pengecualian, yang akan diinstansiasi setiap kali memproses transaksi, tanpa perlu diinisialisasi bersama seluruh Node. Ethereum yang disebutkan di bawah ini merujuk pada struktur ini:
ketik Ethereum struct { // Ethereum config, termasuk chain config *ethconfig. Config // Transaction pool, setelah transaksi pengguna dikirimkan, buka transaction pool txPool *txpool. TxPool // Digunakan untuk melacak dan mengelola transaksi lokal localTxTracker *locals. TxTracker // Struktur blockchain blockchain *inti. BlockChain // adalah komponen inti dari lapisan jaringan node Ethereum, bertanggung jawab untuk menangani semua komunikasi dengan node lain, termasuk sinkronisasi blok, penyiaran transaksi, dan penerimaan, serta mengelola penangan koneksi node peer // bertanggung jawab untuk penemuan node dan manajemen sumber node discmix *enode. FairMix // Bertanggung jawab atas penyimpanan persisten rantai data blockchainDb ethdb. Database // Bertanggung jawab untuk menangani penerbitan dan berlangganan berbagai acara internal ke eventMux *event. TypeMux // Konsensus mesin. Mesin // Kelola akun pengguna dan kunci accountManager * akun. Manajer // Mengelola filter log dan potongan filterMaps *filtermaps. FilterMaps // Saluran untuk mematikan filterMaps dengan aman, memastikan bahwa sumber daya dibersihkan dengan benar ketika node dimatikan closeFilterMaps chan chan struct{} // Menyediakan dukungan backend untuk RPC API APIBackend *EthAPIBackend // Di bawah PoS, bekerja dengan mesin konsensus untuk memvalidasi penambang blok *miner. Penambang // Harga gas terendah yang diterima oleh node adalah gasPrice *big. Int // ID Jaringan networkID uint64 // Menyediakan layanan RPC terkait jaringan, memungkinkan status jaringan ditanyakan melalui RPC netRPCService *ethapi. NetAPI // Mengelola koneksi jaringan P2P, menangani penemuan node dan pembentukan koneksi, dan menyediakan fungsi transportasi jaringan underlay p2pServer *p2p. Server // Lindungi akses bersamaan ke sinkronisasi kunci bidang yang dapat diubah. RWMutex // Melacak apakah node turun dengan anggun dan membantu memulihkan shutdownTracker setelah shutdown *shutdown yang tidak normal. ShutdownTracker}
Node
Node di node/node.go adalah struktur data inti lain yang bertindak sebagai wadah untuk mengelola dan mengoordinasikan operasi berbagai layanan. Dalam struktur di bawah ini, penting untuk fokus pada bidang siklus hidup, yang digunakan siklus hidup untuk mengelola siklus hidup fungsi internal. Misalnya, abstraksi Ethereum di atas perlu bergantung pada Node untuk memulai dan mendaftar dalam siklus hidup. Dengan cara ini, fungsi spesifik dapat dipisahkan dari abstraksi node, dan skalabilitas seluruh arsitektur perlu dibedakan, yang perlu dibedakan dari node di devp2p.
type Node struct { eventmux *event.TypeMux config *Config // Pengelola akun, bertanggung jawab untuk mengelola dompet dan akun accman *accounts.Manager log log.Logger keyDir string keyDirTemp bool dirLock *flock.Flock stop chan struct{} // instance jaringan p2p server *p2p.Server startStopLock sync.Mutex // Melacak status siklus hidup node (inialisasi, berjalan, ditutup) state int lock sync.Mutex // Semua backend, layanan, dan layanan pendukung yang terdaftar lifecycles []Lifecycle // Daftar API yang saat ini disediakan rpcAPIs []rpc.API // Berbagai cara akses yang disediakan untuk RPC http *httpServer ws *httpServer httpAuth *httpServer wsAuth *httpServer ipc *ipcServer inprocHandler *rpc.Server databases map[*closeTrackingDB]struct{} }
Jika dilihat dari dimensi abstrak lapisan eksekusi Ethereum, Ethereum sebagai komputer dunia perlu mencakup tiga bagian, yaitu jaringan, komputasi, dan penyimpanan. Maka komponen yang sesuai dengan ketiga bagian ini di lapisan eksekusi Ethereum adalah:
devp2p
Ethereum pada dasarnya adalah sistem terdistribusi, di mana setiap Node terhubung dengan Node lainnya melalui jaringan p2p. Implementasi protokol jaringan p2p di Ethereum adalah devp2p.
devp2p memiliki dua fungsi inti, yang pertama adalah penemuan Node, yang memungkinkan Node untuk terhubung dengan Node lain saat bergabung ke jaringan; yang kedua adalah layanan transfer data, setelah terhubung dengan Node lain, maka bisa melakukan pertukaran data.
Struktur Node di p2p/enode/node.go mewakili node dalam jaringan p2p, di mana enr. Struktur Record menyimpan pasangan kunci-nilai detail node, termasuk informasi identitas (algoritma tanda tangan yang digunakan oleh identitas node, kunci publik), informasi jaringan (alamat IP, nomor port), informasi protokol yang didukung (misalnya, dukungan untuk protokol eth / 68 dan snap), dan informasi kustom lainnya, yang dikodekan dalam RLP dan didefinisikan dalam EIP-778:
type Node struct { // Node record, contains various properties of the node r enr.Record // Unique identifier of the node, 32 bytes length id ID // hostname tracking the DNS name of the node hostname string // IP address of the node ip netip.Addr // UDP port udp uint16 // TCP port tcp uint16 }// enr.Recordtype Record struct { // Serial number seq uint64 // Signature signature []byte // RLP encoded record raw []byte // Sorted list of all key-value pairs pairs []pair }
Struktur Table di p2p/discover/table.go adalah struktur data inti dari implementasi protokol penemuan node devp2p, yang menerapkan tabel hash terdistribusi mirip Kademlia, untuk memelihara dan mengelola informasi node di jaringan.
printf("ketik Table struct { mutex sync. Mutex // Indeks bucket node yang diketahui berdasarkan jarak [nBuckets]*bucket // bootstrap node nursery []*enode. Node rand reseedingRandom ips netutil. Tabel validasi ulang DistinctNetSetRevalidasi // Database node yang diketahui db *enode. DB net transport cfg Log log konfigurasi. Logger // Secara berkala memproses berbagai peristiwa dalam jaringan refreshReq chan chan struct{} revalResponseCh chan revalidationResponse addNodeCh chan addNodeOp addNodeHandled chan bool trackRequestCh chan trackRequestOp initDone chan struct{} closeReq chan struct{} closed chan struct{} // Menambahkan dan menghapus antarmuka untuk node nodeAddedHook func(*bucket, *tableNode) nodeRemovedHook func(*ember, *tableNode)} dunia!" );
ethdb
ethdb menyelesaikan abstraksi penyimpanan data Ethereum, menyediakan antarmuka penyimpanan yang seragam, dan database konkret di lapisan bawah bisa berupa leveldb, pebble, atau database lainnya. Banyak ekstensi dapat dilakukan, asalkan tetap menjaga keseragaman di tingkat antarmuka.
Beberapa data (seperti data blok) dapat dibaca dan ditulis langsung ke basis data bawah melalui antarmuka ethdb, sedangkan antarmuka penyimpanan data lainnya dibangun di atas dasar ethdb, misalnya sebagian besar data dalam basis data adalah data status, data ini akan diorganisir dalam struktur MPT, yang dalam Geth diimplementasikan sebagai trie. Selama proses menjalankan node, data trie akan menghasilkan banyak status sementara, data ini tidak dapat langsung dipanggil menggunakan ethdb untuk dibaca dan ditulis, perlu triedb untuk mengelola data dan status sementara ini, dan akhirnya akan dipersistensikan melalui ethdb.
Di ethdb/database.go, antarmuka untuk kemampuan baca-tulis basis data yang mendasari didefinisikan, tetapi tidak mencakup implementasi konkret, yang akan diimplementasikan oleh basis data yang berbeda. Misalnya leveldb atau pebble database. Dalam Database, dua lapisan antarmuka baca-tulis data didefinisikan, di mana antarmuka KeyValueStore digunakan untuk menyimpan data yang aktif dan mungkin sering berubah, seperti blok terbaru, status, dll. AncientStore digunakan untuk menangani data blok sejarah, yang jarang berubah setelah ditulis.
// Antarmuka puncak basis data type Database interface { KeyValueStore AncientStore}// Antarmuka baca tulis data KV type KeyValueStore interface { KeyValueReader KeyValueWriter KeyValueStater KeyValueRangeDeleter Batcher Iteratee Compacter io.Closer}// Antarmuka baca tulis data lama type AncientStore interface { AncientReader AncientWriter AncientStater io.Closer}
EVM
EVM adalah fungsi transisi status dari mesin status Ethereum, semua pembaruan data status hanya dapat dilakukan melalui EVM, jaringan p2p dapat menerima informasi transaksi dan blok, informasi ini setelah diproses oleh EVM akan menjadi bagian dari basis data status. EVM menyembunyikan perbedaan perangkat keras yang mendasarinya, sehingga program yang dijalankan di EVM di berbagai platform dapat menghasilkan hasil yang konsisten. Ini adalah cara desain yang sangat matang, di mana JVM dalam bahasa Java juga memiliki desain serupa.
Implementasi EVM memiliki tiga komponen utama, struktur EVM yang didefinisikan dalam core/vm/evm.go menetapkan struktur keseluruhan EVM dan ketergantungannya, termasuk konteks eksekusi, ketergantungan basis data status, dan lain-lain; struktur EVMInterpreter yang didefinisikan dalam core/vm/interpreter.go menetapkan implementasi interpreter, bertanggung jawab untuk mengeksekusi bytecode EVM; struktur Contract yang dibungkus dalam core/vm/contract.go mengemas parameter spesifik untuk pemanggilan kontrak, termasuk pemanggil, kode kontrak, input, dan lain-lain, dan semua opcode saat ini didefinisikan dalam core/vm/opcodes.go:
EVMtype EVM struct { // Block context, berisi informasi terkait blok Context BlockContext // Konteks transaksi, berisi informasi terkait transaksi TxContext // State database, digunakan untuk mengakses dan memodifikasi status akun StateDB StateDB // Current call depth int // Parameter konfigurasi rantai chainConfig *params. ChainConfig parameter chainRules. Aturan // EVM Config Config // Bytecode Interpreter interpreter *EVMInterpreter // Abort execution flag abort atomic. Bool callGasTemp uint64 // precompiles map[common. Alamat]PrecompiledContract jumpDests map[common. Hash]bitvec }type EVMInterpreter struct { // Tunjuk instance EVM yang menjadi miliknya evm *EVM // Opcode Jump Table table *JumpTable // Keccak256 hasher instance, bagikan hasher crypto antar opcode. KeccakState // Keccak256 hasil hash buffer hasherBuf umum. Hash // Apakah itu mode read-only, modifikasi status tidak diperbolehkan dalam mode read-only readOnly bool // Data pengembalian dari CALL terakhir digunakan untuk penggunaan kembali berikutnya returnData []byte }type Contract struct { // caller's address caller caller common. Alamat // Alamat kontrak alamat umum. Alamat jumpdests map[common. Hash]analisis bitvec bitvec // Kode Bytecode Kontrak []byte // Kode hash CodeHash umum. Hash // Input panggilan []byte // Apakah akan menggunakan IsDeployment bool untuk kontrak // Apakah akan memanggil IsSystemCall bool // Gas gas yang tersedia uint64 // Jumlah ETH yang melekat pada nilai panggilan *uint256. Int }
Implementasi Modul Lain
Fungsi lapisan eksekusi diimplementasikan melalui pendekatan berlapis, modul dan fungsi lainnya dibangun di atas tiga komponen inti ini. Berikut adalah beberapa modul inti yang akan diperkenalkan.
Di bawah eth/protocols terdapat implementasi subprotokol jaringan p2p Ethereum saat ini. Ada subprotokol eth/68 dan snap, yang dibangun di atas devp2p.
eth/68 adalah protokol inti Ethereum, nama protokolnya adalah eth, 68 adalah nomor versinya, kemudian di atas protokol ini diimplementasikan fungsi seperti kolam transaksi (TxPool), sinkronisasi blok (Downloader), dan sinkronisasi transaksi (Fetcher). Protokol snap digunakan untuk melakukan sinkronisasi blok dan data status dengan cepat ketika node baru bergabung ke jaringan, yang dapat sangat mengurangi waktu startup node baru.
ethdb menyediakan kemampuan baca dan tulis untuk database dasar. Karena ada banyak struktur data yang kompleks dalam protokol Ethereum, pengelolaan data ini tidak dapat dilakukan secara langsung melalui ethdb. Oleh karena itu, rawdb dan statedb diimplementasikan di atas ethdb untuk mengelola data blok dan status secara terpisah.
EVM mengalir melalui semua proses utama, baik dalam pembangunan blok maupun verifikasi blok, semua transaksi perlu dieksekusi menggunakan EVM.
05\Proses Memulai Node Geth
Peluncuran Geth dibagi menjadi dua tahap, tahap pertama akan menginisialisasi komponen dan sumber daya yang diperlukan untuk memulai Node, tahap kedua Node akan secara resmi memulai Node dan kemudian melayani eksternal.
Inisialisasi Node
Saat memulai sebuah node geth, kode berikut akan terlibat:
Inisialisasi setiap modul adalah sebagai berikut:
Inisialisasi Node akan dilakukan di makeFullNode dalam cmd/geth/config.go, dengan fokus untuk menginisialisasi tiga modul berikut.
Pada langkah pertama, struktur Node dalam node/node.go akan diinisialisasi, yaitu seluruh kontainer node, semua fungsi perlu dijalankan dalam kontainer ini. Langkah kedua adalah menginisialisasi struktur Ethereum, yang mencakup implementasi berbagai fungsi inti Ethereum, Etherereum juga perlu didaftarkan ke dalam Node. Langkah ketiga adalah mendaftarkan Engine API ke dalam Node.
Di antara Node yang diinisialisasi, itu adalah membuat sebuah instansi Node, kemudian menginisialisasi server p2p, manajemen akun, serta port protokol http yang diekspos ke luar.
Inisialisasi Ethereum akan jauh lebih kompleks, sebagian besar fungsi inti diinisialisasi di sini. Pertama, ethdb akan diinisialisasi dan konfigurasi rantai akan dimuat dari penyimpanan, kemudian mesin konsensus akan dibuat. Mesin konsensus di sini tidak akan melakukan operasi konsensus, tetapi hanya akan memverifikasi hasil yang dikembalikan oleh lapisan konsensus. Jika ada permintaan penarikan dari lapisan konsensus, operasi penarikan nyata juga akan diselesaikan di sini. Kemudian, struktur Block Chain dan kolam transaksi akan diinisialisasi.
Setelah semuanya selesai, handler akan diinisialisasi. Handler adalah titik masuk untuk semua permintaan jaringan p2p, termasuk sinkronisasi transaksi, pengunduhan blok, dan lain-lain. Ini adalah komponen kunci untuk implementasi operasi terdesentralisasi di Ethereum. Setelah semua ini selesai, beberapa subprotokol yang diimplementasikan di atas devp2p, seperti eth/68, snap, dll., akan didaftarkan ke dalam kontainer Node, dan akhirnya Ethereum akan didaftarkan sebagai lifecycle ke dalam kontainer Node, dan inisialisasi Ethereum selesai.
Akhirnya, inisialisasi Engine API relatif sederhana, hanya mendaftarkan Engine API ke dalam Node. Dengan ini, inisialisasi node telah selesai sepenuhnya.
Node mulai
Setelah menyelesaikan inisialisasi Node, Anda perlu memulai Node. Proses memulai Node relatif sederhana, Anda hanya perlu menyalakan semua layanan RPC dan Lifecycle yang telah terdaftar, maka seluruh Node dapat memberikan layanan kepada eksternal.
06\ringkasan
Sebelum memahami implementasi lapisan eksekusi Ethereum secara mendalam, perlu ada pemahaman keseluruhan tentang Ethereum, yang dapat dianggap sebagai mesin status yang didorong oleh transaksi. Lapisan eksekusi bertanggung jawab untuk pelaksanaan transaksi dan perubahan status, sedangkan lapisan konsensus bertanggung jawab untuk mendorong lapisan eksekusi berjalan, termasuk menghasilkan blok dari lapisan eksekusi, menentukan urutan transaksi, memberikan suara untuk blok, dan memastikan blok mendapatkan finalitas. Karena mesin status ini terdesentralisasi, komunikasi dengan node lain melalui jaringan p2p diperlukan untuk menjaga konsistensi data status.
Di lapisan eksekusi tidak bertanggung jawab untuk menentukan urutan transaksi, hanya bertanggung jawab untuk mengeksekusi transaksi dan merekam perubahan status setelah eksekusi transaksi. Ada dua bentuk pencatatan di sini, satu adalah merekam semua perubahan status dalam bentuk blok, yang lainnya adalah merekam status saat ini dalam basis data. Sementara itu, lapisan eksekusi juga merupakan pintu masuk transaksi, melalui kolam transaksi untuk menyimpan transaksi yang belum dibundel ke dalam blok. Jika node lain perlu mendapatkan data blok, status, dan transaksi, lapisan eksekusi akan mengirimkan informasi ini melalui jaringan p2p.
Untuk lapisan eksekusi, ada tiga modul inti: komputasi, penyimpanan, dan jaringan. Komputasi sesuai dengan implementasi EVM, penyimpanan sesuai dengan implementasi ethdb, dan jaringan sesuai dengan implementasi devp2p. Setelah memiliki pemahaman keseluruhan seperti itu, kita bisa memahami setiap submodul dengan lebih mendalam tanpa tersesat dalam detail spesifik.
07\Ref
[1]
[2]
[3]
[4]
[5]
[6]
·END·
Konten | Ray
Editing & Typesetting | Huanhuan
Desain | Daisy